2012-02-03 91 views
1

我想实现事件委托下面的代码:事件冒泡事件代表团

<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的警报。我如何修改它以便事件起泡?

回答

1

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

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

1

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

顺便说一句,事件没有泡沫了DOM树。如果没有,它不会达到document对象,并且您不会看到任何警报框。

因此,事件触发LI元素,然后一直到达document对象,触发click处理程序。

顺便说一句,通常你不会委托一直到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/

+0

谢谢,但我有随机排列的不同层级的按钮,并且事先不能指定的结构。 – sawa 2012-02-03 19:54:43

+0

所以这个问题的答案是不可能的?我怀疑它 – Ced 2016-05-01 15:38:51

1

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

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时,它们都会触发。

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; 
    } 
});