bhavya_w
bhavya_w

Reputation: 10077

Event Delegation : catch event on Element not its children

HTML

  <section id='mainwrap'>
  .. 
  ....
  ......
  <section class='innerwrap'>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
  </section>
 .....
 ....
...
</section>

Here section innerwrap is added dynamically in the application. I have delegated an event to mainwrap section ( which is static).

Question: I am not able to catch the click event on the section innerwrap........ instead everytime the element getting clicked is its children divs.

JS

document.getElementById('mainwrap').addEventListener('click',handler,false);

function handler(e){
  event = e || window.event;
  var target = e.target || e.scrElement;
  var cls = target.className;
  
  
  console.log(target,cls);
  if(cls === 'innerwrap'){
   console.log('my right element clicked');
  }
  
}  
  
.innerwrap{
  border:2px solid #ddd;
  position:relative;
  z-index:1;
  display:inline-block;
}

.innerwrap > div{
  border:1px solid #efefef;
  position:relative;
  z-index:0;
  display:inline-block;
  margin-right:-4px;
 }
  <section id='mainwrap'>
  <section class='innerwrap'>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
  </section>
</section>

Upvotes: 0

Views: 200

Answers (3)

fast
fast

Reputation: 885

You could add one event handler for each container you actually want to receive the event in (if this is feasable in your setup):

(somewhere:)

(function() {
 var container = document.getElementById('mainwrap');
 container.addEventListener('click',handler,false);

 function handler(e) {
  e = e || window.event;
  var element = e.target || e.srcElement;

  console.log("Element actually clicked: ", element);
  console.log("Container receiving event: ", container);
 }

})();

Or expand to (can register handler for multiple containers..):

function registerHandlerForContainer(container_id, handler) {
 var container = document.getElementById(container_id);
 container.addEventListener('click',delegating_handler,false);

 function delegating_handler(e) {
  handler(container, e);
 }
}

function handler(container, e) {
  e = e || window.event;
  var element = e.target || e.srcElement;

  console.log("Element actually clicked: ", element);
  console.log("Container receiving event: ", container);
 }

registerHandlerForContainer('mainwrap', handler);

Upvotes: -1

Greg Burghardt
Greg Burghardt

Reputation: 18783

You need to climb the document tree until you find the right element:

document.getElementById('mainwrap').addEventListener('click',handler,false);

function handler(e){
  e = e || window.event;
  var element = e.target || e.srcElement;

  while (element.className !== "innerwrap" && element !== this) {
    element = element.parentNode;
  }

  if(element.className === 'innerwrap'){
    console.log('my right element clicked');
  }
}

The event.target property is always the deepest element that got clicked, so you just need to keep looking at the parentNodes until you find the right one.

Upvotes: 2

giordanolima
giordanolima

Reputation: 1218

Try this:

  if(cls === 'innerwrap'){
        console.log('my right element clicked');
  }else{
     if(target.id === "mainwrap"){
        console.log('Ooops wrong div!');
     }else{
        target.parentNode.click(); 
     }
  }

Upvotes: 0

Related Questions