當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


JQuery .on()用法及代碼示例


用法
.on( events [, selector ] [, data ], handler ) => jQuery

說明:將一個或多個事件的事件處理函數附加到選定元素。

  • 添加的版本:1.7.on( events [, selector ] [, data ], handler )

    • events
      類型:String
      一種或多種以空格分隔的事件類型和可選的命名空間,例如 "click" 或 "keydown.myPlugin"。
    • selector
      類型:String
      一個選擇器字符串,用於過濾觸發事件的選定元素的後代。如果選擇器為null 或省略,則始終在到達選定元素時觸發事件。
    • data
      類型:Anything
      觸發事件時要傳遞給 event.data 中的處理程序的數據。
    • handler
      類型:Function (Event eventObject [, Anything extraParameter ] [, ... ])
      觸發事件時執行的函數。值 false 也允許作為簡單執行 return false 的函數的簡寫。
  • 添加的版本:1.7.on( events [, selector ] [, data ] )

    • events
      類型:PlainObject
      一個對象,其中字符串鍵表示一個或多個空格分隔的事件類型和可選的命名空間,值表示要為事件調用的處理函數。
    • selector
      類型:String
      一個選擇器字符串,用於過濾將調用處理程序的選定元素的後代。如果選擇器為 null 或省略,則處理程序總是在到達所選元素時被調用。
    • data
      類型:Anything
      發生事件時要傳遞給 event.data 中的處理程序的數據。

.on() 方法將事件處理程序附加到 jQuery 對象中當前選定的元素集。從 jQuery 1.7 開始,.on() 方法提供了附加事件處理程序所需的所有函數。有關從舊 jQuery 事件方法轉換的幫助,請參閱 .bind() .delegate() .live() 。要刪除與 .on() 綁定的事件,請參閱 .off() 。要附加僅運行一次然後自行刪除的事件,請參閱 .one()

事件名稱和命名空間

events 參數可以使用任何事件名稱。 jQuery 將通過瀏覽器的標準 JavaScript 事件類型,當瀏覽器由於用戶操作(例如 click )生成事件時調用 handler 函數。此外, .trigger() 方法可以觸發標準瀏覽器事件名稱和自定義事件名稱來調用附加的處理程序。事件名稱隻能包含字母數字、下劃線和冒號字符。

事件名稱可以由event namespaces 限定,以簡化刪除或觸發事件。例如,"click.myPlugin.simple" 為這個特定的點擊事件定義了 myPlugin 和 simple 命名空間。通過該字符串附加的單擊事件處理程序可以使用.off("click.myPlugin").off("click.simple") 刪除,而不會幹擾附加到元素的其他單擊處理程序。命名空間類似於 CSS 類,因為它們不是分層的;隻有一個名字需要匹配。命名空間應僅包含大寫/小寫字母和數字。

.on() 的第二種形式中,events 參數是一個普通對象。鍵是與 events 參數形式相同的字符串,帶有空格分隔的事件類型名稱和可選的命名空間。每個鍵的值是一個函數(或 false 值),用作 handler 而不是方法的最終參數。在其他方麵,這兩種形式的行為相同,如下所述。

直接和委托事件處理程序

大多數瀏覽器事件bubble, 或者propagate,從最深、最裏麵的元素(事件目標) 在文檔中它們一直出現到正文和document元素。在 Internet Explorer 8 及更低版本中,一些事件,例如changesubmit不要原生冒泡,但 jQuery 修補這些冒泡並創建一致的跨瀏覽器行為。

如果 selector 被省略或為空,則事件處理程序稱為 directdirectly-bound 。每次在選定元素上發生事件時都會調用處理程序,無論它是直接發生在元素上還是來自後代(內部)元素的冒泡。

當提供 selector 時,事件處理程序稱為 delegated 。當事件直接發生在綁定元素上時,不會調用處理程序,而隻會調用與選擇器匹配的後代(內部元素)。 jQuery 將事件從事件目標冒泡到附加處理程序的元素(即從最裏麵到最外麵的元素),並為沿著該路徑匹配選擇器的任何元素運行處理程序。

事件處理程序僅綁定到當前選定的元素;它們必須在您的代碼調用 .on() 時存在。為了確保元素存在並且可以被選擇,請將腳本放置在 HTML 標記中的元素之後,或者在文檔就緒處理程序中執行事件綁定。或者,使用委托的事件處理程序來附加事件處理程序。

