事件简介

线上365bet注册 admin 2025-10-07 23:25:55

link 简介网页都是关于交互的。用户执行无数操作,例如将鼠标移到页面上、单击元素和在文本框中输入文本——所有这些都是事件的示例。除了这些用户事件之外,还发生许多其他事件,例如当页面加载时、当视频开始播放或暂停时等。每当页面上发生一些有趣的事情时,就会触发一个事件,这意味着浏览器基本上会宣布某事已发生。正是这个公告允许开发人员“监听”事件并适当地对它们做出反应。

link 什么是 DOM 事件?如前所述,有无数的事件类型,但也许最容易理解的是用户事件,例如当有人单击元素或在表单中输入内容时。这些类型的事件发生在元素上,这意味着当用户单击按钮时,例如,按钮上发生了事件。虽然用户交互并不是 DOM 事件的唯一类型,但它们肯定是最容易理解的,特别是刚开始的时候。Mozilla Developer Network 对可用的 DOM 事件进行了很好的参考。

link 监听事件的方法有很多方法可以监听事件。网页上不断发生操作,但只有当开发人员监听它们时,才会收到它们的通知。监听事件基本上意味着您正在等待浏览器告诉您已发生特定事件,然后您将指定页面应如何做出反应。

要向浏览器指定在事件发生时要做什么,您需要提供一个函数,也称为事件处理程序。每当事件发生(或直到事件解除绑定)时,都会执行此函数。

例如,要每当用户单击按钮时发出警报,你可以写类似这样的内容

1

我们要监听的事件由按钮的onclick属性指定,事件处理程序是alert函数,它向用户发出“Hello”警报。虽然这有效,但由于以下几个原因,这是实现此功能的一种糟糕方法

首先,我们将视图代码(HTML)与交互代码(JS)耦合在一起。这意味着每当我们需要更新功能时,我们都必须编辑 HTML,这是一种不好的做法,也是维护的噩梦。

其次,它不可扩展。如果你必须将此功能附加到多个按钮上,你不仅会用一堆重复的代码使页面臃肿,而且还会再次破坏可维护性。

像这样使用内联事件处理程序可以被认为是侵入式 JavaScript,但它的反面,非侵入式 JavaScript是讨论该主题更常见的方式。非侵入式 JavaScript的概念是你的 HTML 和 JS 是分开的,因此更易于维护。关注点分离很重要,因为它将类似的代码片段(即 HTML、JS、CSS)放在一起,并将不同的代码片段分开,从而方便更改、增强等。此外,非侵入式 JavaScript 强调尽可能减少向页面添加的冗余代码。如果用户的浏览器不支持 JavaScript,那么它不应该与页面的标记交织在一起。此外,为了防止命名冲突,JS 代码应为不同的功能或库使用单个命名空间。jQuery 就是一个很好的例子,因为jQuery对象/构造函数(以及$别名到jQuery)只使用一个全局变量,并且 jQuery 的所有功能都打包到该一个对象中。

为了以非侵入式的方式完成所需的任务,让我们通过删除onclick属性并用一个id替换它来稍微更改我们的 HTML,我们将在脚本文件中使用该id“挂钩”到按钮。

1

如果我们希望在用户以非侵入式方式单击该按钮时收到通知,我们可以在单独的脚本文件中执行类似以下操作

1

2

3

4

5

6

// Event binding using addEventListenervar helloBtn = document.getElementById( "helloBtn" ); helloBtn.addEventListener( "click", function( event ) { alert( "Hello." );}, false );

在这里,我们通过调用 getElementById 并将其返回值分配给变量来保存对按钮元素的引用。然后,我们调用 addEventListener 并提供一个事件处理程序函数,该函数将在该事件发生时被调用。虽然这段代码没有问题,因为它在现代浏览器中可以正常工作,但在 IE9 之前的 IE 版本中却无法正常工作。这是因为 Microsoft 选择实现不同的方法 attachEvent,而不是 W3C 标准 addEventListener,并且直到 IE9 发布后才改变了它。因此,利用 jQuery 是有益的,因为它消除了浏览器的不一致性,允许开发人员使用单个 API 来执行这些类型的任务,如下所示。

