jquery事件委托
jQuery使JavaScript中的事件处理变得容易。 但是,定义的事件处理程序越多,使用的内存就越多,最终可能会降低性能并导致UI变慢。 本文探讨事件委托如何帮助防止这种情况的发生,以及如何将事件委托与jQuery一起应用。
事件委托是一种事件处理技术,您可以将单个事件处理程序附加到这些元素的父元素上,以监听发生在其后代元素上的事件,而不是将事件处理程序直接直接附加到要监听事件的每个元素上。 处理事件时,请检查触发该事件的元素,并做出相应的响应。 事件委托依赖于DOM中的事件冒泡。 此过程是在子元素上触发的事件沿DOM树向上传播到其父元素以及其父元素的父元素等的过程,直到到达document
为止。 程序员也可以使用event.stopPropagation()
停止冒泡。 请注意,并非所有DOM事件都会传播-聚焦,模糊,加载和卸载不会传播。
事件委托使用的内存更少,因为您用一个事件处理程序替换了多个事件处理程序。 例如,如果将事件处理程序附加到十个链接列表中的每个链接上,则将有十个事件处理程序占用内存空间。 相反,如果使用事件委托并在父<ul>
元素上处理事件,则仅创建一个事件处理程序,并使用比单独附加到每个链接上更少的内存。 除了减少内存消耗外,事件委托还具有以下好处。
- 从DOM中添加或删除元素时,无需手动管理事件。 如果使用传统的事件处理,则必须将事件处理程序附加到添加到DOM的元素上,并从DOM中删除的元素中删除事件处理程序。
- 通过更少的事件处理功能来管理更少的代码。 这可以使我们拥有更简单的代码,而无需任何重复的事件处理逻辑,从而可以帮助我们JavaScript保持美观和DRY 。
jQuery中的事件委托示例
假设您正在开发一个出售小猫图片的单页应用程序。 页面加载时,将显示前20只小猫。 当用户向下滚动页面时,将加载更多小猫。 我们HTML如下所示。
<section id="cats">
<ul>
<li>
<img src="http://placekitten.com/200/200" alt=""/>
<a href="/moreinfo">More info</a>
<button>Add to cart</button>
</li>
...
</ul>
</section>
使用传统的事件处理,我们需要将事件处理程序连接到:
- 当用户单击缩略图时,显示较大的图片。
- 当用户单击“更多信息”链接时显示更多信息。
- 当用户单击“添加到购物车”时,将图片添加到购物车。
- 将这三个事件附加到在用户向下滚动页面时添加的新DOM元素。
此代码将类似于以下示例。 请注意,这是样板代码,旨在显示将事件处理程序附加到各个元素与使用事件委托有何不同,因此没有为loadImage()
, moreInfo()
, addToCart()
和loadNewKittens()
函数提供实现。
$(document).ready(function() {
var cats = $('#cats');
cats.find('img')
.on('click', function() {
loadImage();
})
cats.find('a')
.on('click', function(event) {
event.preventDefault();
moreInfo();
});
cats.find('button')
.on('click', function() {
addToCart();
});
$(window).scroll(function() {
var fragment = loadNewKittens();
// attach event handlers for new DOM elements
fragment.find('img')
.on('click', function() {
loadImage();
});
fragment.find('a')
.on('click', function(event) {
event.preventDefault();
moreInfo();
});
fragment.find('button')
.on('click', function() {
addToCart();
});
fragment.appendTo('#cats ul');
});
});
那是很多代码。 现在让我们看看如果使用事件委托,我们的代码看起来如何:
$(document).ready(function() {
$('#cats')
.on('click', 'img, a, button', function(event) {
event.preventDefault();
var target = event.target;
switch(target.tagName.toLowerCase()) {
case 'img':
loadImage();
break;
case 'a':
moreInfo();
break;
case 'button':
addToCart();
break;
default:
// do nothing
}
});
$(window).scroll(function() {
var fragment = loadNewKittens();
fragment.appendTo('#cats ul');
});
});
关键是on()
的可选第二个参数。 通过在此处传递选择器, on()
知道它正在处理委托的事件处理程序,而不是直接绑定的事件处理程序。
现在,我们的事件处理代码也更加简单。 通过获取event.target
并打开其tagName
,我们可以知道触发该事件的元素并可以做出适当响应。 此外,我们不再需要为$(window).scroll
加载的元素附加事件处理程序,因为这些新元素$(window).scroll
的事件将委托给父元素。
使用事件委派时可能要注意的一个“陷阱”是,在删除的事件处理程序触发之前,将处理附加到子元素的任何事件处理程序。 因此,子事件处理程序可能会调用event.stopPropagation()
或return false
,这将防止事件冒泡到委托的事件处理程序,并让您抓狂为何未委托事件。
结论
在本文中,我们研究了事件委托。 我们已经看到了它如何通过减轻它必须承担的事件处理负载来帮助提高网站的性能。 我们还看到了如何通过on()
函数在jQuery中实现事件委托。
翻译自: https://www.sitepoint.com/event-delegation-with-jquery/
jquery事件委托