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 id
s or class
es 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.
精彩评论