2012-12-05 2 views
0

jQuery가 약간 있지만 가능한 결함을 쉽게 식별 할 수 있도록 여기에 간단한 버전을 넣습니다. 나는 나의 시도와 문제를 더 잘 강조 할 수 있도록 코드에 인라인을 달았다. 제 코멘트를 인라인 코드로 찾으십시오.동적 데이터()로 jQuery 이벤트 버블 링 문제가 발생했습니다.

내 문제는 "지우기"버튼입니다. 이전에 클릭 한 입력을 지우지 만 현재 활성 입력 만 지워야합니다. 이벤트 버블 링 문제와 같은 냄새가 나지만 지금은 확인할 수 없으므로 도움을 주시면 대단히 감사하겠습니다.

워크 플로는 다음과 같이이다 :

  1. I/튀어 시작됩니다 .container

  2. DIV 번호 팝업 내부

  3. 나는 버튼을 클릭 (input[name="a"]를) input.trigger 클릭 #popup 내부의 "지우기"는 input[name="a"]을 지 웁니다. 나는 값을 되돌리려면 "되돌리기"를 수행한다. 기본 값이 존재하면 되돌릴 수있다 (이 부분은 코드에 포함되지 않는다. 왜냐하면 다음 문제가 해결되면 주요 문제가 아니기 때문이다). 닫아. 따라서 "a"입력은 지워졌지 만 저장 데이터 - 기본값을 통해 기본값으로 되돌려졌습니다.

  4. 좋아, 지금까지.

  5. 나는

  6. 나는 ""취소 "버튼을,이 입력을 지 웁니다 클릭"A "와 .... 좋은 .. 다른 input.trigger (input[name="b"]) 출시 #popup, 추가 조치를 클릭하지만, b "이며, 현재는 input.trigger[name="b"] 만 지울 것으로 예상됩니다 (이전 입력 인"a "가 아님).

해결책 here은 아직 도움이되지 않습니다.

$('.container').on('focus', 'input.trigger', function(e) { 
    e.preventDefault(); 
    // First fix attempt, no use 
    // https://stackoverflow.com/questions/9153501/how-do-you-stop-children-from-propagating-an-event-triggered-by-a-live-delegate 
    // Trying to solve problem with event bubbling, but no use 
    if (e.target != this){ 
    return true; 
    } 
    var input = $(this); 
    // somewhere added a class focused on input focused, please ignore. 
    // we add blur here to make any button or input inside popup clickable. 
    $('input:not(.focused)').blur(); 

    // Added dynamic data("popup") based on input name (a, b, c, d) 
    $("#popup").data("popup", this.name).css({ 
    left: "20px", 
    top: input.offset().top + 24 + "px" 
    }) 
    // Second fix attempt, no use 
    .stop(true, true) 
    .show('slow', function() { 
    var currentPopup = $(this), 
     popupName = currentPopup.data("popup"), 
     // Trying to get input/trigger name from data "popup" per clicked input name. 
     // I tried putting this after `var input = $(this);` above but put it here later 
     // thinking it should solve the problem, but alas not. 
     theinput = $('input[name="' + popupName + '"]'), 
     // Used for other dynamic interaction with some classes (.a_popup, .b_popup, etc). 
     popupid = theinput.data('popupid'); 

    currentPopup.on('click', '.clear', function(e) { 
     // Third fix attempt, no use 
     e.stopPropagation(); 
     // The problem is here: 
     // The button clears out any previous (opened) input.trigger, 
     // while it should only clears the input with name == current popupName 

     // Why this also bubbles to previously opened input.trigger "popupid" 
     console.log(popupid); 

     theinput.val(""); 
    }); 
    // More buttons here: Revert and Close. But once the "Clear" button issue is solved, this is no issue. So excluded. 
    }); 
}) 
.on('blur', 'input.trigger', function (e) { 
    e.preventDefault(); // no use 
    var hidden = $("#popup"), 
    popupName = this.name; 
    if (hidden.data("popup") === popupName) { 
    hidden.hide().removeData("popup"); 
    } 
}); 

HTML :

<body> 
<div id="page-wrapper"> 
    <div class="container"> 
    <form> 
     <!-- This input value is dynamically changed via other function --> 
     <input class="trigger" name="a" value="one" data-popupid=".a_popup" data-default="a_value"> 
     <input class="trigger" name="b" value="" data-popupid=".b_popup" data-default=""> 
     <input class="trigger" name="c" value="three" data-popupid=".c_popup" data-default="c_value"> 
     <input class="trigger" name="d" value="four" data-popupid=".d_popup" data-default="d_value"> 
    <form> 

    <!-- Ignore below divs, but here to have a general idea with above data-popid 
     This is not directly addressed in the code above --> 
    <div class="a_popup">Content</div> 
    <div class="b_popup">Content</div> 
    <div class="c_popup">Content</div> 
    <div class="d_popup">Content</div> 
    </div> 
