事件冒充的事件冒泡

时间:2012-02-03 19:30:02

标签: javascript html html5 event-bubbling event-delegation

我正在尝试使用以下代码实现事件委派:

<html>
<head>
<script>
document.addEventListener('click', function(e){
    alert(e.target.className);
}, false);
</script>
</head>
<body>
<ul class="list">
    <li class="item">A</li>
    <li class="item">B</li>
    <li class="item">C</li>
    <li class="item">D</li>
</ul>
</body>
</html>

我希望事件能够冒泡,以便当我点击<li>项时,警报会显示item,然后另一个警报会显示list。但是此代码仅提供item的警报。如何修改它以使事件冒泡?

5 个答案:

答案 0 :(得分:1)

document对象上绑定单击处理程序时,不能指望多次调用它。它只会被调用一次(在document对象上)。

事件确实冒泡了DOM树。如果没有,它将无法到达document对象,您将看不到任何警告框。

因此,事件在LI元素处触发,然后一直冒泡到document对象,调用单击处理程序。

顺便说一下,你通常不会一直委托给document对象,而是委托给最近的共同祖先。例如,如果要处理LI元素的点击,则委托UL元素:

var list = document.getElementsByClassName( 'list' )[0];    

list.addEventListener( 'click', function ( e ) {
    var item = e.target;

    // handle item click
}, false );

现场演示: http://jsfiddle.net/rCVfq/

答案 1 :(得分:1)

您需要为列表添加事件以提醒它。事件由父对象捕获,但没有绑定到它们的事件,因此它不会发出警报。您需要为所有对象添加事件以提醒它。

答案 2 :(得分:1)

事件回调仅触发一次,但并不意味着事件不会冒泡。回调仅在元素侦听事件时执行。

如果您真的希望将警报一直触发回祖先,请在回调中逐个添加祖先的警报。您不必向所有祖先添加侦听器,这会导致消耗更多内存。

答案 3 :(得分:1)

我刚刚发布了一个小型事件委托库,以便更轻松地执行此类操作。请查看http://craig.is/riding/gators

你可以做到

Gator(document).on('click', 'li', function() { alert('li clicked!'); });
Gator(document).on('click', 'ul', function() { alert('ul clicked!'); });

这会将单击处理程序绑定到文档,并相应地调度事件。

除非您停止传播,否则当您点击li时,它们都会触发。

答案 4 :(得分:0)

您可以使用一些循环方法来调用两个警报:

var list = document.getElementsByClassName('list')[0];
list.addEventListener("click", function (e) {
   var target = e.target;
   while (target !== list) {
      switch(target.nodeName) {
          case "LI": //alert('li clicked!')
          break;
          case "UL": //alert('ul clicked!')
          break;
      }
      target = target.parentNode;
   }
});