Javascript 如何将eventListener应用于具有相同类的多个元素,并使每个元素独立响应

Javascript 如何将eventListener应用于具有相同类的多个元素,并使每个元素独立响应,javascript,dom,addeventlistener,Javascript,Dom,Addeventlistener,我的HTML中有一个元素列表,如下所示: <div class='container'> <div class="zone green">In the first version you are executing the pickSelection function instead of passing its reference, the addEventListener expects a function reference as a callback w

我的HTML中有一个元素列表,如下所示:

<div class='container'>
    <div class="zone green">In the first version you are executing the 
pickSelection
function instead of passing its reference, the
addEventListener
expects a function reference as a callback when the particular event is triggered.

But since you passed return value of the
pickSelection
function which is
undefined
(as you are not returning anything from the
pickSelection
so by default it is returning
undefined
) it is not working.

In the second version you are actually passing the function reference to the
addEventListner
, which being a arrow function syntax.

This following would also work, by simply passing the reference
pickSelection
, but this time it will receive the
event
object.

const selection = document.querySelectorAll(".zone");
selection.forEach(element => {
   element.addEventListener('click', pickSelection)
})
function pickSelection(event) {
      //getting the event object from the callback, target refers to the current element clicked.
    console.log(event.target.textContent)
}


在第一个版本中,您执行的是
pickSelection
函数,而不是传递其引用,期望在触发特定事件时将函数引用作为回调

但是,由于您传递了
pickSelection
函数的返回值,该函数是
未定义的
(由于您没有从
pickSelection
返回任何内容,因此默认情况下它返回的是
未定义的
),因此它不起作用

在第二个版本中,实际上是将函数引用传递给
addEventListner
,这是一种箭头函数语法

通过简单地传递引用
pickSelection
,下面的操作也会起作用,但这次它将接收对象

const selection=document.queryselectoral(“.zone”);
selection.forEach(元素=>{
元素。addEventListener('click',pickSelection)
})
函数选择(事件){
//从回调中获取事件对象时,target引用单击的当前元素。
console.log(event.target.textContent)
}

这条线

element.addEventListener('click', pickSelection(element));
实际上是这样吗

const temp = pickSelection(element);
element.addEventListener('click', temp);
你想要的是

element.addEventListener('click', pickSelection);
你看到区别了吗

在这个版本中

element.addEventListener('click', pickSelection(element))
您调用了函数
pickSelection
,并将其传递给
元素
。然后传递任何
pickSelection
返回到
元素。addEventListener

您想要/需要做的是将函数本身传递给
元素。addEventListener

这个版本有效的原因

selection.forEach(element => {
    element.addEventListener('click', () => pickSelection(element))
})
是因为您正在将匿名函数传递给
元素。addEventListener
。这些行可以翻译成这样

function anonymousFn1(element) {
    function anonymousFn2() {
         pickSelection(element);
    }
    element.addEventListener('click', anonymousFn2);
}

selection.forEach(anonymousFn1);
请注意,在功能上还有另一个区别

在这个

 element.addEventListener('click', pickSelection);
click事件将一个选择传递给
pickSelection
,而在另一个事件中,在
forEach
时创建的变量
元素
被称为anonmousFn1被“关闭”,因此在调用AnonomousFN2时,使用了
元素
变量

所以要让第一个开始工作,你真的需要这个

function pickSelection(event) {
    const element = event.target;
    console.log(element.textContent);
}
例如:

const selection=document.queryselectoral(“.zone”);
selection.forEach(元素=>{
元素。addEventListener('click',pickSelection);
});
函数选择(事件){
元素=event.target;
console.log(element.textContent);
}


旁注:在每个元素上注册一个侦听器是一种不好的做法。改为使用事件委派:

document.querySelector(`.container`).addEventListener(`click`,({target})=>{
const el=目标距离最近(`.zone`);
如果(el){
console.log(el.textContent);
}
})


对于event listner,您应该传递一个方法引用。在第二个方法中,您做得对。但是在第一个情况下,您传递的是未定义的(从pickSelection方法调用返回的内容)。第一个方法应该是
function(){pickSelection(element)}
我现在明白了,非常感谢!但我还有一个问题,在第二个版本中,它说:“()=>pickSelection(element)”,空括号中不应该有一个参数吗?因为在arrow函数中,语法()=>并不意味着函数不带参数?但是对于pickSelection函数,它确实需要一个参数。箭头函数
=>
实际上是在事件发生时调用的回调函数,它反过来将调用
pickSelection
函数并将
元素
传递给它。它通常应该采用一个参数,即
事件
对象,如下所示:
(事件)=>pickSelection(元素)这是可选的。但是,由于您已经将
元素
局部变量传递给
pickSelection
它将按预期工作。