2012-02-03 122 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; 
    } 
});