委托事件處理程序具有他們可以處理來自的事件的優勢descendant elements稍後添加到文檔中。通過選擇在附加委托事件處理程序時保證存在的元素,您可以使用委托事件處理程序來避免頻繁附加和刪除事件處理程序的需要。例如,此元素可以是Model-View-Controller 設計中視圖的容器元素,或者document如果事件處理程序想要監視文檔中的所有冒泡事件。這document元素在head在加載任何其他 HTML 之前刪除文檔,因此在此處附加事件是安全的,而無需等待文檔準備好。

除了能夠處理尚未創建的後代元素上的事件之外,委托事件處理程序的另一個優點是當必須監視許多元素時,它們的開銷可能會大大降低。在 tbody 中有 1,000 行的數據表上,此示例將處理程序附加到 1,000 個元素:

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

event-delegation 方法僅將事件處理程序附加到一個元素,即 tbody,並且事件隻需要冒泡一個級別(從單擊的 trtbody ):

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

注意:委托事件處理程序不適用於 SVG。

事件處理程序及其環境

handler 參數是一個函數(或值 false ,見下文),除非您為 events 參數傳遞對象,否則它是必需的。您可以在 .on() 調用時提供一個匿名處理函數,就像上麵的示例所做的那樣,或者聲明一個命名函數並傳遞其名稱:

function notify() {
  alert( "clicked" );
}
$( "button" ).on( "click", notify );

當瀏覽器觸發事件或其他 JavaScript 調用 jQuery 的 .trigger() 方法時,jQuery 會向處理程序傳遞一個 Event 對象,它可以用來分析和更改事件的狀態。這個對象是瀏覽器提供的一個normalized subset數據; event.originalEvent 中提供了瀏覽器未修改的本機事件對象。例如, event.type 包含事件名稱(例如,"resize"), event.target 表示事件發生的最深(最裏麵)元素。

默認情況下,大多數事件從原始事件目標冒泡到document 元素。在此過程中的每個元素處,jQuery 都會調用任何已附加的匹配事件處理程序。處理程序可以通過調用 event.stopPropagation() 來防止事件在文檔樹上進一步冒泡(從而防止這些元素上的處理程序運行)。但是,附加在當前元素 will 上的任何其他處理程序都會運行。為防止這種情況,請調用 event.stopImmediatePropagation() 。 (綁定到元素的事件處理程序的調用順序與它們綁定的順序相同。)

類似地,處理程序可以調用event.preventDefault() 來取消瀏覽器可能對此事件執行的任何默認操作;例如,click 事件的默認操作是跟隨鏈接。並非所有瀏覽器事件都有默認操作,也不是所有默認操作都可以取消。有關詳細信息,請參閱W3C Events Specification

從事件處理程序返回 false 將自動調用 event.stopPropagation()event.preventDefault() 。也可以為 handler 傳遞 false 值作為 function(){ return false; } 的簡寫。因此,$( "a.disabled" ).on( "click", false ); 將事件處理程序附加到具有類 "disabled" 的所有鏈接,以防止在單擊它們時跟蹤它們並阻止事件冒泡。

當 jQuery 調用處理程序時,this 關鍵字是對傳遞事件的元素的引用;對於直接綁定事件,這是附加事件的元素,對於委托事件,這是匹配 selector 的元素。 (請注意,如果事件從後代元素冒泡,則 this 可能不等於 event.target。)要從元素創建 jQuery 對象以便它可以與 jQuery 方法一起使用,請使用 $( this )

將數據傳遞給處理程序

如果 data 參數提供給 .on() 並且不是 nullundefined ,則每次觸發事件時,它都會傳遞給 event.data 屬性中的處理程序。 data 參數可以是任何類型,但如果使用字符串,則必須提供 selector 或作為 null 顯式傳遞,以免數據被誤認為是選擇器。最佳實踐是使用普通對象,以便可以將多個值作為屬性傳遞。

從 jQuery 1.4 開始,同一個事件處理程序可以多次綁定到一個元素。這在使用event.data 函數或其他唯一數據駐留在事件處理函數周圍的閉包中時特別有用。例如:

