2012-02-03 3 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).

Btw событие делает пузырь до дерева DOM. Если это не так, оно не достигнет объекта document, и вы не увидите никаких предупреждений.

Итак, событие срабатывает у элемента LI, а затем пузырится до объекта document, где вызывается обработчик кликов.

Btw обычно вы не делегируете весь путь до объекта document, но ближайшему общему предку. Например, если вы хотите обрабатывать клики на элементах LI, делегировании к элементу UL:

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

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

    // handle item click 
}, false); 

Live Demo:http://jsfiddle.net/rCVfq/

+0

Спасибо, но у меня есть кнопки случайно расположенных в разных иерархиях, и не может определить структуру заранее. – sawa

+0

Итак, ответ на вопрос, что это невозможно? – Ced

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; 
    } 
}); 
Смежные вопросы