1. 程式人生 > >jquery-事件-on原始碼

jquery-事件-on原始碼

談一下Jquery中的bind(),live(),delegate(),on()的區別?

1.bind()

.bind()直接繫結在相應的DOM元素上,可以解決跨瀏覽器的問題。
但是對於動態新增的屬於匹配到的元素,不會被觸發事件的,需要多次繫結,影響效率。

$("#niu").bind('click',function(){
  alert("hello niuniu");
});

2.live()

live()通過冒泡的方式來繫結到元素上的,對於動態新增的屬於匹配到的元素,也能夠執行。
但是event.stopPropagation()不再有效了,因為事件已經委託到了document上了。此方法在jQuery1.7的時候已經廢除

$("a").live("click", function() { return false; })

3.delegate()

.delegate()則是通過冒泡的方式來繫結事件到制定元素上(但不是冒泡到document),對後生成的元素也可以繫結相應的事件。

delegate(selector,[type],[data],fn)

$(document).ready(function(){
    $("div").delegate("p","click",function(){
        $(this).slideToggle();
    });
    $("button"
).click(function(){ $("<p>這是一個新段落</p>").insertAfter("button"); }); });

4.on()

.on() 方法在被選元素及子元素上新增一個或多個事件處理程式

$(selector).on(event,childSelector,data,function,map)

event:必需。規定要從被選元素移除的一個或多個事件或名稱空間。

childSelector:可選。規定只能新增到指定的子元素上的事件處理程式

data:可選。規定傳遞到函式的額外資料。

function:可選。規定當事件發生時執行的函式。

map:規定事件對映 ({event:function, event:function, …}),包含要新增到元素的一個或多個事件,以及當事件發生時執行的函式。

// Bind
$( "#members li a" ).on( "click", function( e ) {} );
$( "#members li a" ).bind( "click", function( e ) {} );

// Live
$( document ).on( "click", "#members li a", function( e ) {} );
$( "#members li a" ).live( "click", function( e ) {} );

// Delegate
$( "#members" ).on( "click", "li a", function( e ) {} );
$( "#members" ).delegate( "li a", "click", function( e ) {} );
//多個事件
$(document).ready(function(){
  $("p").on("mouseover mouseout",function(){
    $("p").toggleClass("intro");
  });
});
//使用map引數新增多個事件處理程式
$(document).ready(function(){
  $("p").on({
    mouseover:function(){$("body").css("background-color","lightgray");},  
    mouseout:function(){$("body").css("background-color","lightblue");},
    click:function(){$("body").css("background-color","yellow");}  
  });
});
$("table.planning_grid").on({
    mouseenter: function() {
        // Handle mouseenter...
    },
    mouseleave: function() {
        // Handle mouseleave...
    },
    click: function() {
        // Handle click...
    }
}, "td");

總結:
1.bind()直接繫結在元素上,當元素很多時,會出現效率問題,不會繫結到在它執行完後動態新增的那些元素上

2.live()僅有一次的事件繫結,繫結到document上而不像.bind()那樣給所有的元素挨個繫結,那些動態新增的elements依然可以觸發

3.delegate()更精確的小範圍使用事件代理,效能優於.live(),它不會把所有的event全部繫結到document,而是由你決定把它放在哪兒。而和.live()相同的地方在於都是用event delegation.

4.on()是 bind()、live() 和 delegate() 方法的新的替代品,提供了一種統一繫結事件的方法
仍然提供了.delegate()的優點,當然如果需要你也可以直接用.bind()

5.on原始碼解析

首先,判斷events是否為物件,若是物件則遍歷events物件,針對每一個屬性繫結on()方法,將events[event]作為fn傳入。然後on方法其實就是對於每一個呼叫物件單獨呼叫jQuery.event.add方法進行事件繫結。另外,bind,live,delegate都是通過on實現的。

on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
    var type, origFn;

    // Types can be a map of types/handlers
    if ( typeof types === "object" ) {
        // ( types-Object, selector, data )
        if ( typeof selector !== "string" ) {
            // ( types-Object, data )
            data = data || selector;
            selector = undefined;
        }
        // 遍歷types物件,針對每一個屬性繫結on()方法
        // 將types[type]作為fn傳入
        for ( type in types ) {
            this.on( type, selector, data, types[ type ], one );
        }
        return this;
    }

    // 引數修正
    // jQuery這種引數修正的方法很好
    // 可以相容多種引數形式
    // 可見在靈活呼叫的背後做了很多處理
    if ( data == null && fn == null ) {
        // ( types, fn )
        fn = selector;
        data = selector = undefined;
    } else if ( fn == null ) {
        if ( typeof selector === "string" ) {
            // ( types, selector, fn )
            fn = data;
            data = undefined;
        } else {
            // ( types, data, fn )
            fn = data;
            data = selector;
            selector = undefined;
        }
    }
    if ( fn === false ) {
        // fn傳入false時,阻止該事件的預設行為
        // function returnFalse() {return false;}
        fn = returnFalse;
    } else if ( !fn ) {
        return this;
    }

    // one()呼叫on()
    if ( one === 1 ) {
        origFn = fn;
        fn = function( event ) {
            // Can use an empty set, since event contains the info
            // 用一個空jQuery物件,這樣可以使用.off方法,
            // 並且event帶有remove事件需要的資訊
            jQuery().off( event );
            return origFn.apply( this, arguments );
        };
        // Use same guid so caller can remove using origFn
        // 事件刪除依賴於guid
        fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
    }

    // 這裡呼叫jQuery的each方法遍歷呼叫on()方法的jQuery物件
    // 如$('li').on(...)則遍歷每一個li傳入add()
    // 推薦使用$(document).on()或者集合元素的父元素
    return this.each( function() {
        jQuery.event.add( this, types, fn, data, selector );
    });
},