2010-03-01 2 views
3

나는 미디어 위키 확장 기능을 쓰는 중입니다. 나는 실제로 매우 초기 단계에있다.). 여기서 코드를 찾을 수 있습니다. (좋아요, 하나의 링크 만 제출할 수 있으니 github URL을 상상해보십시오)/eugenkiss/discussion-extension간단한 테스트 페이지의 이상한 Javascript 버그 (jQuery)

이상한 jQuery 문제가 있습니다. 방화 광 및 내 코드를 디버깅하려고합니다. 현재 코드와 예제를 업로드했습니다 : http://jsfiddle.net/NMpU5/

토론을 열고 적어도 두 개의 "답장"링크를 클릭하십시오. 그런 다음 나타나는 첫 번째 양식의 취소 버튼을 클릭하십시오. 이유는 모르겠지만 취소 버튼을 클릭하면 다른 양식이 원하는 양식 대신 닫힙니다.

이 내용도 다를 수 있습니다. 예를 들어, 두 개의 양식을 열고 마지막으로 열린 양식을 닫습니다. 처음에는 효과가있는 것 같습니다. 그러나 취소를 클릭하여 다른 양식을 닫으려고하면 이 사라집니다. 그러나 이벤트는 방화범에 표시된 것처럼 트리거됩니다. 때로는 다른 응답 앵커를 클릭하면 다른 양식의 겉으로보기에는 작동하지 않는 취소 버튼을 클릭했을 때 많은 양식이 열릴 것입니다.

글쎄, 내 원하는 확장을 위해 나는 물론 열린 형태의 존재를 하나의 것으로 제한 할 수 있습니다 - 왜 다른 두 개 이상을 열어야합니까? 그러나 나는 벌써 그것을 발견하는데 많은 시간을 투자했기 때문에 망할 버그를 찾고 싶다! 내가 원하는 : 내가 jQuery를 1.4.2


$(document).ready(function() { 
    // Hide the discussion bodys per default 
    $(".discussion").addClass("closed") 
     .children(".discussion-body").hide(); 

    // Register two custom events for the individual discussion divs  
    // "open" & "close" in order to make the discussion bodys 
    // collapsable and be able to toggle the events by clicking 
    // the "discussion-header-button" anchor 
    $(".discussion") 
    .bind("open", function(e) { 
     if(!$(this).hasClass("opened")) { 
      $(this).children(".discussion-body").slideDown(); 
      $(this).find(".discussion-header-button").html("[-]"); 
      $(this).addClass("opened"); 
      $(this).removeClass("closed"); 
     } 
    }) 
    .bind("close", function(e) { 
     if(!$(this).hasClass("closed")) { 
      $(this).children(".discussion-body").slideUp(); 
      $(this).find(".discussion-header-button").html("[+]"); 
      $(this).addClass("closed"); 
      $(this).removeClass("opened"); 
     } 
    }) 
    .find(".discussion-header-button").click(function(){ 
     relatedDiscussion = $(this).parents(".discussion"); 
     if(relatedDiscussion.hasClass("closed")) { 
      relatedDiscussion.trigger("open"); 
     } 
     else if(relatedDiscussion.hasClass("opened")) { 
      relatedDiscussion.trigger("close"); 
     } 
    }); 

    // Register custom "showForm" & "destroyForm" events on posts  
    // in order to make the "Reply" button work 
    // TODO: Maybe add "preview" & "submit" 
    $(".discussion-body .post") 
    .bind({ 
     showForm: function(){ 
      post = $(this); 
      postBody = post.find(".post-body").first(); 
      postHeader = post.find(".post-header").first(); 

      postBody.append(postCommentFormHtml); 
      replyLink = postHeader.find(".reply"); 
      replyLink.unbind(); 

      form = postBody.find(".post-comment-form"); 
      form.slideDown(); 

      // create actions for the form buttons 
      form.find(".cancel").click(function(){ 
       post.triggerHandler("destroyForm"); 
      }); 
      form.find(".preview").click(function(){ 
       // Hier muss mit Ajax und der Datenbank gespielt 
       // werden um ein preview erstellen zu können 
      }); 
      form.find(".submit").click(function(){ 
       // Hier muss mit Ajax und der Datenbank gespielt 
       // werden um den Post abschicken zu können 
      }); 
     }, 
     destroyForm: function(){ 
      post = $(this); 
      postBody = post.find(".post-body").first(); 
      postHeader = post.find(".post-header").first(); 

      replyLink = postHeader.find(".reply"); 
      replyLink.click(replyAction); 

      form = postBody.find(".post-comment-form"); 
      form.slideUp(function(){ 
        $(this).remove(); 
      }); 
     } 
    }); 
    //$(".discussion-post-comment").click(createPostCommentForm); 
    $(".discussion .reply").click(replyAction); 

    function replyAction(event){ 
     // Note: It is important to use triggerHandler instead of trigger 
     // otherwise the "showForm" event of all parents is triggered 
     // recursively (bubbling) and this is not desired 
     event.preventDefault(); 
     relatedPost = $(this).parents(".post").first(); 
     relatedPost.triggerHandler("showForm"); 
    } 
}); 
postCommentFormHtml = "\ 
    <div class='post-comment-form' style='display:none;'><br>\ 
    <form action='textarea.htm'>\ 
     <textarea name='post' cols='50' rows='8'></textarea>\ 
     <br>\ 
     <input class='submit' type='submit' value=' Post '>\ 
     <input class='preview' type='submit' value=' Preview '>\ 
     <input class='cancel'type='reset' value=' Cancel '>\ 
    </form>\ 
    </div>";​ 