1

2

3

4

// Event binding using a convenience method$( "#helloBtn" ).click(function( event ) { alert( "Hello." );});

$( "#helloBtn" ) 代码使用 $(又名 jQuery)函数选择按钮元素并返回 jQuery 对象。jQuery 对象有很多可用的方法(函数),其中一个名为 click,它位于 jQuery 对象的原型中。我们在 jQuery 对象上调用 click 方法并传递一个匿名函数事件处理程序,当用户单击按钮时该处理程序将被执行,向用户发出“Hello”。

可以使用 jQuery 侦听事件的方法有很多

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

// The many ways to bind events with jQuery// Attach an event handler directly to the button using jQuery's// shorthand `click` method.$( "#helloBtn" ).click(function( event ) { alert( "Hello." );}); // Attach an event handler directly to the button using jQuery's// `bind` method, passing it an event string of `click`$( "#helloBtn" ).bind( "click", function( event ) { alert( "Hello." );}); // As of jQuery 1.7, attach an event handler directly to the button// using jQuery's `on` method.$( "#helloBtn" ).on( "click", function( event ) { alert( "Hello." );}); // As of jQuery 1.7, attach an event handler to the `body` element that// is listening for clicks, and will respond whenever *any* button is// clicked on the page.$( "body" ).on({ click: function( event ) { alert( "Hello." ); }}, "button" ); // An alternative to the previous example, using slightly different syntax.$( "body" ).on( "click", "button", function( event ) { alert( "Hello." );});

从 jQuery 1.7 开始,所有事件都通过 on 方法绑定,无论您直接调用它还是使用别名/快捷方式方法(例如 bind 或 click),这些方法在内部都映射到 on 方法。考虑到这一点,使用 on 方法是有益的,因为其他方法都只是语法糖,而使用 on 方法将产生更快、更一致的代码。

让我们看看上面的 on 示例并讨论它们的差异。在第一个示例中,将字符串 click 作为第一个参数传递给 on 方法,并将匿名函数作为第二个参数传递。这看起来很像之前的 bind 方法。在这里,我们将事件处理程序直接附加到 #helloBtn。如果页面上还有其他按钮,当单击这些按钮时,它们不会发出“Hello”提示,因为该事件仅附加到 #helloBtn。

在第二个 on 示例中,我们传递了一个对象(由大括号 {} 表示),它有一个属性 click,其值是一个匿名函数。on 方法的第二个参数是一个 jQuery 选择器字符串 button。虽然示例 1-3 在功能上是等效的,但示例 4 不同,因为 body 元素正在侦听发生在任何按钮元素上的单击事件,而不仅仅是 #helloBtn。上面的最后一个示例与前一个示例完全相同,但我们传递的是一个事件字符串、一个选择器字符串和回调,而不是传递一个对象。这两个示例都是事件委托的示例,事件委托是一个元素在 DOM 树中侦听其子元素上发生的事件的过程。

link 事件委托事件委托之所以有效,是因为事件冒泡的概念。对于大多数事件,每当页面上发生某些事情(例如单击某个元素)时,事件就会从发生事件的元素传播到其父元素,然后传播到父元素的父元素,依此类推,直到到达根元素,即 window。因此,在我们的表格示例中,每当单击 td 时,其父元素 tr 也会收到单击通知,父元素 table 会收到通知,body 会收到通知,最终 window 也会收到通知。虽然事件冒泡和委托运行良好,但委托元素(在我们的示例中,即 table)应始终尽可能靠近被委托元素,以便事件不必在调用其处理程序函数之前在 DOM 树中向上传播很远。