</div><!-- page wrapper --> 

<!-- This popup has data("popup") namee by above inputs (a, b, c, d) assigned dynamically --> 
<div id="popup"> 
    <!-- Sometext and additional inputs --> 
    <button class="revert">Revert</button> 
    <button class="clear">Clear</button> 
    <button class="close">Close</button> 
</div> 
</body> 

CSS :

#popup { 
    background: #fff; 
    display: none; 
    height: 200px; 
    width: 200px; 
    z-index: 99999; 
    position: absolute; 
} 

내가 나 자신을 명확하게 할 수 있기를 바랍니다,하지만 난 단순화에서 놓친 어떤 경우 그렇지 않으면 내가 업데이트됩니다 위의 코드. 실제 문제를 발견하는 데 도움이되는 정보를 제공해 주셔서 감사합니다.

업데이트 : $('.container').off('input.trigger');이 닫기 버튼에 있습니다.

+0

위임 된 이벤트 핸들러를 사용하는 경우 핸들러가 호출되기 전에 이벤트가 이미 컨테이너에 버블 링되어 있기 때문에 전달을 중지하기에는 너무 늦습니다. 이전에 바인드 된 핸들러를 제거하기 위해'.off()'를 사용하지 않는다. 팝업이 나타날 때마다'.on() '을 다시 바인딩하는 것이 계속된다 ... – nnnnnn

+0

, 나는 상기를 갱신했다. .off()는 닫기 버튼에 붙어 있지만 좋은 일은 아닙니다. 두렵습니다. – swan

+0

하지만 'currentPopup.on ('click ','.clear ', function (e) {...})로 설정된 핸들러는 지울 수 없습니까? – nnnnnn

답변

1

JavaScript가 너무 복잡하고 따라하기 힘듭니다.

$(document).ready(function() { 
    $('.container').on('focus', 'input.trigger', function(e) { 
     var input = $(this); 
     var position = input.position(); 

     $("#popup") 
      .data('target', $(e.target)) 
      .css('top', position.top + 24) 
      .css('left', position.left + 20) 
      .show(); 
    }); 

    $('.clear').on('click', function(e) { 
     e.preventDefault(); 
     var input = $(e.target).closest('#popup').data('target'); 
     input.val(''); 
     $(e.target).closest('#popup').hide(); 
    }); 
    $('.revert').on('click', function(e) { 
     e.preventDefault(); 
     $(e.target).closest('#popup').hide(); 
    }); 
    $('.close').on('click', function(e) { 
     e.preventDefault(); 
     $(e.target).closest('#popup').hide(); 
    }); 
});​ 

을 그리고 여기이 간단한 방법의 일 예는 다음과 같습니다 : 그래서 우리에게 간단하게 할 수 http://jsfiddle.net/UZ4QM/

다시 블링 이제

우리가 다시 블링 추가 할 수 있습니다 추가 :

$(document).ready(function() { 
    $('.container') 
     .on('focus', 'input.trigger', function(e) { 
      var input = $(this); 
      var position = input.position(); 

      $("#popup") 
       .data('target', $(e.target)) 
       .css({'top': position.top + 24, 
         'left': position.left + 20 }) 
       .show('slow'); 
     }) 
     .on('blur', 'input.trigger', function(e) { 
      $("#popup").hide(); 
     }); 

    $('.clear').on('click', function(e) { 
     e.preventDefault(); 
     var input = $(e.target).closest('#popup').data('target'); 
     input.val(''); 
     $(e.target).closest('#popup').hide(); 
    }); 
    $('.revert').on('click', function(e) { 
     e.preventDefault(); 
     $(e.target).closest('#popup').hide(); 
    }); 
    $('.close').on('click', function(e) { 
     e.preventDefault(); 
     $(e.target).closest('#popup').hide(); 
    }); 
});​ 

다음은 원본에 가까운 블링 업 예제입니다. http://jsfiddle.net/C9JM5/

+0

정말 고마워. 이것을 통합 할 시간을 좀 주겠다. – swan

+0

문제 없습니다. 나는 블링 아웃 된 버전의 버그를 수정했다. – Cymen

+0

숙제를위한 유사한 팝업 버튼이 몇 개 있지만 문제없이 작동합니다. 감사 – swan