即使在调用jQuery的stopPropagation()之后,Click事件处理程序也会无意中冒泡

时间:2010-06-25 02:16:10

标签: javascript jquery event-bubbling

我正在尝试为列表中“li”元素中的不同元素设置不同的委托点击处理程序。例如:

<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>

当用户点击button1(任何项目)时,我想抓住该事件,并停止传播(对于button2实例也是如此)。单击父li元素的用户将是不同的处理程序:

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

$('#myList').delegate('button', 'click', function(event) {
    event.stopPropagation();
    event.stopImmediatePropagation();
    alert("You clicked a button (but which one?)!");
});

所以一个问题是,如何为button1实例设置委托,为button2实例设置另一个委托?上面示例中的第二个委托在单击按钮时触发,但是event.stopPropagation()似乎不起作用,因为仍然会调用父li项的处理程序,

------更新--------------

同时尝试调用event.stopImmediatePropagation(),但没有效果,父处理程序仍被调用。

谢谢

4 个答案:

答案 0 :(得分:1)

确实,它应该工作,我试图逐步完成jQuery代码,但无济于事。相反,我做了这个:

(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?)!");
    };

})();

以您希望它的工作方式工作(但未在IE中测试)。我现在已经厌倦了进一步研究,现在,也许是明天。

要回答您的其他问题:我认为您应该将idclass es添加到<button> s,这样您就可以轻松测试哪个按钮被调用了。

答案 1 :(得分:1)

也许在父母身上:

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

答案 2 :(得分:0)

您可以尝试event.stopImmediatePropagation()。从理论上讲,你所拥有的应该是有用的,所以扩展它可能有所帮助。

答案 3 :(得分:0)

原因是.delegate()只有在click事件通过子元素向下到myList时才会执行click函数。然后它将执行匹配的每个委托,因此它在您的示例中正确调用两者,因为当单击到达myList时它已经通过了BUTTON和LI。

由于你在BUTTON之前绑定了LI,LI委托是被调用的列表中的第一个,你可以先绑定BUTTON,然后它就可以了。