事件委托相对于直接绑定到元素(或一组元素)的两个主要优点是性能和前面提到的事件冒泡。想象一下有一个包含 1000 个单元格的大表格,并为每个单元格绑定一个事件。这是 1000 个单独的事件处理程序,浏览器必须附加这些处理程序,即使它们都映射到同一个函数。但是,我们不必绑定到每个单独的单元格,而是可以使用委托来侦听发生在父表格上的事件并做出相应反应。将绑定一个事件而不是 1000 个事件,从而大大提高性能和内存管理。

发生的事件冒泡使我们能够通过 Ajax 添加单元格,例如,而不必将事件直接绑定到这些单元格,因为父表正在侦听点击并因此收到其子项上的点击通知。如果我们不使用委托,我们将不得不为每个添加的单元格不断绑定事件,这不仅是一个性能问题,而且还可能成为维护噩梦。

链接 事件对象在所有先前的示例中,我们一直在使用匿名函数并在该函数中指定一个 event 参数。让我们稍作更改。

1

2

3

4

5

6

// Binding a named functionfunction sayHello( event ) { alert( "Hello." );} $( "#helloBtn" ).on( "click", sayHello );

在这个稍有不同的示例中,我们正在定义一个名为 sayHello 的函数,然后将该函数传递到 on 方法中,而不是匿名函数。如此多的在线示例显示了用作事件处理程序的匿名函数,但重要的是要认识到,您还可以将已定义的函数作为事件处理程序传递。如果不同的元素或不同的事件应执行相同的功能,这一点很重要。这有助于保持代码 DRY。

但是 sayHello 函数中的 event 参数是什么——它是什么,为什么它很重要?在所有 DOM 事件回调中,jQuery 传递一个 事件对象 参数,其中包含有关事件的信息,例如它发生的准确时间和地点、它是什么类型的事件、事件发生在哪个元素上以及大量其他信息。当然,您不必称它为 event;您可以称它为 e 或您想要的任何名称,但 event 是一个非常常见的惯例。

如果元素具有特定事件的默认功能(例如,链接打开新页面,表单中的按钮提交表单等),则可以取消该默认功能。这通常对 Ajax 请求很有用。当用户单击按钮通过 Ajax 提交表单时,我们希望取消按钮/表单的默认操作(将其提交到表单的 action 属性),而我们改为执行 Ajax 请求以完成同一任务,以获得更无缝的体验。为此,我们将利用事件对象并调用其 .preventDefault() 方法。我们还可以使用 .stopPropagation() 阻止事件在 DOM 树中冒泡,以便父元素不会收到其发生通知(在使用事件委托的情况下)。

1

2

3

4

5

6

7

8

9

10

11

// Preventing a default action from occurring and stopping the event bubbling$( "form" ).on( "submit", function( event ) { // Prevent the form's default submission. event.preventDefault(); // Prevent event from bubbling up DOM tree, prohibiting delegation event.stopPropagation(); // Make an AJAX request to submit the form data});

同时使用 .preventDefault() 和 .stopPropagation() 时,您可以改为 return false 以更简洁的方式实现两者,但建议仅在两者都实际需要时才 return false,而不仅仅是为了简洁。关于 .stopPropagation() 的最后一点说明是,在委托事件中使用它时,最早可以停止事件冒泡的时间是事件到达委托它的元素时。

同样重要的是要注意,事件对象包含一个名为 originalEvent 的属性,它是浏览器本身创建的事件对象。jQuery 用一些有用的方法和属性包装了这个本机事件对象,但在某些情况下,您需要通过 event.originalEvent 访问原始事件。这对于移动设备和平板电脑上的触摸事件特别有用。

最后,要检查事件本身并查看它包含的所有数据,您应该使用 console.log 在浏览器的控制台中记录事件。这将允许您查看事件的所有属性(包括 originalEvent),这对于调试非常有帮助。

1

2

3

4

5

6

7

8

9

10

11

// Logging an event's information$( "form" ).on( "submit", function( event ) { // Prevent the form's default submission. event.preventDefault(); // Log the event object for inspectin' console.log( event ); // Make an AJAX request to submit the form data});