这两个jQuery如何区别以及直接和委托事件模型

时间:2012-08-15 15:50:13

标签: jquery

所以,这可能是一个非常简单的问题,但无论如何我都会问。这显然只是为了澄清这两个陈述是如何运作的。

情景 我通过Ajax调用一些JSON,然后我插入到html中,它有一些选择器。像这样:

$.each(r, function(k,v){
  str+='location: <div class=\'loc-to-select\' data-location-id=\'' + v.id +  '\'>';
  str+= v.name + '</div>';
});
$('#event-search-locations').html(str);

基本上写出:

<div class='loc-to-select' data-location-id='2'>Joe's</div>

我有两个jQuery:

// doesn't work
$('.loc-to-select').on('click',function(){
  alert('here you go');
});

// does work
$(document).on('click','.loc-to-select', function(){
  alert('here you go');
});

所有这一切都明确发生在jQuery的$(文件).ready已经完成解雇之后。据我所知,这是jQuery提供的主要功能。我熟悉事件冒泡的概念。我还在这里阅读了文档http://api.jquery.com/on/,其中讨论了委托事件。我不是在内部通过后代元素来了解jQuery是如何做到这一点的。其中一些讨论了如何处理用户空间pov:Direct vs. Delegated - jQuery .on()

此外,出于性能原因,似乎优选后代元素技术。后代元素模型是否基本上说,如果我们将新的东西添加到DOM中,检查它是否符合'委托元素'模型而直接事件绕过这个?

在一个更简单的层面上,jQuery'运行时'本质上是监视DOM的变化,然后检查或检查早期的例如html函数(实质上是通过html解析它知道的项目)?

最后,他们为什么不将第二种语法(委托语法)设为默认语言?它似乎提供了更大的特异性和更好的性能(如文档中所述)

thx

1 个答案:

答案 0 :(得分:3)

我并不是100%肯定你想知道什么,因为你链接到(Direct vs. Delegated - jQuery .on())的问题似乎能解决你所要求的问题。

这又是对差异的解释:

$('.loc-to-select').on('click',function(){
  alert('here you go');
});

将搜索当时存在的所有.loc-to-select元素,并将事件处理程序绑定到每个元素。

使用DOM API的等价物是:

var elements = document.getElementsByClassName('loc-to-select');
for(var i = 0, l = elements.length; i < l; i++) {
    elements[i].onclick = handler;
}

现在考虑

$(document).on('click','.loc-to-select', function(){
  alert('here you go');
});

仅将一个事件处理程序绑定到document。它检查每个点击事件,并测试它是来自或来自具有类loc-to-select的元素。

同样,DOM等效(简化):

document.body.onclick = function(event) {
    if(event.target.className === 'loc-to-select') {
         handler.call(this);
    }
}

jQuery不监视DOM的更改,它只是使用事件正在冒泡树的事实。

  

最后,他们为什么不将第二种语法(委托语法)设为默认语言?它似乎提供了更大的特异性和更好的性能(如文档中所述)

让我们再次回顾一下事件委托中发生的事情:单个事件处理程序绑定到一个元素来处理多个(相似)元素。这意味着您只需要搜索并触摸x元素来处理y元素,其中x << y,即设置更快。

它有一个权衡但是:由于事件首先遍历树并且必须评估原点,无论它是否匹配,处理事件发生时需要更多时间。
想一想如果您将事件委派用于页面上的所有点击事件并将处理程序绑定到document,会发生什么。您最终会得到n绑定到document的事件处理程序,并且只需单击一下即可执行每个事件处理程序。但是在n之内,只有一个 需要才能执行。这似乎不是很有效。

使用直接事件处理时,设置速度较慢,因为您必须找到所有元素并将事件处理程序绑定到每个元素。如果元素不多,那不是问题,但如果有很多元素,那就可以了。显然,浏览器在绑定的事件处理程序越多时表现越差,但这可能会改变或已经存在。

将许多事件处理程序绑定到许多元素执行的次数较少,并且很少有事件处理程序绑定到很少次执行的少量元素之间的权衡。