当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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()。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。