不要仅仅使用
Event.target
! 正如我在网上找到的许多答案所错误建议的那样,
Event.target可能是一个
不需要的子元素! 例如考虑以下情况:
<button class="dynamic" type="button">CLICK <i>ME!</i></button>
如果你点击按钮中的
"ME!" 部分- 你的逻辑会失败得很惨。
始终与 .closest()
结合使用 Event.target
document.querySelector("#staticParent").addEventListener("click", evt => {
if (event.target.closest(".dynamic")) {
}
});
创建自己的on()
帮助函数:
对于动态创建的元素,在它们被插入到DOM之前想要分配一个点击事件 - 将事件分配给父级 代理器,然后查询事件 Event.target.closest(selector)
是否匹配所需的动态子级选择器:
const on = (evtName, delegator, ...args) => {
if (typeof delegator === "string") {
delegator = document.querySelector(delegator);
}
if (typeof args[0] === "string") {
delegator.addEventListener(evtName, (evt) => {
if (evt.target.closest(args[0])) {
args[1](evt);
}
});
} else {
delegator.addEventListener(evtName, ...args);
}
};
on("click", document.querySelector("#staticParent"), ".dynamicChild", (evt) => {
console.log(evt.target);
console.log(evt.currentTarget);
});
on("click", document.querySelector("#staticParent"), (evt) => {
console.log(evt.currentTarget);
});
这里有一个更加简洁的版本,包括一些其他有用的工具函数和更多的巧妙示例:
const el = (sel, parent) => (parent || document).querySelector(sel);
const els = (sel, parent) => (parent || document).querySelectorAll(sel);
const isStr = (str) => typeof str === 'string' || str instanceof String;
const on = (evtName, delegator, ...a) =>
(isStr(delegator) ? el(delegator) : delegator)
.addEventListener(evtName, ...isStr(a[0]) ? [e => e.target.closest(a[0]) && a[1](e), a[2]] : a);
上述片段可以像这样使用,例如:
on("click", "#delegatorParent", ".dynamicTarget", (evt) => {
console.log(evt.target);
console.log(evt.currentTarget);
});
els(".delegatorParent").forEach(elParent => {
on("click", elParent, ".dynamicTarget", (evt) => {
console.log(evt.target);
console.log(evt.currentTarget);
});
});
它也可以用于静态(现有)元素:
on("click", "#target", (evt) => {
console.log(evt.currentTarget);
});
on("click", "#target", (evt) => {
console.log(evt.currentTarget);
}, { once: true });
els(".items").forEach(elItem => {
on("click", elItem, (evt) => {
console.log(evt.currentTarget);
});
});
这是与上面相同的on()
函数,以更易读的形式书写,没有任何依赖性: