您好,登錄后才能下訂單哦!
事件是 Web 應用中不可或缺的一個東西,用戶在應用中執行一個操作的時候,比如鼠標單擊時要觸發執行一些事情,就可以給該事件綁定一個事件處理程序(event handler)。使用 jQuery 的 .on() 方法可以為選中的元素綁定任意的 DOM 事件,并添加事件處理程序。假設有如下 HTML 結構:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> <button id="example" type="button">Click me!</button> <script src="http://code.jquery.com/jquery-1.11.2.js"></script> <script> // code here </script> </body> </html>
在 <script> 元素內添加如下代碼,其中,事件名稱是 .on() 方法的第一個參數,事件處理程序的回調函數作為第二個參數:
$('#example').on('click', function(e) { alert('Clicked!'); });
這樣當該按鈕元素觸發鼠標單擊(click)事件的時候就會執行綁定的事件處理程序,彈出一個對話框!回調函數的第一個參數 e 為事件對象,通過該對象可以得到很多事件相關的信息,比如事件類型,事件發生的坐標點等以及一些事件方法。回調函數除了可以像這樣使用一個匿名函數,也可以使用一個變量標識的函數引用:
$('#example').on('click', clickHandler);
同時綁定多個事件
另外,jQuery 還支持使用空格分隔多個事件名稱來同時綁定多個事件,比如 mouseenter mouseleave,同時給元素綁定鼠標移入和鼠標移出事件。可以通過事件對象的 type 屬性來判斷發生的是哪個事件:
$('#example').on('mouseenter mouseleave', function(e) { if (e.type === 'mouseenter') { // mouseenter } else { // mouseleave } });
除了上面這種方法外,還可以傳入一個鍵值對來綁定多個事件:
$('#example').on({ mouseleave: function() { // mouseleave }, mouseenter: function() { // mouseenter } });
事件上下文
同時給多個元素綁定事件處理程序的時候可以使用事件執行的上下文來簡化代碼:
$('li').on('click', function() { var $this = $(this); $this.addClass('active'); });
上下文關鍵字 this 引用的是原生 DOM 元素,所以如果要使用 jQuery 的方法需要先包裝成 jQuery 對象。
事件委托
事件會經過一個捕捉和冒泡的過程,為了兼容,jQuery 只使用了事件的冒泡,即目標元素觸發事件后會逐級冒泡直到頂級元素節點。利用事件的冒泡可以將目標元素的事件處理程序綁定到其祖先元素上統一處理,可以給 .on() 方法傳入一個可選的選擇器字符串作為第二個參數:
$(document).on('click', '#example', clickHandler);
此時表示將 id="example" 的元素的鼠標單擊事件委托綁定到了 document 元素上,當目標元素(即 id="example" 的元素)觸發鼠標單擊事件的時候,該事件就會冒泡到 document 元素上,從而觸發事件處理程序。使用事件委托的好處是如果頁面上有很多列表,每個列表都去綁定一個鼠標單擊事件,那么就會有很多事件處理程序,會對性能造成影響。利用事件冒泡的原則,將事件處理程序綁定到目標元素的父元素或者祖先元素上,可以明顯地減少事件處理程序的數量,改善性能:
$('ul').on('click', 'li', clickHandler);
使用事件委托另外一個好處是那些動態添加的 <li> 元素也會具有事件處理程序。個人比較侵向于將事件都委托到 document 元素上方便管理,而且也不用等到 DOM 準備就緒:
$(document) .on('click', 'selector-1', clickHandler) .on('focusin', 'selector-2', focusHandler);
在 IE8 中一些事件比如 submit 或者 change 是不會冒泡的,但是 jQuery 對此做了處理,因此也可以放心使用。像 focus 和 blur 事件則推薦使用相應的 focusin 和 focusout 事件來代替。對于 mouseover 和 mouseout 事件,為了避免事件冒泡造成的不良影響,推薦使用 mouseenter 和 mouseleave 來代替。
阻止事件冒泡與默認行為
調用事件對象的 .stopPropagation() 方法可以阻止事件冒泡:
$('#example').on('click', function(e) { e.stopPropagation(); });
這樣當單擊事件在該元素上發生的時候就不會冒泡了。jQuery 還有另外一個方法 .stopImmediatePropagation() 調用后事件冒泡被阻止同時該元素上后面綁定的事件處理程序也不會執行了:
$('#example').on('click', function() { alert('Clicked-1!'); // 會執行 }).on('click', function(e) { e.stopImmediatePropagation(); }).on('click', function() { alert('Clicked-2!'); // 不會執行 });
調用事件對象的 .preventDefault() 方法可以阻止事件的默認行為:
$('#example').on('click', function(e) { e.preventDefault(); });
在事件處理程序中直接返回 false 可以同時取消冒泡和阻止默認行為:
$('#example').on('click', function() { return false; });
相當于同時調用了事件對象上面的 .stopPropagation() 和 .preventDefault() 方法。如果沒有其它操作,還可以進一步簡寫為 $('#example').on('click', false);。
應用示例,點擊按鈕顯示彈出層,點擊文檔其它地方隱藏:
$(document) .on('click', '#example', popup.show) .on('click', popup.hide);
由于事件冒泡,所以該彈出層并不會顯示出來,需要在事件處理程序中阻止事件冒泡:
$(document) .on('click', '#example', function(e) { e.stopPropagation(); popup.show(); }).on('click', popup.hide);
獲取原生事件對象
事件處理程序中引用的事件對象實際上是經過 jQuery 包裝過的,有時候需要使用瀏覽器原生的事件對象,要得到瀏覽器原生的事件對象可以通過事件對象的 originalEvent 屬性獲取。例如,使用拖拽事件的時候就會用到原生的事件對象:
$('#example').on('dragstart', function(e) { var originalEvent = e.originalEvent; originalEvent.dataTransfer.effectAllowed = 'move'; originalEvent.dataTransfer.setData('text/plain', $(this).text()); originalEvent.dataTransfer.setData('text/html', $(this).html()); originalEvent.dataTransfer.setDragImage('/images/drag.png', -10, -10); });
傳遞數據
可以給事件處理程序傳入數據,該數據保存在事件對象的 data 屬性中:
$('#example').on('click', 1, function(e) { console.log(e.data); // 1 });
為了區別事件代理,傳遞的數據貌似不能是一個直接的字符串,不過可以傳入一個對象來代替:
$('#example').on('click', {str: 'xxx'}, function(e) { console.log(e.data.str); // xxx });
自定義事件
除了瀏覽器的標準事件,還可以綁定自定義事件的事件處理程序,其中事件名可以使用任意命名:
$('#example').on('sleep', function() { alert('Sleeping!'); });
標準事件的事件處理程序可以通過瀏覽器原生事件去觸發,而自定義事件的事件處理程序則可以使用 jQuery 的 .trigger() 方法觸發,使用方式如下,傳入需要觸發的事件名稱作為參數:
$('#example').trigger('sleep');
可以通過給 trigger() 方法傳入更多參數來給事件處理程序傳遞數據,數據會作為回調函數的參數進行傳遞:
$('#example').on('sleep', function(e, time) { alert('Sleep at' + time); }); $('#example').trigger('sleep', '22:00');
應用示例,使用自定義事件編寫異步代碼:
$('#example').on('done', doHandler); function foo() { setTimeout(function() { // foo 函數的邏輯比較耗時,所以使用 setTimeout 函數排隊 $('#example').trigger('done'); // 執行完了,通知一聲 }, 1000); }
foo 函數執行完成后,就會觸發元素的 done 事件,前面綁定的 doHandler 函數就會開始執行。
事件命名空間
無論是瀏覽器標準事件或是自定義事件都可以添加命名空間,添加在事件名稱后面,通過一個 . 號分隔,像這樣 click.widget,也可以給一個事件添加多個命名空間 click.widget.common,使用命名空間可以更有針對性地觸發或者移除某個特定的事件處理程序。比如一個元素同時綁定了 click.tab 和 click.collapse 兩個點擊事件,當使用 .trigger() 方法觸發 click.collapse 事件時會執行該事件的事件處理程序,而 click.tab 的事件處理程序則不會執行。
移除綁定事件
使用 .off() 方法可以移除綁定的事件處理程序,有下面幾種情況:
一次性事件
使用 .one() 方法綁定的事件處理程序只會觸發執行一次,一次后自動移除:
$('#example').one('click', clickHandler);
事件節流
瀏覽器中有幾個事件會頻繁觸發,比如 scroll, resize, mousemove 等,那么給這些事件綁定的事件處理程序也會跟著頻繁地執行,導致頁面反應遲鈍,要解決這個問題,需要節流事件,減少事件處理程序執行的頻率:
var timer = 0; // 使用一個定時器 $(window).on('scroll', function() { if (!timer) { timer = setTimeout(function() { // Do something timer = 0; }, 200); } });
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持億速云!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。