HTML을


<div class="discussion"> 
<div class="discussion-header"> 
    <a class="discussion-header-button">[+]</a> 
    Diskussion: 3 Kommentar(e) 
    <a class="discussion-post-comment">Post Comment</a> 
</div> 
<div class="discussion-body"> 
<div class="post"> 
    <div class="post-header"> 
     <span class="post-header-name">Eugen</span> 
     <span class="post-header-date">2010-02-25 12:32:30</span> 
     <a class="reply" href="#">Reply</a> 
     <a class="edit" href="#">Edit</a> 
     <a class="delete" href="#">Delete</a> 
    </div> 
    <div class="post-body"> 
     Ich denke das sollte anders sein! 
    </div> 
    <div class="post"> 
     <div class="post-header"> 
      <span class="post-header-name">Markus</span> 
      <span class="post-header-date">2010-02-25 12:32:31</span> 
      <a class="reply" href="#">Reply</a> 
     <a class="edit" href="#">Edit</a> 
     <a class="delete" href="#">Delete</a> 
     </div> 
     <div class="post-body"> 
      Ich denke nicht 
     </div> 
    </div> 
</div> 
<div class="post"> 
    <div class="post-header"> 
     <span class="post-header-name">Jan</span> 
     <span class="post-header-date">2010-03-25 12:32:30</span> 
     <a class="reply" href="#">Reply</a> 
     <a class="edit" href="#">Edit</a> 
     <a class="delete" href="#">Delete</a> 
    </div> 
    <div class="post-body"> 
     Mal was ganz anderes: Denkt ihr das selbe was ich denke? 
    </div> 
</div> 
</div> 
</div> 

편집 자바 스크립트

을 사용하고, BTW)

을, 그것은 당신이 알고, 나를 위해 귀중한 버그 클래스에 이드의 변경을 추가하는 것은 도움이되지 않았습니다. 그게 도움이된다면 : 나는 ("destroyForm"이벤트에서) "post"(그리고 "postbody") 변수가 실제로 잘못된 포스트를 가리키고 있기 때문에 잘못된 폼이 삭제된다는 (Firebug 사용) 것을 발견했습니다. 하지만 포스트 변수가 처음

Edit2가에서 잘못된 포스트 가리키는 왜 나를 넘어 : 클래스 http://jsfiddle.net/NMpU5/1/

에 ALLS ID를 변경
+0

어쨌든 고유하도록 "id"값을 변경해야합니다. 이렇게하면 사람들이 도움을 줄 수 있습니다. 그렇듯이 디버깅할만한 가치가없는 것은 너무 잘못된 것입니다. – Pointy

+0

ide를 디버그 용으로 사용하고 있습니까? –

+0

나는 http://jsfiddle.net/NMpU5/1/을 만들었지 만 버그는 여전히 존재합니다. 클래스 대신에 id를 사용하여 새 버전의 stackoverflow에서 코드를 여기에서 업데이트해야합니까? – Eugen

답변

3

