1. 程式人生 > >JQuery中bind事件和live事件的區別

JQuery中bind事件和live事件的區別

       今天在和同事聊天的時候聊到了關於JQuery中bind事件和live事件的使用,感覺在日常程式碼中大多使用的都是bind很少接觸live,一直以來對於bind的事件繫結都挺順手的就沒想著去調整使用live,今天因為這個討論重新瞭解JQuery的事件繫結機制,發現原來bind方法一直都存在缺陷,而live方法相當於是對bind的補足。

        首先要說的還是總結,JQuery對於事件的繫結大概有三種模式:

一:直接使用內建方法繫結,如$("#clickThis").click(function(){});

二:使用bind來繫結事件,如$("#clickThis").bind('click',function(){});

三:使用live來繫結事件,如$("#clickThis").live('click',function(){});

第一種方法很明顯,一看就能明白是給id為clickThis的控制元件繫結點選事件,不細說了。

第二種方法和第三種方法在程式碼上看起來基本是一模一樣的,但實質上卻存在一定的差別。就像我一開始說的,live方法是對bind方法的補足,在我們實際專案過程中,有的控制元件在頁面載入的時候是不存在的,只有在使用者觸發某一個方法以後才會生成這麼一個控制元件,對於這樣的控制元件上繫結事件,bind就沒有辦法實現了。原因是bind方法會在頁面載入的時候就去判斷是否存在目標控制元件,如果存在可以繫結事件,如果不存在就無法繫結事件上去。這個判斷只有在頁面載入的時候才會進行,也就是說,當頁面載入的時候還不存在你要控制的目標控制元件,那麼你的bind事件就是一句冗餘程式碼,沒有絲毫作用的,而當用戶互動之後生成了這個控制元件,這個控制元件同樣繫結不了bind事件。這個需求就在live方法裡面被補充了,live方法在本質上完成的是和bind方法相同的工作,只是live方法在對目標控制元件是否存在的判斷上是“滯後”的。

live方法是基於“事件委託”的,所謂的“事件委託”指的是,繫結在祖先元素上的事件可以在其後代元素上進行使用。在頁面載入到live方法的時候,live方法會去判斷DOM中是否存在目標控制元件節點,如果沒有找到,就一層一層的向上冒泡,將事件“委託”到DOM根節點上。

舉個栗子:在ready中有:

$(".ClickThis").live('click',function(){alert("Success!")});

$("body").append("<div class='ClickThis'>測試live</div>");

在我們點選“測試live的div時會執行以下過程:

一、生成一個click事件,並在div上尋找對應的事件;

二、由於在div上找不到click事件的繫結,尋找會一直隨著DOM樹向上查詢

三、在DOM根節點找到了click事件的繫結

四、找到這個繫結以後開始執行繫結事件

五、執行的第一步就是返回去檢視是否已經存在了目標控制元件,如果是目標控制元件觸發的click則執行。

看到這裡,是不是覺得live方法比bind要強大的多了,是不是很想不清楚為什麼bind方法沒有被live方法給替換掉而是依然存在,或者說為什麼live方法不直接在bind上面進行補足而是重開了一個新的方法名。其實實際上,bind方法還是存在自己的優勢的。比如說:

(1)bind方法可以繫結任何JavaScript的事件,而live方法在jQuery1.3的時候只支援click, dblclick, keydown, keypress,

keyup,mousedown, mousemove, mouseout, mouseover, 和 mouseup.在jQuery 1.4.1中,甚至也支援 focus 和 blue事件了(對映到更合適,並且可以冒泡的focusin和focusout上)。另外,在jQuery 1.4.1中,也能支援hover(對映到"mouseenter mouseleave")。

    (2)live() 並不完全支援通過DOM遍歷的方法找到的元素。取而代之的是,應當總是在一個選擇器後面直接使用 .live()方法。

    (3)當一個元素採用live方法進行事件的繫結的時候,如果想阻止事件的傳遞或冒泡,就要在函式中return false,僅僅呼叫stopPropagation()是無法實現阻止事件的傳遞或者冒泡的