【问题标题】:Is it bad to bind behaviours to document unconditionally?将行为无条件地绑定到文档中是不是很糟糕?
【发布时间】:2013-05-26 13:05:00
【问题描述】:

我正在处理的页面上的分页控件被有条件地绑定在超过 1 页的情况下。我不喜欢在我的项目中看到下面的代码,

if (pages > 1) {
  $('.some_class').bind('event', function() {});
}

因为我觉得它代表了一种杂乱无章的编码风格。我会把它放在与到处散布return 语句而不是使用控制相同的水平上。我觉得将事件绑定到全局可用对象在函数调用的本地范围内没有位置。所以我通常做的是制作两个javascript文件,例如:pagination.jspagination-controls.js。在一个中,我有关于构建 html 和显示分页控件的逻辑。在另一个我有如下陈述:

$(document).on('click', '.pagination .next', function() {});

无论页面上的任何位置是否有 $('.pagination .next') 元素都会触发。我喜欢这种感觉:网站有行为,它只知道 id 和类,而不知道某个本地范围内的实例变量。

编辑:这绝对是不好的做法,如下所述。然而:

从 jQuery 1.7 开始,.on() 方法是 将事件处理程序附加到文档。

关于direct and delegated 事件的讨论是相关的。特别是我认为以下描述了我的用法:

通过选择一个保证在 附加了委托事件处理程序,您可以使用委托事件 避免频繁附加和删除事件处理程序的需要。这 element 可以是视图中的容器元素 例如,模型-视图-控制器设计,或记录事件 处理程序想要监视文档中的所有冒泡事件。

编辑:所以我想现在我想知道“无条件地首选绑定行为而不是基于逻辑的绑定是不是很糟糕?”这可能只是风格问题,我原来的问题已经回答了,所以我想我会接受这个答案。

【问题讨论】:

  • 我会说这很浪费,除非您确实有 +1 页面,否则无论如何您都会绑定事件,这意味着您必须在设计应用程序时为这种情况做好计划。鉴于此,我不确定这是否真的很浪费。我有点像在使用大部分内存之前为桌面应用程序保留一大块内存。
  • 好吧,这样看。页面上发生的每个点击事件都将被该事件捕获,并且针对选择器测试 event.target 以查看它是否匹配。如果您使用第一个,它不会为您的应用程序中的每次点击添加额外的处理。
  • 选择一个 JS 框架并使用它。 jQuery 自然而然地让自己在几乎所有级别上都与 UI 相关的代码一团糟,现在有一些非常好的框架可以为您解开这一点,并为分离关注点提供可靠的约定。
  • 我最初不明白您将它们绑定到顶级文档。我想我应该先阅读整个问题。我猜这真的取决于你有多少这些事件,以及是否有机会在不刷新页面的情况下开始使用它们。 (也就是动态构建一些新的 DOM 元素以作为目标)

标签: javascript jquery performance


【解决方案1】:

是的,这会导致大量不必要的开销,这是一种“不好的做法”。

将您的事件处理绑定到顶级文档对象意味着在页面中任何位置的任何元素上发生的每一次单击都会冒泡到document 对象,该对象的目标是检查它是否匹配.pagination .next

事实上,文档本身建议不要使用:

在文档树顶部附近附加许多委托事件处理程序会降低性能。每次事件发生时,jQuery 必须将该类型的所有附加事件的所有选择器与从事件目标到文档顶部的路径中的每个元素进行比较。为获得最佳性能,请将委托事件附加到尽可能靠近目标元素的文档位置。 避免在大型文档的委托事件中过度使用 document 或 document.body。

所以,您误用了on。它用于直接绑定到元素或可能动态创建子元素的父元素,并且您应该绑定到最接近的可能父元素。绑定到文档当然不是唯一您在页面中处理事件的方式。

【讨论】:

  • 是的,我猜它说“避免过度使用 document 或 document.body 来处理大型文档的委托事件。”就在文档中。
  • @Ziggy 谢谢,是的,更新我的答案。
  • 如果我将事件绑定到包装分页控件的div 元素,我认为这会更合理。
  • @Ziggy 你真的不应该使用on。它是为了允许将事件绑定到 DOM 中尚不存在的元素;如果你的 DOM 是静态的,你绝对应该使用 $('.some_class').bind...
  • 正确:当我说“不喜欢看”时,我的意思是“不认为是有组织的”。在我看来,这与长函数中间的return 语句的严重性相同。另一方面$('.pagination-controls').on('click', function() {}); 可能更合理? [我在阅读上述评论之前写了这篇评论]
猜你喜欢
  • 2010-10-30
  • 1970-01-01
  • 2010-11-24
  • 2011-10-06
  • 2021-06-29
  • 1970-01-01
  • 2020-01-29
  • 2020-01-27
  • 1970-01-01
相关资源
最近更新 更多