javascript - How does addEventListener uniquely identify the functions passed to it?
问题描述
Say I have some code like this:
let myFunc = () => {
console.log("hello");
}
document.addEventListener("click", myFunc);
document.addEventListener("click", myFunc);
document.addEventListener("click", myFunc);
document.addEventListener("click", myFunc);
Why does clicking the document only console log once? I don't mind this behavior, but I'm just curious how it is implemented.
For example, if you did something like this:
let events = {};
function addEventListener(key, callback) {
if (!key) { return; }
if (!events.hasOwnProperty(key)) {
events[key] = {};
}
events[key][callback] = callback;
}
Then you're using a function as a key, but aren't only strings valid for keys? How does JavaScript uniquely identify the functions so that it knows not to add the same one multiple times?
解决方案
具有特定配置的给定事件侦听器只能添加到元素一次- 如果您多次添加它,如您所见,就好像只添加了一个侦听器。这在此处的规范中有所描述:
- 如果 eventTarget 的事件监听列表中不包含类型为监听器类型的事件监听器,callback 为监听器回调,capture 为监听器捕获,则将监听器追加到 eventTarget 的事件监听器列表中。
为了扩展这一点,让听众被认为是这样的重复:
其类型是侦听器的类型
指事件名称,例如'click'
callback 是监听器的回调
必须是相同的函数引用(===
添加到先前的侦听器)
capture 是监听器的捕获
指的是监听器是在捕获阶段还是冒泡阶段监听。(这由第三个布尔参数设置为addEventListener
,默认为true
- 冒泡,或{ capture: boolean }
作为第三个参数)
如果以上都与之前添加的监听器相同,那么新的监听器将被视为重复,不会再次添加。
如果您愿意,可以多次添加此类侦听器的一种简单方法是创建一个调用您的侦听器的内联回调:
let myFunc = () => {
console.log("hello");
}
document.addEventListener("click", () => myFunc());
document.addEventListener("click", () => myFunc());
document.addEventListener("click", () => myFunc());
document.addEventListener("click", () => myFunc());
click me
以上将起作用,因为传递给的回调addEventListener
不相等:() => myFunc()
is not ===
to () => myFunc()
。
推荐阅读
- azure-devops - 如何指定特定 Azure 作业需要作业级别的给定操作系统?
- sql - sql按天查询显示不同的结果
- android - 我需要为每个页面制作横幅广告吗?
- pandas - 如何连接到另一列具有特定值的一列下的单元格?
- reactjs - Nginx 子文件夹 admin react app 在 main react app 下
- python-3.x - 用 pack() tkinter 对齐东西
- .htaccess - .htaccess RewriteRule 条件规则
- c# - 使用 AutoMapper 后实体框架分离的虚拟对象
- csv - 使用字段中的空格解析空格分隔文件
- three.js - threejs 纹理贴图 UV 与独立的 alphamap