javascript - addEventListener 和 removeEventListener 在 Firefox/Chrome 与 Edge 中的不同行为
问题描述
与 Chrome 和 Firefox 相比,我最近在 Edge 执行一段 Javascript 的方式上遇到了一个奇怪的不一致。
当附加一个点击处理程序(错误的,意外)时,Edge 的反应如预期的那样。但是 Chrome 和 Firefox 忽略了错误的点击处理程序,隐藏了我的错误。
button.addEventListener("click", functionOne);
function functionOne(e) {
console.log('functionOne called');
functionTwo(e);
}
function functionTwo(e) {
console.log('functionTwo called');
// My intial mistake was here: According to my application logic,
// I should have removed the event listener for functionOne. Whoops.
button.removeEventListener("click", functionThree);
console.log("Doing some asynchronous work...");
// Same here: I should have re-added the event listener for functionOne
button.addEventListener("click", functionThree);
}
// This function is never called by FF and Chrome, but it is called in Edge
function functionThree(e) {
console.error('functionThree called');
}
我打算在functionOne
做一些异步工作时删除事件侦听器,然后在异步调用完成后重新连接。我的错误是removeEventListener()
引用错误的函数 ( functionThree
) 进行调用,然后附加另一个事件侦听器,该侦听button
器也调用functionThree
.
但奇怪的是,该代码在 Chrome 和 Firefox 中按预期工作。只有当我在 Edge 中尝试它时,我才注意到 Edge 正在调用functionThree
,而 Chrome 和 Firefox 都忽略了它。
有人可以解释这种行为吗?为什么 Chrome 和 Firefox 不调用,functionThree
虽然我附加了一个事件监听器?为什么Edge 这么称呼它?
浏览器版本:
FireFox 59.0.2
Edge 41.16299.371.0
Chrome 66.0.3359.139
TL;DR - Firefox/Chrome 没有像我预期的那样附加事件侦听器。边缘做到了。
解决方案
根据我的观察,差异源于以下事实:
- 在 chrome/firefox 和 IE 中,添加的 eventListener 不会为当前事件触发,而是为下一个事件触发。
- 在 chrome/firefox 中删除的事件监听器立即阻止调用处理程序 WHEREAS 中,已经附加到元素上的处理程序将触发,但效果
removeEventListener
将在引擎的下一个滴答声中发生。
这就是为什么在这两种情况下(ie 和 firefox/chrome),第一次点击不会触发 function-3,但随后的点击将在 ie 中触发。为了纠正这种行为,我的解决方案是添加到 ie stopImmediatePropagation
:
function functionTwo(e) {
console.log('functionTwo called');
// My intial mistake was here: I put functionThree in by accident
// and only then noticed the strange behaviour
button.removeEventListener("click", functionThree);
console.log("Doing some asynchronous work...");
// Same here: I should have put functionOne as the second argument
button.addEventListener("click", functionThree);
e.stopImmediatePropagation();
}
现在 ie 将表现得像 firefox/chrome。
推荐阅读
- javascript - 在 mvc JavaScript 中的下拉更改选择上加载列
- html - Angular matdatepicker 未按应有的方式显示
- vb.net - 任何人都可以帮助我了解 WinForms 应用程序中的命令行参数吗?
- reactjs - 状态更改时如何停止在上下文使用者中重新呈现列表项
- progressive-web-apps - URL 栏未隐藏
- c - 如何仅使用 C 中的整数将十六进制转换为十进制
- python - 从字典列表到具有相同值的字典列表
- raspberry-pi - PyBluez over HCI 在 ESP32 的 Raspberry Pi 计算模块上工作异常
- javascript - 如何从 webpack 编译的模板文字中删除 \n 和 \t?
- twilio - 有没有办法调用私有/受保护的 twilio 函数?