3

我正在尝试为列表中“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

4 回答 4

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 中测试)。现在,也许明天,我已经厌倦了进一步研究这个问题。

回答你的另一个问题:我认为你真的应该在你的 s 中添加ids 或classes <button>,这样你就可以轻松测试哪个按钮被调用了。

于 2010-06-25T02:49:48.387 回答
1

也许在父母中:

$('#myList').delegate('li', 'click', function(event) {
    if (!$(event.target).is('button')) {
        alert("You clicked a parent <li> item!");
    }
});
于 2010-06-25T02:50:32.300 回答
0

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

由于您在 BUTTON 之前绑定了 LI,因此 LI 代表在被调用的列表中是第一个,您可以先绑定 BUTTON 并且它应该可以工作。

于 2012-11-28T09:29:06.770 回答
0

你可以试试event.stopImmediatePropagation()。从理论上讲,您所拥有的应该可以工作,因此扩展它可能会有所帮助。

于 2010-06-25T02:26:54.027 回答