使用jQuery托管事件对阻止冒泡的影响

列表范例
移动App中常见的列表

jQuery托管事件是个好东西,减少侦听器的数量,还能降低内存泄露的风险,尤其在列表类的应用比较常见。

想象一个如右图所示的下载列表,点击各列表项会展开详情,用户可以在里面查看详细信息;不展开的话也可以直接点击右边的下载按钮,就会直接下载应用。使用jQuery来写代码大概是这样的:

$('#app-list li').on('click', function (event) {
  // 显示/隐藏详情
  $(this).toggleClass('active');
});
$('#app-list .download-button').on('click', function (event) {
  // 下载通过超链进行
  // 这时为了不让详情展开,需要阻止事件冒泡
  event.stopPropagation();
});

假如列表里有20个选项,那么这样就会添加40个侦听器。在PC浏览器里这样做问题不大,但是移动设备内存比较少的话可能会引发问题。另外,如果我们还引入了“上拉读取更多”和“下拉刷新”的功能,那么就要为内容的更新添加更多的代码,以避免内存泄露。所以这时,就应当将事件托管到ul去处理。( 关于jQuery事件托管可以参考其文档(http://api.jquery.com/delegate/)。)

$('#app-list').on('click', 'li', function (event) {
  $(this).toggleClass('active');
});
$('#app-list').on('click', '.download-button', function (event) {
  event.stopPropagation();
});

可以看到,我没有修改事件处理函数。这样做,我们只添加了2个侦听器,并且不管#app-list里的内容如何变化,都不需要重新注册侦听器。这给代码减了不少负。

不过接下来我发现,点击按钮后,详情仍然会被展开收起,似乎阻止冒泡的代码没有生效。仔细一想,对了,我已经把事件注册到#app-list上了,所有的事件其实都是冒泡上来的,所以点击按钮,冒泡必然经过上层节点。于是继续修改代码,改变事件处理函数的逻辑:

$('#app-list').on('click', 'li', function (event) {
  // 如果事件始于下载按钮,则退出
  if ($(event.target).is('.download-button')) {
    return;
  }
  $(this).toggleClass('active');
});

这样便万事大吉了。

如果您觉得文章内容对您有用,不妨支持我创作更多有价值的分享:


已发布

分类

来自

评论

《“使用jQuery托管事件对阻止冒泡的影响”》 有 1 条评论

  1. […] 使用jQuery托管事件对阻止冒泡的影响 […]

欢迎吐槽,共同进步

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据