JavaScript获取“被单击”元素addEventListener

10
我知道我可以获取单个ID的元素。
不过,我能够将侦听器附加到父div并传递被点击的单个span的ID吗?
<div id = "divId">
  <span id="one"></span>
  <span id="two"> </span>
 </div>

JS

document.getElementById("two").addEventListener("click", someFunction);

1
你能让这个更清晰一些吗?听起来像是你想要了解事件冒泡,但不是完全确定。 - temporary_user_name
什么?你想要点击的元素?使用event.target获取实际被点击的元素的引用。 - Teemu
还有这个:https://dev59.com/lHVD5IYBdhLWcg3wOo5h - temporary_user_name
如果以上答案都不起作用或者你需要其他帮助,请告诉我,我会尽力帮助你。 - AmmarCSE
是的,当我点击这个span时,似乎无法获取到它的id。 - Doc Holiday
4个回答

31
你可以使用event对象并访问其中的target属性。

document.getElementById("divId").addEventListener("click", someFunction);

function someFunction(event) {
  console.log(event.target.id);
}
<div id="divId">
  <span id="one">one</span>
  <span id="two"> two</span>
</div>


@Teemu,“event”是JavaScript中绑定处理程序的默认对象。 - AmmarCSE
@Teemu,我可能错了,但我认为event就像arguments一样,你可以在不传递它的情况下访问它。 - AmmarCSE
@Teemu,出于好奇,如果我没有传递它,以前的工作方式是怎样的? - AmmarCSE
1
我在控制台上看到了“ReferenceError: event is not defined”的错误信息,现在已经解决了。抱歉,我忘记了Chrome也实现了全局的event,但它不是任何标准的一部分。我使用的是FF浏览器,所以出现了这个错误。 - Teemu
1
这正是我所需要的。谢谢 :) - MatthewSzurkowski
显示剩余6条评论

4
如果用户点击的是被测试元素的子节点,那么e.target将会是另一个节点。现在合理的检查方法是监听文档并迭代路径(或使用一些委托库,其中有许多选择):
向文档添加一个事件监听器:
const isOnId = (path,id) => path.some(element => element.id === id);

document.addEventListener('click',function(e) {
  if(isOnId(e.path,'two')) {
    //you clicked on or in element with an id two
  } else {
    //you clicked on something else
  }
});

2

由于我没有足够的积分来评论,只能添加一个新答案。

与@CubeInTheBox分享的答案不同,我认为利用事件捕获/冒泡的概念为相应元素实现比为每个目标元素添加事件侦听器更好。 对于上面分享的示例,替代方案如下:

 <ul>
     <li class="list_item" data-mydata="hello there!">
         <img src="..." alt="" width="50", height="50">
     </li>
     <li class="list_item" data-mydata="hello world">
        <img src="..." alt="" width="50", height="50">
     </li>
 </ul>
 
 <script>
     const parentElement = document.querySelector('ul');
     parentElement.addEventListener('click', e => {
         // If you want to add the listener on li alone and not on image
         if (e.target.className === 'list_item') {
             const myvalue = e.target.dataset.mydata;
             console.log(myvalue);
         }
     });
 </script>

请注意,e.currentTarget在这种情况下不起作用,因为它会返回绑定事件的父级ul


2

Adam的答案是正确的,可以避免很多麻烦。不过有一种更好、更简单的方法可以实现这个功能,请查看这个答案

使用Event.currentTarget,代码如下:

<ul>
  <li class="list_item" data-mydata="hello there!">
    <img src="..." alt="" width="50", height="50">
  </li>
  <li class="list_item" data-mydata="hello world">
    <img src="..." alt="" width="50", height="50">
  </li>
</ul>

<script>
  const items = document.querySelectorAll(".list_item");
  items.forEach(node => {
    node.addEventListener("click", e => {
      let myvalue = e.currentTarget.dataset.mydata;
      console.log(myvalue); //hello there! || hello world It depends on which element the user has clicked
    })
  })
</script>

我希望这对您有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接