function greet( event ) {
  alert( "Hello " + event.data.name );
}
$( "button" ).on( "click", {
  name: "Karl"
}, greet );
$( "button" ).on( "click", {
  name: "Addy"
}, greet );

當點擊按鈕時,上麵的代碼會產生兩個不同的警報。

作為提供給 .on() 方法的 data 參數的替代或補充,您還可以使用 .trigger() .triggerHandler() 的第二個參數將數據傳遞給事件處理程序。以這種方式提供的數據將作為 Event 對象之後的其他參數傳遞給事件處理程序。如果將數組傳遞給 .trigger().triggerHandler() 的第二個參數,則數組中的每個元素都將作為單獨的參數呈現給事件處理程序。

活動表現

在大多數情況下,諸如click 之類的事件很少發生,性能並不是一個重要問題。但是,諸如mousemovescroll 之類的高頻事件每秒可以觸發數十次,在這些情況下,明智地使用事件變得更加重要。性能可以通過減少處理程序本身完成的工作量、緩存處理程序所需的信息而不是重新計算它或通過 rate-limiting 使用 setTimeout 的實際頁麵更新次數來提高。

在文檔樹頂部附近附加許多委托事件處理程序會降低性能。每次事件發生時,jQuery 必須將該類型的所有附加事件的所有選擇器與從事件目標到文檔頂部的路徑中的每個元素進行比較。為了獲得最佳性能,請將委托事件附加到盡可能靠近目標元素的文檔位置。避免過度使用documentdocument.body 來處理大型文檔上的委派事件。

當用於過濾委托事件時,jQuery 可以非常快速地處理 tag#id.class 形式的簡單選擇器。因此,"#myForm""a.external""button" 都是快速選擇器。使用更複雜選擇器(尤其是分層選擇器)的委托事件可能會慢幾倍——盡管對於大多數應用程序來說它們仍然足夠快。通常可以通過將處理程序附加到文檔中更合適的點來避免分層選擇器。例如,而不是 $( "body" ).on( "click", "#commentForm .addNew", addComment ) 使用 $( "#commentForm" ).on( "click", ".addNew", addComment )

補充筆記

有一些事件的速記方法,例如 .click() ,可用於附加或觸發事件處理程序。有關速記方法的完整列表,請參閱events category

Deprecated in jQuery 1.8, removed in 1.9: 名稱 "hover" 用作字符串 "mouseenter mouseleave" 的簡寫。它為這兩個事件附加了 single event handler,處理程序必須檢查 event.type 以確定事件是 mouseenter 還是 mouseleave 。不要將 "hover" pseudo-event-name 與接受 one or two 函數的 .hover() 方法混淆。

jQuery 的事件係統要求 DOM 元素允許通過元素上的屬性附加數據,以便可以跟蹤和傳遞事件。 objectembedapplet 元素不能附加數據,因此不能將 jQuery 事件綁定到它們。

focusblur 事件由 W3C 指定為不冒泡,但 jQuery 定義了跨瀏覽器的 focusinfocusout 事件會冒泡。當focusblur 用於附加委托事件處理程序時,jQuery 映射名稱並將它們分別作為focusinfocusout 傳遞。為了一致性和清晰性,使用冒泡事件類型名稱。

在所有瀏覽器中,loadscrollerror 事件(例如,在 <img> 元素上)不會冒泡。在 Internet Explorer 8 及更低版本中,pastereset 事件不會冒泡。此類事件不支持與委托一起使用,但它們 can 在事件處理程序直接附加到生成事件的元素時使用。

window 對象上的 error 事件使用非標準參數和返回值約定,因此 jQuery 不支持它。相反,將處理函數直接分配給window.onerror 屬性。

元素的處理程序列表在第一次傳遞事件時設置。在下一次處理事件之前,在當前元素上添加或刪除事件處理程序不會生效。要防止任何進一步的事件處理程序在事件處理程序內的元素上執行,請調用 event.stopImmediatePropagation() 。此行為違反 W3C events specification 。為了更好地理解這種情況,請考慮以下代碼:

var $test = $( "#test" );
 
function handler1() {
  console.log( "handler1" );
  $test.off( "click", handler2 );
}
 
function handler2() {
  console.log( "handler2" );
}
 