이벤트 처리기 함수 (특히 "post"및 "relatedDiscussion")의 많은 변수가 각 함수에서 "var"로 선언되지 않은 것처럼 보입니다. 내가 할 수있는 일을 정확하게 알아 내려고 노력했지만 혼란 스러웠습니다.그럼에도 불구하고 지역 변수를 선언하지 않으면 전역 변수가됩니다. 즉, "post"를 새로운 값으로 설정하는 각 함수는 활성화 될 수있는 다른 모든 함수에서 "post"가 사용하는 값을 변경합니다.

var post = $(this); 

변경을 등

+0

감사합니다. 그게 내가 자바 스크립트 기본을 기억하지 못하게하는거야! 나는 방화범이 내게 그 지역 변수가 이미 s.th를 할당하기 전에 값을 가지고 있다는 것을 보여 주 었는지 궁금했다. 그들에게. 하지만 나는 방화범이 맞지 않는다고 생각했다. 여기에서 업데이트 된 버전을 볼 수 있습니다. http://jsfiddle.net/NMpU5/4/ 다시 한번 감사합니다;) – Eugen

3
내 눈을 파업

우선 : 사용할 수있는 ID가 고유해야합니다. 태그에 대한 ID를 클래스로 변경하고 태그를 지우는 지 확인합니다.

+0

예 (git 브랜치에서) 시도했지만 문제가 해결되지 않아 되돌려졌습니다. – Eugen

+1

다시 시도해보십시오. 여러 요소간에 "id"값을 공유 할 수 없습니다. 모든 "id"는 모든 페이지에서 완벽하게 고유해야합니다. – Pointy

+0

여기 있습니다 http://jsfiddle.net/NMpU5/1/ 버그가 아직 있습니다. – Eugen

0

'#something'과 같은 jQuery 선택기를 사용하면 라이브러리에서 'document.getElementById()'를 사용하여 요소를 찾습니다. 은 여러 요소에 대해 동일한 "id"값을 사용하는 경우 작동하지 않을 수 있습니다. 실제로 당신이 설명하는대로 정확하게의 결과를 얻을 것입니다. "find()"를 사용하여 공유 "id"로 요소를 찾는 것은 중요하지 않습니다.

그런 문제는 제외하고 어쨌든 양식 입력란에 "이름"속성을 사용해야합니다.

+0

좋아요. 모든 클래스를 클래스로 변경했는데 버그가 아직 남아 있습니다. http://jsfiddle.net/NMpU5/1/ 고마워요. 양식 필드에 대한 설명은 – Eugen

+0

와우 당신은 빠르다 :-) 나는 지금 그것을보고있다. – Pointy

-1

ID를 클래스로 변경할 필요가 없습니다. 각 요소에 고유 한 ID 만 있으면되므로 올바른 요소를 얻을 수 있습니다.

+0

흠 좋아, 나는 그것이 어떻게 든 일할 것이라고 생각한다. 하지만 어쨌든, jQuery 선택자는 올바른 양식을 찾아야합니다. 그 방법으로 중첩되어서 find()는 올바른 양식을 찾아야합니다. – Eugen

1

당신은 생성 후 각 버튼을 클릭 바인딩 대신 폼에 바인딩 jQuery의 live 이벤트를 사용해야합니다.

나는 솔직히 내가 적이 없기 때문에 내가 당신의 post.triggerHandler("destroyForm"); 기능을 사용하지 않았다 나는 기본적으로 양식 클릭 기능을 꺼내

스크립트에 update을 게시 기능

$(".cancel").live("click", function(){ 
    $(this).closest(".post-comment-form").slideUp('',function(){ $(this).remove(); }); 
}); 
$(".preview").live("click", function(){ 
    // Hier muss mit Ajax und der Datenbank gespielt 
    // werden um ein preview erstellen zu können 
}); 
$(".submit").live("click", function(){ 
    // Hier muss mit Ajax und der Datenbank gespielt 
    // werden um den Post abschicken zu können 
}); 

을 살도록 변환 전에 그것을 사용하고 나는 그것을 LOL 일할 수 없습니다.

+0

'.parents()'를'.closest()'로 바꾸는 것이 좋습니다. 게시물의 위치와 응답의 범위를 파악하려고 할 때 코드가 매우 혼란스러워집니다. 나는 당신의'.bind()'함수를 완전히 제거하고'.live() '로 대체 할 것이라고 말하고 싶다. – Mottie

+0

주석을 주셔서 감사하지만 문제는 이미 해결되었다. 'destroyForm'은'bind()'로 만든 커스텀 이벤트입니다. 나는 closest()를 살펴볼 것이다. – Eugen