简而言之,我在 addEventListener
中添加了 addEventListener
。我正在收听的事件是 click
。这是我的代码示例:
function toggleElement() {
// function stuff
}
anchor.addEventListener('click', (e) => {
e.preventDefault();
if (!anchorWrapper.classList.contains('active')) {
// do some stuff
window.addEventListener('click', toggleElement, false);
} else {
// do some stuff
window.removeEventListener('click', toggleElement, false);
}
});
每次点击 anchor 元素时,我都会为监听点击的窗口分配一个事件监听器。我希望用户单击 anchor ,而 anchor 不应该初始化 toggleElement
,而只是为窗口分配一个事件监听器。然后,根据我的想法(结果证明是错误的),该函数应该只在下一次、第二次单击窗口上的任意位置时初始化。但是,它会在单击 anchor 元素时运行。
我哪里不对?如何防止 toggleElement
函数在用户单击 anchor 元素时未初始化,而是等待窗口上的 click
事件?
最佳答案
问题是您的第一个事件是 propagating通过 DOM 直到您刚刚添加事件处理程序的节点(在您的情况下为窗口)。因为传播在回调退出后继续,这意味着在添加第二个事件处理程序后,它将命中第二个事件处理程序。
您可以使用 stopPropagation
来避免这种情况您的事件中的方法。您还可以使用一些其他技术,例如 promise 或零长度超时,将其委托(delegate)给引擎中的下一个 JS“任务”,但也有一些您不想这样做的原因。
我在这里创建了一些示例代码,它还处理了您希望随后在按钮(或其他)内单击也触发第二个事件处理程序的情况。另请注意,我正在让第二个事件处理程序自行注销,这使此逻辑稍微简单一些。
let target = document.getElementById("target");
let targetWrapper = document.getElementById("targetWrapper");
function secondFunction() {
console.log("Called second callback");
//alert("Second Function Called");
targetWrapper.removeEventListener('click', secondFunction, false);
targetWrapper.classList.remove("active");
}
target.addEventListener('click', (e) => {
console.log("Called first callback")
e.preventDefault();
if(!targetWrapper.classList.contains("active")){
targetWrapper.addEventListener('click', secondFunction, false);
targetWrapper.classList.add("active");
e.stopPropagation();
}
});
body {
font-size: 20px;
font-family:sans-serif;
}
#targetWrapper {
min-height: 400px;
min-width: 400px;
text-align: center;
background-color: green;
position:relative;
}
#target {
vertical-align: middle;
background-color:blue;
color:red;
padding:50px;
position:absolute;
top:100px;
left:50px;
}
#targetWrapper.active{
outline: 3px solid red;
}
<div id="targetWrapper">
<a id="target">
Click me!
</a>
</div>
有关事件传播和处理程序的更多信息:
关于javascript - 在没有预期点击的情况下触发了点击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55559278/