$test.on( "click", handler1 );
$test.on( "click", handler2 );

在上麵的代碼中,handler2 無論如何都會在第一次執行,即使它是使用 .off() 刪除的。但是,在觸發 click 事件之後,將不會執行處理程序。

例子:

單擊時在警報中顯示段落的文本:

$( "p" ).on( "click", function() {
  alert( $( this ).text() );
});

將數據傳遞給事件處理程序,這裏按名稱指定:

function myHandler( event ) {
  alert( event.data.foo );
}
$( "p" ).on( "click", { foo: "bar" }, myHandler );

通過返回 false 取消表單提交操作並防止事件冒泡:

$( "form" ).on( "submit", false );

使用 .preventDefault() 僅取消默認操作。

$( "form" ).on( "submit", function( event ) {
  event.preventDefault();
});

使用 .stopPropagation() 在不阻止表單提交的情況下阻止提交事件冒泡。

$( "form" ).on( "submit", function( event ) {
  event.stopPropagation();
});

使用 .trigger() 的第二個參數將數據傳遞給事件處理程序

$( "div" ).on( "click", function( event, person ) {
  alert( "Hello, " + person.name );
});
$( "div" ).trigger( "click", { name: "Jim" } );

使用 .trigger() 的第二個參數將數據數組傳遞給事件處理程序

$( "div" ).on( "click", function( event, salutation, name ) {
  alert( salutation + ", " + name );
});
$( "div" ).trigger( "click", [ "Goodbye", "Jim" ] );

附加並觸發自定義(非瀏覽器)事件。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>on demo</title>
  <style>
  p {
    color: red;
  }
  span {
    color: blue;
  }
  </style>
  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
</head>
<body>
 
<p>Has an attached custom event.</p>
<button>Trigger custom event</button>
<span style="display:none;"></span>
 
<script>
$( "p" ).on( "myCustomEvent", function( event, myName ) {
  $( this ).text( myName + ", hi there!" );
  $( "span" )
    .stop()
    .css( "opacity", 1 )
    .text( "myName = " + myName )
    .fadeIn( 30 )
    .fadeOut( 1000 );
});
$( "button" ).click(function () {
  $( "p" ).trigger( "myCustomEvent", [ "John" ] );
});
</script>
 
</body>
</html>

演示:

使用普通對象同時附加多個事件處理程序。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>on demo</title>
  <style>
  .test {
    color: #000;
    padding: .5em;
    border: 1px solid #444;
  }
  .active {
    color: #900;
  }
  .inside {
    background-color: aqua;
  }
  </style>
  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
</head>
<body>
 
<div class="test">test div</div>
 
<script>
$( "div.test" ).on({
  click: function() {
    $( this ).toggleClass( "active" );
  }, mouseenter: function() {
    $( this ).addClass( "inside" );
  }, mouseleave: function() {
    $( this ).removeClass( "inside" );
  }
});
</script>
 
</body>
</html>

演示:

單擊任何段落以在其後添加另一個段落。請注意,.on() 允許在任何段落(甚至是新段落)上單擊事件,因為該事件在冒泡到那裏後由 ever-present 正文元素處理。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>on demo</title>
  <style>
  p {
    background: yellow;
    font-weight: bold;
    cursor: pointer;
    padding: 5px;
  }
  p.over {
    background: #ccc;
  }
  span {
    color: red;
  }
  </style>
  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
</head>
<body>
 
<p>Click me!</p>
<span></span>
 
<script>
var count = 0;
$( "body" ).on( "click", "p", function() {
  $( this ).after( "<p>Another paragraph! " + (++count) + "</p>" );
});
</script>
 
</body>
</html>

演示:

每次單擊時都會在警告框中顯示每個段落的文本:

$( "body" ).on( "click", "p", function() {
  alert( $( this ).text() );
});

使用 .preventDefault() 方法取消鏈接的默認操作:

$( "body" ).on( "click", "a", function( event ) {
  event.preventDefault();
});

將多個事件(一個在 mouseenter 上,一個在 mouseleave 上)附加到同一元素:

$( "#cart" ).on( "mouseenter mouseleave", function( event ) {
  $( this ).toggleClass( "active" );
});

相關用法


注:本文由純淨天空篩選整理自jquery.com大神的英文原創作品 .on()。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。