开发者

Click event handler inadvertently bubbles, even after calling jQuery's stopPropagation()

I'm trying to have different delegate click handlers for different elements within "li" elements in a list. Example:

<ul id='myList'>
  <li>
    <p>First item.</p>
    <button>button1</button>
    <button>button2</button>
  </li>
  <li>
    <p>Second item.</p>
    <button>button1</button>
    <button>button2</button>
  </li>
</ul>

when the user clicks button1 (of any item) I want to grab that event, and stop propagation (same for button2 instances). The user clicking the parent li element would be a different handler:

$('#myList').delegate('li', 'click', function() {
    alert("You clicked a parent <li> item!");
});

$('#myList').delegate('button', 'click', function(event) {
    event.stopPropagation();
    event.stopImmedi开发者_StackOverflow社区atePropagation();
    alert("You clicked a button (but which one?)!");
});

So one issue is, how do I have a delegate for button1 instances, and another for button2 instances? The second delegate in the example above does fire when a button is clicked, but event.stopPropagation() doesn't seem to work as the handler for the parent li item still gets called,

------ Update --------------

Also trying to call event.stopImmediatePropagation(), no effect though, parent handler still being called too.

Thank you


Maybe in the parent:

$('#myList').delegate('li', 'click', function(event) {
    if (!$(event.target).is('button')) {
        alert("You clicked a parent <li> item!");
    }
});


Indeed, it should work, and I tried to step through the jQuery code, but to no avail. Instead, I made this:

(function(){
  var el = document.getElementsByTagName("li");
  var i = el.length;

  while (i--)
    el[i].onclick = function () {
      alert("You clicked a parent <li> item!");
    };

  el = document.getElementsByTagName("button");
  i = el.length;

  while (i--)
    el[i].onclick = function (event) {
      var e = event || window.event;

      e.stopPropagation();
      e.cancelBubble = true;
      alert("You clicked a button (but which one?)!");
    };

})();

which works the way you want it to work (not tested in IE, though). I'm to tired to look into this further, now, perhaps tomorrow.

To answer your other question: I think you should really add ids or classes to your <button>s, so you can easily test which button got called.


You can try event.stopImmediatePropagation(). Theoretically, what you have should work, so expanding it might help.


The reason is that .delegate() will only execute the click functions once the click event bubbles down through the child elements to myList. It will then perform every delegate that matches, so it is correctly calling both in your example because by the time click arrives at myList it has passed through both a BUTTON and a LI.

Since you bound LI before BUTTON the LI delegate is first in the list that get called, you could just bind the BUTTON ones first and it should work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