mowwwalker mowwwalker - 3 days ago 5
Javascript Question

Javascript event delegation, handling parents of clicked elements?

http://jsfiddle.net/walkerneo/QqkkA/

I've seen many questions here either asking about or being answered with event delegation in javascript, but I've yet to see, however, how to use event delegation for elements that aren't going to be the targets of the click event.

For example:

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



What if I want to add a click event to handle the
li
elements when they're clicked? If I attach an event handler to the
ul
element, the
div
s will always be the target elements. Apart from checking every parent of the target element in a click function, how can I accomplish this?

edit:

I want to use event delegation instead of:

var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
lis[i].onclick = function(){};
}


But if I do:

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: I'm not interested in how to use Javascript libraries for this, I'm interested in how they do it and how it can be done with pure js.

Answer

Delegation is most useful for simple, common actions, like links/buttons/controls which generally are a single element. You can solve this problem in different ways. Here's one:

document.getElementById('dom').addEventListener('click', function(e){
  var el = e.target;
  while (el && el.tagName !== 'LI'){
     el = el.parentNode
  } // note that this will go up even past the listener
  console.log(el)
}, false)

You also have Node.contains and Node.compareDocumentPosition at your disposal.

Comments