1. 程式人生 > >jQuery的事件委託機制和事件繫結的區別

jQuery的事件委託機制和事件繫結的區別

首先看一下DOM樹:


當我們點選一個事件的時候,其觸發了連線元素的單擊事件,該事件則引發任何我們已經繫結到該元素的單擊事件上的函式的執行。

例如:

     $('a').bind('click',function(){

alert("hello world");

})

click事件接著會向樹的根方向傳播最終會傳播到window物件,

在操縱DOM的語境中,document是根節點。

1:.bind()事件

 如上例所示,jQuery掃描檔案找出所用的$('a')元素,並把alert函式繫結到每個元素的click事件上。

2:.live()事件

 如:$('a').live('click',function(){

     alert('hello world');

})

JQuery把alert函式繫結到$(document)元素上,並使用’click’和’a’作為引數。任何時候只要有事件冒泡到document節點上,它就檢視該事件是否是一個click事件,以及該事件的目標元素與’a’這一CSS選擇器是否匹配,如果都是的話,則執行函式。
  live方法還可以被繫結到具體的元素(或“context”)而不是document上,像這樣:

[javascript] view plain copy
  1. $('a', $('#container')[0]).live(...);   
3:delegate事件 [javascript]
 view plain copy
  1. $('#container').delegate('a''click'function() { alert("That tickles!") });   
  JQuery掃描文件查詢$(‘#container’),並使用click事件和’a’這一CSS選擇器作為引數把alert函式繫結到$(‘#container’)上。任何時候只要有事件冒泡到$(‘#container’)上,它就檢視該事件是否是click事件,以及該事件的目標元素是否與CCS選擇器相匹配。如果兩種檢查的結果都為真的話,它就執行函式。
  可以注意到,這一過程與.live()類似,但是其把處理程式繫結到具體的元素而非document這一根上。精明的JS’er們可能會做出這樣的結論,即$('a').live() == $(document).delegate('a'),是這樣嗎?嗯,不,不完全是。

現在用的比較多的就是on了

 通過檢視jQuery的原始碼(我檢視的版本是1.12.4),可以發現無論bind()還是delegate()都是通過on()方法實現的,只是引數不同,如下圖: 
這裡寫圖片描述

直接繫結和事件委託

1:直接繫結:大多數瀏覽器的事件冒泡,都是從文件的最深、最內層發生事件的元素(也稱為event target——事件目標),一路向上到達body或document元素上。在IE8和之前的版本上,少數事件例如change、submit不支援原生的事件冒泡,但jQuery模擬並建立了一致的、跨瀏覽器的事件冒泡行為。

如果on()方法的selector 引數為空,事件處理程式就被稱為直接繫結。每當在被繫結元素上(如下例中被繫結的document元素,譯者注)發生事件時,無論這個事件發生在這個元素上還是從內層元素經冒泡而來,該處理程式都會被呼叫。

      並且,如果on()方法的selector 引數為空,它與bind()方法相同——只能繫結頁面已有元素的事件。

下面我們用程式碼說明什麼是直接繫結

<body>
<div>
        這是一個div
        <button>點選</button>
</div>
<script type="text/javascript">
        $(function(){
            //將click事件繫結在document物件上,
            //頁面上任何元素髮生的click事件都冒泡到document物件上得到處理
            //從而呼叫事件處理程式
            //本例為了簡單繫結到了document,實際上繫結到那個元素上都有類似效果
            $(document).on("click",function(e){
               console.log(e.target.tagName + " is clicked")
            })  
        })
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

      頁面執行效果如下圖: 
這裡寫圖片描述

      如果on()方法的selector 引數不為空,事件處理程式就被稱為委託。當事件直接發生在被繫結的元素上(如下例中繫結到document上,譯者注)時,該程式不會被呼叫,而只有當事件發生在與選擇器匹配的內部元素上(如下例中click事件發生在button上,譯者注)時,才會呼叫該程式。

jQuery的事件委託是將事件從事件的發生者(即event target,譯者注)一直向上冒泡到綁定了事件處理程式的元素上(例如從最內層元素向上冒泡到最外層元素),併為冒泡“沿路”過程中匹配的所有選擇器執行事件處理程式。

      下面我們用程式碼說明什麼是委託

<body>
    <div>
        這是一個div
        <button>點選</button>
    </div>
    <script type="text/javascript">
        $(function(){
            //將click事件繫結在document物件上,
            //並傳入第二個可選引數:selector
            //當事件冒泡到document物件時,檢測事件的target,
            //如果與傳入的選擇符(這裡是button)匹配,就呼叫事件處理程式即觸發事件,否則不觸發。
            $(document).on("click","button",function(e){
                console.log(e.target.tagName + " is clicked")
            })
        })
    </script>
    </body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

      面執行效果如下圖: 
這裡寫圖片描述

事件處理程式只會被繫結到當前已被選定的元素上(如上例中的document元素上,譯者注),這些元素在呼叫on()方法時必須已經存在——同bind()。

為了確保這些元素已經存在並能被選中,請將程式碼放置到</body>標籤之前或者在$(function(){ ... })內執行事件繫結。或者,使用事件委託來繫結事件處理程式。

事件委託的優點 
      1、能處理來自於內層子元素的事件,這些內層子元素是在稍後時間裡被新增的文件中的。通過選擇一個在繫結事件委託處理程式時肯定存在的元素,就可以使用事件委託來避免 需要頻繁的新增和刪除事件處理程式的操作。 
      這個元素可以是MVC模式下的一個檢視容器元素或者是document元素(如果事件處理程式需要監聽文件中的全部冒泡事件)。在載入任何html程式碼之前,document元素已經在html文件的頭部存在了,所以無需等待dom ready就可以在document這個元素上繫結事件了,這是安全可靠的。

      2、除了可以處理尚未建立的內層子元素的事件,事件委託的另一個優點是:當需要監聽很多元素時,事件委託的效能更好。

例如:有一個1000行資料的表格,下面的程式碼就是將一個事件處理程式繫結到這1000個元素上,事件繫結需要執行1000次。

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

      事件委託方式(如下程式碼)是將事件處理程式繫結到一個元素上,即tbody上,事件只需向上冒泡一級(從被點選的tr元素到tbody元素)。事件只需繫結一次,然後採用事件冒泡來觸發事件。

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

總結

1.選擇器匹配到的元素比較多時,不要用bind()迭代繫結 
2.用id選擇器時,可以用bind() 
3.需要給動態新增的元素繫結時,用delegate()或者on() 
4.用delegate()和on()方法,dom樹不要太深 
5.儘量使用on()來代替delegate()和bind() 
6.在需要為較多的元素繫結事件的時候,優先考慮事件委託,可以帶來效能上的好處 
7.bind()和delegate()都是通過on()方法實現的,只是引數不同——當on()的selector引數為空時,其效果完全等同於bind();當selector引數不為空時,其效果完全等同於delegate(); 
8.使用.on()方法時,事件只會繫結到$()函式的選擇符表示式匹配的元素上(上面例子中,為了簡單繫結到了document),因此可以精確地定位到頁面中的一部分,從而減少事件冒泡的開銷。

停止傳播

  最後一個我想做的提醒與事件傳播有關。通常情況下,我們可以通過使用這樣的事件方法來終止處理函式的執行:
[javascript] view plain copy
  1. $('a').bind('click'function(e) {    
  2. e.preventDefault();    
  3. // 或者  
  4. e.stopPropagation();    
  5. });    
  不過,當我們使用live或是delegate方法的時候,處理函式實際上並沒有在執行,需要等到事件冒泡到處理程式實際繫結的元素上時函式才會執行。而到此時為止,我們的其他的來自.bind()的處理函式早已運行了。
原文出處:點選開啟連結

相關推薦

jQuery事件委託機制事件區別

首先看一下DOM樹: 當我們點選一個事件的時候,其觸發了連線元素的單擊事件,該事件則引發任何我們已經繫結到該元素的單擊事件上的函式的執行。 例如:      $('a').bind('click',function(){ alert("hello world"); })

JS事件機制事件事件監聽、事件委託(代理)事件執行順序總結

JS 對於使用者的操作做出響應,就必須對DOM元素繫結事件處理函式 事件繫結  1、在DMO中直接繫結事件 <input type="button" value="click me"

jQuery事件-委託機制事件物件

委託機制 語法:.on( events ,[ selector ] ,[ data ], handler(eventObject) ) 原理:如果提供了第二引數,那麼事件在往上冒泡的過程中遇到了選擇

jQuery事件解除

HTML程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>練習</title>

jQuery: Ajax動態載入內容on()事件無效的解決方法

問題描述 這是一個很普遍但又經常犯錯的問題,還是記錄一下。 一個例子 HTML: <div id="the_div"> </div> <button id="btn">test</button> javascript

jQuery動態生成的元素如何事件

 這段時間在寫程式碼的時候遇到一個問題,通過append()新增的節點,點選事件不起作用。當時我百思不得其解,各種找錯都沒找到錯誤的原因。後來才發現是動態生成節點的問題,還是自己沒有經驗啊。   下面來

js IE火狐事件

<script> function(){ var EventUtil = { addHandler: function(element, type, handler){ if (element.addEventListener){

從零開始學 Web 之 jQuery(六)為元素多個相同事件,解綁事件

一、為元素繫結多個相同事件 1、方式一 $("#btn").click(function () { console.log("click1"); }).click(function () { console.log("click2"); }).cli

jQuery-為動態新增的元素事件(以及不重複新增新的內容)

在使用jQuery的方式為元素繫結事件時,我經常使用bind或者click,但這隻能為頁面已經載入好的元素繫結事件。像需要用ajax的方式請求遠端資料來動態新增頁面元素時,顯然以上幾種繫結事件的方式是無效的 $(selector).bind(event,d

利用jquery給動態載入的元素事件

工作中經常會遇見利用ajax載入dom元素,這樣就不能給動態載入的元素繫結時間 此時可以利用jquery的on方法解決(老版本使用live方法) $(document).on("click",".edit-btn",function(){             aler

jquery bind 方法一個特點(多個方法到一個dom的某個事件

目錄: [TOC] jquery bind方法介紹 方法宣告:bind(type,[data],fn) 方法說明:為每一個匹配元素的特定事件(eg:click)繫結一個事件處理器函式。這個事件處理函式會通過引數方式接收到一個事件物件,可以通過它來阻止(瀏

jquery html動態新增的元素事件

在實際開發中會遇到要給動態生成的html元素繫結觸發事件的情況: <div id="testdiv">    <ul></ul> </div> 假設我們要給ul動態新增的<li>繫結click事件形成如下結果 &

Jquery給動態新增的元素事件:live() delegate() on()

給已存在的元素繫結事件時可以直接寫: $(".class a").click(function(){ }) 但是對於動態生成並append()到頁面上的元素來說,就不能直接用上面的方法來繫結事件了。 在Jquery 1.7之前我們可以通過live()和delega

關於 jquery html 動態新增的元素事件——On()

Ajax動態生成的資料,動作繫結需要重新執行1 $(document).on('click','.btn1',function(){}); 2 3 替換: 4 5 $('btn1').on('click') = function(){};JQuery On()定義和用法on() 方法在被選元素及子元素上新

jQuery向動態新增的元件事件

jquery中繫結事件一般使用bind,或者click,但是這隻能是對已經載入好的元素定義事件,那些後來新增插入的元素則需要另行繫結。在1.7版本以前使用live。但是在1.8版本以後推薦使用on。 $('body').on('click','.admi

jQuery bind/One/live三種事件方法的區別

1. bind/Unbind 在jquery的事件模型中,有兩個基本的事件綁 定函式,bind與unbind,這兩個函式的含義就是匹配頁面元素進行相關事件的處理。比如我們在JS中經常使用到的 onfocus,onblur,onmouseover,onmousedown等事件都可以作為bind的引數進行傳遞。$

Jquery 對新插入的節點 Click事件失效

1.有人說用 Live, 事實上現在最新的Jquery已經不支援 Live 了。live的解決方法如下: 你可以看這個 也可以不看 ,只是做到心中有數就可以了。下面介紹ON的方法。 2.有人用了ON 來解決, 這個解決方法基本在理。 On的方法,基本能解決問題,但是你也要根據你的具體情況

jquery動態新增元素無法觸發事件的解決方案。

  最近遇到一個問題,即當用jquery動態新增元素後,發現給動態新增的元素卻無法觸發事件。後來在網上查閱了一些資料,發現原來要這樣處理:   先上我出錯的程式碼:    <!DOCTY

Qt消息機制事件

參數 question 建立 idg 鍵盤 exe mes ber 也不能 Qt消息機制和事件 1 事件 事件(event)是由系統或者 Qt 本身在不同的時刻發出的。當用戶按下鼠標、敲下鍵盤,或者是窗口需要重新繪制的時候,都會發出一個相應的事件。一些事件在對用戶操作做出響

jQuery的onclick直接click區別

狀況之外 在之前的公司並沒有遇到這個問題,也就沒有深究。直到自己換了現在的公司,剛來第二天就開始寫別人寫到一半的專案,很無奈,不是原生就是jquery,由於專案急,已經來不及切換框架重新佈局,只能繼續了。 狀況之中 到處都是列表,到處都是js建立的動態頁面,好吧,那我也繼續吧,突然,意外發生了