Делегирование событий Javascript, обработка родителей щелкнутых элементов?
http://jsfiddle.net/walkerneo/QqkkA/
Я видел много вопросов здесь, спрашивая или отвечая на делегирование событий в javascript, но я еще не видел, однако, как использовать делегирование событий для элементов, которые не будут целями события click.
например:
HTML-код:
<ul>
<li><div class="d"></div></li>
<li><div class="d"></div></li>
<li><div class="d"></div></li>
<li><div class="d"></div></li>
<li><div class="d"></div></li>
<li><div class="d"></div></li>
</ul>
CSS:
ul{
padding:20px;
}
li{
margin-left:30px;
margin-bottom:10px;
border:1px solid black;
}
.d{
padding:10px;
background:gray;
}
что делать, если я хочу добавить событие click для обработки li
элементы, когда они нажаты? Если Я присоединю обработчик событий к ul
элемента div
s всегда будут целевыми элементами. Помимо проверки каждого родителя целевого элемента в функции click, как я могу это сделать?
edit:
Я хочу использовать делегирование событий вместо:
var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
lis[i].onclick = function(){};
}
но если я это сделаю:
document.getElementsByTagName('ul')[0].addEventListener('click',function(e){
// e.target is going to be the div, not the li
if(e.target.tagName=='LI'){
}
},false);
EDIT:меня не интересует, как использовать библиотеки Javascript для этого меня интересует как они это делают и как это можно сделать с помощью pure js.
3 ответов
вот один из способов решить это:
var list = document.getElementsByTagName('ul')[0]
list.addEventListener('click', function(e){
var el = e.target
// walk up the tree until we find a LI item
while (el && el.tagName !== 'LI') {
el = el.parentNode
}
console.log('item clicked', el)
}, false)
это чрезмерно упрощено, цикл будет продолжаться вверх по дереву даже мимо элемента UL. См. реализацию в рожь/события для более полного примера.
на Element.matches
, Node.contains
и Node.compareDocumentPosition
методы могут помочь вам реализовать такие функции.
Я не JavaScript geek, но, чтобы ответить на ваш вопрос (только для любопытства), я провел некоторое время в интернете, и через пару минут я понял, что вы можете вызвать событие на родительском элементе также, как это (как альтернативная идея, может быть, я не подходит) для обработки родителей нажатых элементов
var el=document.getElementsByTagName('ul')[0];
el.addEventListener('click',function(e){
var elm=e.target.parentNode;
if(document.createEvent)
{
evt = document.createEvent('MouseEvents');
evt.initMouseEvent("click", false, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
elm.dispatchEvent(evt);
liEventhandler(evt);
}
});
function liEventhandler(e)
{
console.log(e);
console.log(e.target);
console.log(e.which);
alert(e.target.innerHTML);
}
пример здесь.
выше пример не будет работать в IE использует createEventObject
и fireEvent
if(document.createEventObject)
{
var evt = document.createEventObject();
el.fireEvent('onclick', evt);
liEventhandler(evt);
}
а также e.цель-окно.событие.srcElement и addEventListener
должно быть
el.attachEvent('onclick', function(){...})
когда событие срабатывает на ul
и цель div
Я только что запустил событие на li
ссылки: 1. comp.ленг.в JavaScript 2.СЕТЬ РАЗРАБОТЧИКОВ MOZILLA и 3.этой.
теперь есть метод для элементов с именем closest
, который делает именно это. Он принимает селектор CSS в качестве параметра и находит ближайший соответствующий предок, который может быть самим элементом. Все текущие версии настольных браузеров поддержка оно, но вообще оно не готово для пользы продукции. Страница MDN, связанная выше, содержит полифилл.