jQuery:委托总是比直接函数绑定更好

时间:2015-08-27 01:06:03

标签: javascript jquery delegates click

自第一选择以来,使用$(document).on('click', selector, fn)总是比$(selector).click(fn)更好:

1)可以处理动态创建的元素

2)在页面加载期间更快..对吗? (因为JS不必花时间查询和绑定每个选择器的功能)

忘记直接绑定是否安全并且总是去代表团?

1 个答案:

答案 0 :(得分:0)

通过我的研究,我得出结论,一个好的委托方法比直接绑定更好。让我们从乞讨谈谈。我们知道dom事件会从目标元素冒泡到它的父级,祖父级,直到document。虽然IE和其他浏览器之间存在一些差异,但Jquery event会创建一致的跨浏览器行为。因此,两种方法之间的明显区别在于:

直接绑定事件将在目标(或其后代)上发生并冒泡到document,而委托只会冒泡到最外面的绑定目标。考虑这个例子:

$("#myBtn").click(function(){
    console.log("button was clicked");
});

document.onclick = function(){
    console.log("document is clicked");
}
<div id="testDiv" style="background:darkgrey">
    <button type="button" id="testBtn">click me</button>
</div>

点击按钮后,系统会触发document.onclick。 但是,如果使用委托方法替换:

$("#myDiv").on("click", "#myBtn", function(){
    console.log("myBtn was clicked");
});

document.onclick不会被触发。同时,请注意点击最外面的myDiv不会触发事件。

这是关键点。以良好的方式使用委托方法将极大地提高性能。请参阅此示例(从专业javascript for web developer 变异):

<ul id="myLinks">
  <li id="goSomewhere"> Go somewhere </li>
  <li id="doSomething"> Do something </li> 
  <li id="sayHi"> Say hi </li>
</ul>

传统的直接绑定方式是:

$("#goSomewhere").click(function(){
  window.location.href = "http://sample.com";  
});

$("#doSomething").click(function(){
  window.title = "I change the title";  
});

$("#sayHi").click(function(){
  alert("hi");  
});

如果有很多点击事件,绑定操作的数量将消耗大量内存以及长页面初始时间。我们可以减去只有一个带委托的绑定操作:

$("#myLink").on("click", function(event){
    switch(event.target.id){
      case: "goSomewhere":
         window.location.href = "http://sample.com";
         break;
      case: "doSomething":
        window.title = "title was changed";
        break;
      case: "sayHi":
         alert("hi");
        break;
    }
});

这减少了要使用的内存。更实际的是,如果有很多情况,您可能需要使用object替换switch-case模块以获得性能,例如:

var eventHandler = {
  goSomewhere: function(){ window.location = "http://sample.com"; },
  doSomething: function(){ window.title = "title changed"; },
  sayHi: function(){alert("hi"); }
}
$("#myLink").on("click", function(event){
  if(eventHandler[event.target.id]) eventHandler[event.target.id]();
});

因为javascript的对象实际上是一个哈希表。

然后,有一个想法:只需将一个事件附加到document即可处理所有事件。它对mousedown,click,keydown等事件很实用,不适合mouseout,mousein。优点很明显:我们只是绑定一个导致内存较少的事件,很容易删除事件处理程序,不需要等待文档就绪事件,因为document已经可见,因为它的子script已被读取。在联系中,如果您只是将每个事件绑定到document,那么优势就会消失。

此外,如果使用直接绑定,则存在陷阱,示例来自jquery:考虑包含1000行的表:

$( "#dataTable tbody tr" ).on( "click", function() {
  console.log( $( this ).text() );
});

这会将一个汉字附加到1000 tr!但以下只是tbody的一个附件:

$( "#dataTable tbody" ).on( "click", "tr", function() {
  console.log( $( this ).text() );
});