jQuery 事件用法詳解


jQuery 事件用法詳解

目錄

簡介

實現原理

事件操作

綁定事件

解除事件

觸發事件

事件委托

事件操作進階

阻止默認事件

阻止事件傳播

阻止事件向后執行

命名空間

自定義事件

事件隊列

jquery中文文檔

簡介

jquery 之所以成為最受歡迎的前端庫,很大一部分是得益於它的事件具有良好的語義,優秀的兼容性,並且便於管理和擴展。

在這里我會介紹 jquery 事件的一些比較基礎的用法。

實現原理

jquery 事件脫胎於瀏覽器的 addEventListener (W3)attachEvent (IE) 方法 , 提供了跨瀏覽器的一致性API。具體的實現原理可以參考Aaron的系列文章
jquery源碼分析-事件

事件操作

綁定事件

jquery 中實現事件綁定有多種方式,其中 $(selector).event(func) 方式中 event 支持一系列的瀏覽器事件,文檔加載事件,表單事件,鍵盤事件和鼠標事件,但並非全部。

// 常用的寫法

$('body').click(function(){ })

$('body').on('click',function(){ })

$('body').one('click',function(){ }) // 只會執行一次,然后銷毀事件

// 其他寫法(不推薦)

$('body').bind('click',function(){ })

$('body').delegate('p','click',function(){ })

on.('click').click() 的區別

on 屬於 綁定事件處理器(event-handler-attachment) , 而 .click() 屬於 jquery包裝好的鼠標事件。

on 可以綁定dom和bom的既有事件,也可以綁定自定義的事件。所以推薦始終只使用$(selector).on(event,func) 的方式,彈性的綁定更多的事件:

$(document).hashchange(function(){ }) => 報錯,jquery沒有提供此事件處理器

$(document).on('hashchange',function(){ })  => 綁定事件成功

也可以同時綁定多個事件處理同一事務:

$('input').on('focus input',function(){ })  => 在文本框聚焦和輸入的時候,都做同樣的事情

解除事件

在不需要再繼續監聽事件執行的時候,就需要解除事件了,根據綁定事件方式的不同,解除事件也有好幾種方式,推薦始終使用 $(selector).off(event) 的方式解除事件綁定,因為 on/off 正好構成了一個開關。

$('body').off('click') 

  => 可以解除 $.click(func),$.on('click',func) 
     和 $.bind('click',func) 綁定的事件,
     不能解除delegate方式綁定的事件

$('body').unbind('click') => 同上

$('body').undelegate('p','click') => 只能解除 delegate方式綁定的事件

觸發事件

jquery 中,有許多方法根據其參數個數的不同,既可以是賦值,也可以做為取值操作。
事件也不例外,許多時候可以利用這個特性,代替手動去觸發一些事件,以下示例中的兩種方式,都可以實現自動觸發事件。

// (當表單字段未通過驗證時) 自動選中文本值
$('input').select()
$('input').trigger('select')

// 觸發已有的點擊事件
$(selector).click()
$(selector).trigger('click')


// 通過觸發事件,通知select2插件重新渲染
$('select').change()
$('select').trigger('change')

事件委托

事件委托通過事件從目標元素冒泡到根元素的原理實現,它有2個好處,一是大幅降低事件綁定的內存占用,二是可以對后來加入的元素生效。

// 寫法
$(selector).on(event, selector2, func)

// 不推薦的方法
$(selector).delagate(selector2, event, func)

事件委托原理及性能分析詳見 解密jQuery事件核心 - 委托設計(二)

事件操作進階

上面列舉了一些簡單的事件綁定,解綁和委托的使用,下面會說到一些更加個性化的用法。

阻止默認事件

event.preventDefault() 這個方法用於阻止瀏覽器的默認行為,通常用於表單提交或是頁面滾動。

$('form').on('submit',function(event){
      
  // 阻止了默認的表單提交事件,下面可以做一些愛做的事情了
  event.preventDefault();
})

$(document).on('touchmove',function(event){
      
  // 阻止了瀏覽器的默認滾動,也可以做些愛做的事情了
  event.preventDefault();
})

