最近我一直致力于一个相对简单的个人项目,我需要生成相当数量的Javascript来将各种事件处理程序绑定到元素(例如on('click')
),这让我想知道效率每个元素生成多个on('click')
定义,基于数组中的值(可能会更改每页加载),或者具有将其绑定到每个元素的单个函数。例如:
PHP生成jQuery
<?php
foreach($var as $key => $val){
echo '$("' . $key . '").on("click", function(){
// do something
});';
}
// Which will generate:
// $(elemkey1).on("click", function(){ // do something });
// $(elemkey2).on("click", function(){ // do something });
// $(elemkey3).on("click", function(){ // do something });
// $(elemkey4).on("click", function(){ // do something });
// ...
纯jQuery
$(elem).each(function(){
// do something
);
所以我的问题是:哪种方式可以最有效地宣布上述内容?
显然,第二个例子取决于所使用的选择器(例如它是id
还是class
,我完全知道这里的注意事项)但是除此之外,假设正确的选择器是使用,我很想知道使用PHP for循环声明每个元素的事件处理程序是否有轻微的性能优势,而不是jQuery .each()
或类似的方法。
答案 0 :(得分:5)
首选
存在性能差异,一旦打破3000左右的元素大小,它就会变得可见。不可否认的是10,000。
使用单个选择器一次以处理事件的效率要高得多,因为只有在触发时才需要检查一次click事件。
事件发送是主要原因
效率变化的主要原因是事件的运作方式。当一个事件被调度时,它必须一直传播到元素,通过DOM传播到目标,然后一直冒泡回来。与在DOM中进一步触发事件相比,这是非常低效的。
请阅读W3C的3.1. Event dispatch and DOM event flow,了解更精细的谷物细节。
以下是该部分的图表之一:
带宽和缓存在php生成的场景中也可能存在问题
除了JavaScript执行角度之外,还存在php生成代码的问题。虽然对于较小的集合来说可能可以忽略不计,但从带宽的角度来看,对于较大的集合来说这是有问题的(这在处理移动浏览时会发挥得更为明显)。此外,当服务器生成javascript代码时,为浏览器缓存将是非常困难的,假设这些集合通常会不同,因此生成不同的选择器。如果没有选择器集的缓存破坏方案(可能使用用于生成它们的术语),那么可能会缓存错误的选择器集。
答案 1 :(得分:1)
[是]使用PHP for循环声明每个元素的事件处理程序与jQuery .each()或类似的方法相比,是否有轻微的性能优势?
在没有事件委托的情况下,PHP代码中的echo循环有两个额外的开销:
echo循环为分配给它的每个元素创建一个单独的匿名函数客户端:
$(elemkey1).on("click", function(){ // do something });
$(elemkey2).on("click", function(){ // do something });
$(elemkey3).on("click", function(){ // do something });
$(elemkey4).on("click", function(){ // do something });
会创建四个独立的函数对象来处理点击。
在评估语句中的调用参数表达式时,JQuery中的客户端分配只创建一个处理函数对象:
$(elem).each(function(){
// do something
);
如果元素的数量很大,则通过在DOM中较高的父节点上捕获事件并检查哪个元素是(click)事件的目标来进行事件委托是可取的。根据评论,best practice上的这个问题进一步详细说明。
根据@TravisJ 's answer,event capturing似乎可以提高受支持浏览器中的客户响应速度。我们的想法是在捕获阶段通知事件,如果由点击处理程序处理,则阻止它进一步传播。