最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - Javascript Event Listener on click not working as expected - Stack Overflow

programmeradmin6浏览0评论

I'm trying to create one event listener to handle all my "clicks" by putting it on the body and doing some event delegation. A simple example of what i'm trying to do is this:

<html>
 <body> 
  <div id = "div1">
   <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
   <ul>
  </div>
   <script>
    document.body.addEventListener('click', function(e){
     if(e.target.id == "div1"){alert("hi")}
    })
   </script>
 </body>
</html>

What I expect from the code above is that when I click on the "li" elements, the alert would fire since it is nested within the parent div. I thought that the event would propagate to the parent and fire. However, it doesn't seem to be working at all if I click on the li elements. Can someone help explain what's happening? Thank you!

If i was to do it the normal way by adding the eventListener directly to the div id, it would then work.

I'm trying to create one event listener to handle all my "clicks" by putting it on the body and doing some event delegation. A simple example of what i'm trying to do is this:

<html>
 <body> 
  <div id = "div1">
   <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
   <ul>
  </div>
   <script>
    document.body.addEventListener('click', function(e){
     if(e.target.id == "div1"){alert("hi")}
    })
   </script>
 </body>
</html>

What I expect from the code above is that when I click on the "li" elements, the alert would fire since it is nested within the parent div. I thought that the event would propagate to the parent and fire. However, it doesn't seem to be working at all if I click on the li elements. Can someone help explain what's happening? Thank you!

If i was to do it the normal way by adding the eventListener directly to the div id, it would then work.

Share Improve this question asked Apr 8, 2016 at 1:25 TomPutsTomPuts 1192 silver badges9 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5

There are two elements associated with an event:

  1. event.currentTarget, which is the element that is actually calling the listener (i.e. the on which the listener has been attached), and
  2. event.target, which is the element on which the event actually occurred

These can be the same element, parent and child, or ancestor and descendant (which is the case here).

So a click on an LI makes it the target, and since the body's click handler calls the listener, it's the currentTarget, the DIV is neither. If you put the listener on the DIV, it will then bee the currentTarget.

Originally, nodes other than elements could be event targets, but in recent implementations only elements are targets.

Some links:

  1. W3C DOM 4 Interface eventTarget
  2. W3C DOM 4 Event

Note that that target and eventTarget are specified as (host) objects, they aren't necessarily elements though that is how they are mostly implemented in current browsers.

If you click li ,you are current 2 step childnodes from parentNode div#div1

div#div1 > ul > li[current target] //back parentNode to 2 times

<script>
    document.body.addEventListener('click', function(e){
     if(e.target.parentNode.parentNode.id == "div1"){alert("hi")}
    })
</script>

You should use e.target.parentNode.parentNode.id =='div1' See the demo:

document.body.addEventListener('click', function(e) {
  if (e.target.parentNode.parentNode.id == "div1") {
    alert("hi")
  }
})
<div id="div1">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <ul>

If you want all the LI's in your body to be clicked, you can check against the nodeName.

Here is the fiddle: https://jsfiddle/swaprks/f3crax1q/

Javascript:

document.body.addEventListener('click', function(e){
     if(e.target.nodeName == "LI"){alert("hi")}
})

Here's with jquery for reference:

  $("li").on('click', function(){
      var y = this.parentElement.parentElement.id;
      if (y === 'div1')
        alert(y);
  })

This event is attached to all <li> elements within the Dom. You can follow the tree towards the root with parentElement to access the <li> containing <div> element's id property.

Alternatively:

$("div").on('click', function(){
  var y = this.id;
  if (y === 'div1')
    alert(y);
})

However, this fires on every click within any <div> element.

发布评论

评论列表(0)

  1. 暂无评论