3

所以,这可能是一个非常简单的问题,但我还是会问。这显然只是为了在我心中澄清这两个陈述是如何工作的。

场景我通过 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 的 $(document).ready 完成触发之后。据我了解,这是 jQuery 提供的主要功能。我熟悉事件冒泡的概念。我还阅读了此处的文档http://api.jquery.com/on/ ,其中讨论了委托事件。我在内部不了解 jQuery 是如何通过后代元素做到这一点的。其中一些讨论了它如何从用户空间 pov 处理:Direct vs. Delegated - jQuery .on()

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

在更简单的层面上,jQuery“运行时”本质上是监视 DOM 的更改然后检查还是在更早的时候检查例如 html 函数(本质上是通过 html 解析它知道的项目)?

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

谢谢

4

1 回答 1

3

我不能 100% 确定您想知道什么,因为您链接到的问题(直接与委托 - 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. 它检查每个点击事件并测试它是否来自具有 class 的元素或内部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只有一个 需要被执行。这似乎不是很高效。

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

这是在将许多事件处理程序绑定到许多执行较少次数的元素和将少数事件处理程序绑定到少数执行多次的元素之间进行权衡。

于 2012-08-15T15:55:28.247 回答