阻止事件傳播

阻止事件傳播即阻止事件繼續向上冒泡。

// 點擊div時,會依次alert 2 ,1
$('body').on('click',function(){alert(1)})

$('div').on('click',function(){alert(2)})

// 下面的代碼只會alert一個 2,因為事件停止冒泡了,不會被body監聽到
$('body').on('click',function(){alert(1)})

$('div').on('click',function(event){
   event.stopPropagation();
   alert(2)
})

阻止事件向后執行

除了阻止默認的事件,停止向上冒泡之外,有時還需要禁止后續的事件執行,可以使用 event.stopImmediatePropagation() 方法。該方法會自動調用 event.stopPropagation() 方法。

// 不使用 event.stopImmediatePropagation() 將會alert 2,3,4,1
// 加上之后只會alert 2
$('body').on('click',function(){alert(1)})

$('div').on('click',function(event){
   event.stopImmediatePropagation();
   alert(2)
})
$('div').on('click',function(){
   alert(3)
})
$('div').on('click',function(){
   alert(4)
})

命名空間

想要更精准的控制事件,很多時候還需要利用 jquery 的命名空間機制。

$('div').on('click.click1',function(){console.log(1)})
$('input').on('click.click1',function(){console.log(11)})

$('div').on('click.click2',function(){console.log(2)})
$('input').on('click.click2',function(){console.log(21)})

// 只觸發click2事件
$('div,input').trigger('.click2')

// 解除click1事件,click2任然會執行
$('div,input').off('.click1')

自定義事件

把多個事件組合起來,或者在特定條件下觸發事件,普通的事件綁定是無法滿足需要的,可以通過自定義事件來形成 pub-sub 組合。
比如監聽 短信驗證碼發送倒計時

// 偽代碼

setInterVal(function(){
  time--;
  if(time < 1){
    $('.js-timeless-button').trigger('time-end', params0, params1);
  }
},1000)

// 自定義事件回調函數默認第一個參數為event對象,以后的參數依次是傳入的參數

 $('.js-timeless-button').on('time-end',function(event, params0, params1){
   
 });

或者是 頁面滾動到了底部

// 偽代碼

$(window).on('scroll',function(){
  if((($(window).scrollTop() + $(window).height())) >= $(document).height()){
    $(document).trigger('infinite', params0, params1);  
  }
})

 $(document).on('infinite',function(event, params0, params1){
   
 });

解除自定義事件和解除其他事件的方式相同。可以通過 off 或者 unbind 進行。

事件隊列

jquery 中,事件是按照其綁定順序依次執行的。如果想要調整執行順序,或是禁止之前綁定的方法發生,可以通過重寫事件隊列的方式。

查看某個dom上已綁定事件的方法是
$._data(elem,'events') (jquery版本>1.7)。

elemdom對象 而非 jquery對象

function alertBottle(){
  $("body").on('click',function() { alert("1") });
  $("body").on('click',function() { alert("2") });
  $("body").on('click',function() { alert("3") });
}

// 點擊body會依次alert 1, 2, 3
alertBottle();

// 倒序執行
alertBottle();

var Events = $._data($("body").get(0),'events');
Events.click.sort(function(a,b){return b.guid-a.guid })   

// 禁止執行之前的一切, 只執行我
alertBottle();

var Events = $._data($("body").get(0),'events');
Events.click = null;
$("body").on('click',function() { alert("4") });

// 最先執行我 alert 4, 1, 2, 3
alertBottle();

$("body").on('click',function() { alert("4") });
var Events = $._data($("body").get(0),'events');
var last = Events.click.pop();
Events.click.unshift(last);

兼容jquery低版本的寫法是:

$.fn.getEvents = function() {
    if (typeof(jQuery._data) == 'function') {
        return jQuery._data(this.get(0), 'events') || {};
    } else if (typeof(this.data) == 'function') { // jQuery version < 1.7.?
        return this.data('events') || {};
    }
    return {};
};

// 使用
$("body").getEvents();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM