我的HTML中有一个元素列表,如下所示:
<div class='container'>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
<script type="text/javascript" src="script.js"></script>
</div>
我试图做到这一点,以使我单击的每个元素都可以将元素中的动物记录到控制台。这是我的尝试:
const selection = document.querySelectorAll(".zone");
selection.forEach(element => {
element.addEventListener('click', pickSelection(element))
})
function pickSelection(animal) {
console.log(animal.textContent)
}
但是当我单击任何元素时,它什么都没有返回。但是,一旦将eventListener更改为此,它便开始工作:
selection.forEach(element => {
element.addEventListener('click', () => pickSelection(element))
})
为什么它在第二版代码而不是第一版中起作用?在第一个版本中,我以为我是通过编写“ pickSelection(element)”将元素参数传递给pickSelection函数的,但是显然只有在其前面有“()=>”的情况下它才有效,但是有什么区别用这种表示法?谢谢。
答案 0 :(得分:1)
在第一个版本中,您正在执行pickSelection
函数而不是传递其引用, addEventListener
期望当特定事件为触发。
但是由于您传递了pickSelection
函数的返回值undefined
(因为您没有从pickSelection
返回任何内容,所以默认情况下它返回的是undefined
)它不起作用。
在第二个版本中,您实际上是将函数引用传递给addEventListner
,这是箭头函数语法。
通过简单地传递引用pickSelection
,下面的内容也可以工作,但是这次它将收到 event
对象。
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)
}
<div class='container'>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
</div>
答案 1 :(得分:0)
此行
element.addEventListener('click', pickSelection(element));
实际上是
const temp = pickSelection(element);
element.addEventListener('click', temp);
你想要的是
element.addEventListener('click', pickSelection);
您看到区别了吗?
在此版本中
element.addEventListener('click', pickSelection(element))
您调用了函数pickSelection
并将其传递给element
。然后将pickSelection
返回element.addEventListener
您想要/需要做的就是将函数本身传递给element.addEventListener
此版本有效的原因
selection.forEach(element => {
element.addEventListener('click', () => pickSelection(element))
})
是因为您要将匿名函数传递给element.addEventListener
。这些行可以翻译成这个
function anonymousFn1(element) {
function anonymousFn2() {
pickSelection(element);
}
element.addEventListener('click', anonymousFn2);
}
selection.forEach(anonymousFn1);
请注意,在功能上还有另一个区别。
在这个
element.addEventListener('click', pickSelection);
click事件将Event object传递给pickSelection
,而在另一个事件中,变量element
是在forEach
称为anonmousFn1的情况下“封闭”的{{3 }},所以当调用anonymousFn2时,就使用了element
变量。
所以要使第一个开始工作,您真的需要这个
function pickSelection(event) {
const element = event.target;
console.log(element.textContent);
}
示例:
const selection = document.querySelectorAll(".zone");
selection.forEach(element => {
element.addEventListener('click', pickSelection);
});
function pickSelection(event) {
element = event.target;
console.log(element.textContent);
}
<div class='container'>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
</div>
答案 2 :(得分:0)
旁注:在每个元素上注册一个侦听器是一种不良做法。改用事件委托:
document.querySelector(`.container`).addEventListener(`click`, ({target}) => {
const el = target.closest(`.zone`);
if (el) {
console.log(el.textContent);
}
})
<div class='container'>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
<div class="zone green"></div>
<div class="zone red"></div>
<div class="zone blue"></div>
<div class="zone yellow"></div>
<div class="zone purple"></div>
<div class="zone brown"></div>
</div>