JavaScript:
parent.addEventListener("click", function(e) {
if (e.target === child) { code }
});
对比
jQuery:
$(parent).on("click", child, function() {});
JavaScript:
parent.addEventListener("click", function(e) {
if (e.target === child) { code }
});
对比
jQuery:
$(parent).on("click", child, function() {});
on
方法会做更多的工作,为您提供额外的功能,例如在事件冒泡到根时运行选择器,因此事件来自您期望的元素;如果不小心,可能会有问题。引用文档,在事件性能下面:
另一方面,纯JavaScript则更直接地引发在该元素下发生的任何事件,因此您必须非常具体。在文档树顶部附近附加许多委托事件处理程序可能会降低性能。每次事件发生时,jQuery必须将该类型的所有附加事件的所有选择器与事件目标路径上的每个元素进行比较。
e.target
来查找实际引起事件的原因。# suggested JavaScript version
parent.addEventListener("click", function(e) {
if (e.target === child) { code }
});
# correct equivalent jQuery version
$(parent).on("click", function(e) {
if (e.target === child) { code }
});
简短版:性能差异微乎其微,不会有太大影响。
详细版:两个版本看起来几乎一样。jQuery 变体稍微慢一点,但可以忽略不计。如果我正在使用 jQuery(例如方法链接)或想要使用 jQuery 来提高可读性/一致性,我会使用 jQuery 版本。
出于速度原因而使用 JavaScript 版本,同时又为了在该项目中捍卫/推广/倡导使用 jQuery 而使用 jQuery 版本,这将产生利益冲突。
# OP’s version: jQuery selector/delegate syntax
$(parent).on("click", child, function() { code });
本回答的其余部分通过示例展示了jQuery的错误:
我认为我们都同意一个事件应该最多调用一次处理程序。通过以下代码示例,我向您展示了一个单个事件如何触发3次处理程序的调用。
点击内部框查看jQuery如何将一个单一事件应用于目标元素和处理器元素之间的所有匹配元素。我不知道这种机制的合理用例,即使这种意外和奇怪的行为没有影响到您,jQuery所做的额外工作仍然存在。
它要么没效果只会浪费CPU周期,要么会创建错误。
let lastEvent;
function analyze(tag, event) {
const oe = event.originalEvent;
console.log(`${tag}: Event on ${event.target.id} is ${lastEvent === oe ? 'repeated' : 'new'}.`);
lastEvent = oe;
}
body.addEventListener('click', event =>
console.log('click', event.target.id));
$(body).on('click', analyze.bind(null, '$click'));
$(body).on('click', '.hit', analyze.bind(null, '$delegateClick'));
div.hit {
margin: 20px;
border: solid black 2px;
}
#inner {
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body id=body>
<div id=outer class=hit>
<div id=middle class=hit>
<div id=inner class=hit>
</div>
</div>
</div>
</body>