gpt4 book ai didi

javascript - 即使在事件发生后定义,事件处理程序也会执行

转载 作者:行者123 更新时间:2023-12-04 10:47:30 25 4
gpt4 key购买 nike

考虑以下代码:

function something(){
...
document.addEventListener('click', clickHandler);
}

function clickHandler(e) {...}
something () 单击我页面中存在的图标时被调用。因此,通过单击该图标, clickHandler () 也正在执行。这完全无法解释,因为事件监听器是事后添加的。
有什么好主意吗?

最佳答案

您的答案在问题的第一行:

something() is being called when clicking on an icon existing inside my page.



所以,你一定已经设置了 something作为 click您的图标的处理程序,以使该行为起作用。这意味着每次单击图标时,都会触发 clicksomething 处理的事件,但您还注册了一个完全不同的 click document 的事件处理程序.

由于事件冒泡,任何点击图标(位于 document 中)都会触发该元素的 click事件处理程序 ( something ) 然后事件将冒泡到 document ,这将触发它的 click事件处理程序 ( clickHandler)。

所以这里没有什么是乱序的。这是一个事件处理程序设置另一个事件处理程序的简单情况,因为第一个处理程序在第二个处理程序接收事件之前被调用,第二个绑定(bind)及时发生 document。处理冒泡事件。

这是带有注释的代码(为了运行而稍作修改):

document.querySelector("div").addEventListener("click", something);

function something(){
console.log("function something has been invoked because the div was clicked");

// Every time you click the div, you initiate a click event WITHIN the document
// that will propogate upward to the document itself and the next line sets up
// a handler at that level:
document.addEventListener('click', clickHandler);
}

function clickHandler(e) {
console.log(e.type + " triggered by: " + e.target + " handled at the document level");
}
div { background-color:#800080; color:orange;}
<p>First, click anywhere outside of the purple div and nothing will happen because the only thing
that initially has a click event set up for it is the div. Then click on the div and you'll
not only get the div's event handler to run, but because that handler sets up a click event
handler for the document and the event hasn't bubbled up there yet, you'll get that same
click event handled again, but by the document.
</p>
<p>
Then, click outside of the div again. Because the document now has an event handler set up
for it, the click will be handled there.
</p>
<div>Click me.</div>


如果这种行为不是您想要的,那么您有几个选择:

您可以使用 event.stopPropagation() 阻止事件进一步冒泡(从而阻止它进入文档)。 :

document.querySelector("div").addEventListener("click", something);

function something(e){
// Handle the event here but don't allow it to go anywhere else
e.stopPropagation();
console.log("function something has been invoked because the div was clicked");

// Every time you click the div, you initiate a click event WITHIN the document
// that will propogate upward to the document itself and the next line sets up
// a handler at that level:
document.addEventListener('click', clickHandler);
}

function clickHandler(e) {
console.log(e.type + " triggered by: " + e.target + " handled at the document level");
}
div { background-color:#800080; color:orange;}
<p>First, click anywhere outside of the purple div and nothing will happen because the only thing
that initially has a click event set up for it is the div. Then click on the div and you'll
not only get the div's event handler to run, but because that handler sets up a click event
handler for the document and the event hasn't bubbled up there yet, you'll get that same
click event handled again, but by the document.
</p>
<p>
Then, click outside of the div again. Because the document now has an event handler set up
for it, the click will be handled there.
</p>
<div>Click me.</div>


处理 document 上的所有点击通过让所有东西都冒出来,然后通过确定首先触发事件的元素来根据需要响应事件来达到水平。这称为 "event delegation" . event.target允许您访问该元素:

// All clicks will eventually bubble up to the document
document.addEventListener('click', clickHandler);

function clickHandler(e) {
console.log(e.type + " triggered by: " + e.target + " handled at the document level");

// You can handle the event differently based on which element triggered it.
if(e.target.classList.contains("notSpecial")){
e.target.classList.add("special");
}
}
.special { background-color:red; }
.as-console-wrapper { max-height: 1.5em !important; }
<h1>click me</h1>
<p>No, click me!</p>
<div>What about me?!</div>
<div class="notSpecial">Click me. I'm special</div>

关于javascript - 即使在事件发生后定义,事件处理程序也会执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59633446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com