@@ -15,7 +15,8 @@ slug: Web/API/EventTarget/addEventListener
15
15
16
16
` addEventListener() ` 的工作原理是将实现 {{domxref("EventListener")}} 的函数或对象添加到调用它的 {{domxref("EventTarget")}} 上的指定事件类型的事件侦听器列表中。如果要绑定的函数或对象已经被添加到列表中,该函数或对象不会被再次添加。
17
17
18
- > ** 备注:** 如果先前向事件侦听器列表中添加过一个匿名函数,并且在之后的代码中调用 ` addEventListener ` 来添加一个功能完全相同的匿名函数,那么之后的这个匿名函数* 也会* 被添加到列表中。
18
+ > [ !NOTE]
19
+ > 如果先前向事件侦听器列表中添加过一个匿名函数,并且在之后的代码中调用 ` addEventListener ` 来添加一个功能完全相同的匿名函数,那么之后的这个匿名函数* 也会* 被添加到列表中。
19
20
>
20
21
> 实际上,即使使用* 完全相同* 的代码来定义一个匿名函数,这两个函数仍然存在区别,** 在循环中也是如此** 。在使用该方法的情况下,匿名函数的重复定义会带来许多麻烦,详见下文中的[ 内存问题] ( #内存问题 ) 一节。
21
22
@@ -52,7 +53,8 @@ addEventListener(type, listener, useCapture);
52
53
53
54
- : 一个布尔值,表示在 DOM 树中注册了 ` listener ` 的元素,是否要先于它下面的 ` EventTarget ` 调用该 ` listener ` 。当 useCapture(设为 true)时,沿着 DOM 树向上冒泡的事件不会触发 listener。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。进一步的解释可以查看 [ DOM Level 3 事件] ( https://www.w3.org/TR/DOM-Level-3-Events/#event-flow ) 及 [ JavaScript 事件顺序] ( https://www.quirksmode.org/js/events_order.html#link4 ) 文档。如果没有指定,` useCapture ` 默认为 ` false ` 。
54
55
55
- > ** 备注:** 对于事件目标上的事件监听器来说,事件会处于“目标阶段”,而不是冒泡阶段或者捕获阶段。捕获阶段的事件监听器会在任何非捕获阶段的事件监听器之前被调用。
56
+ > [ !NOTE]
57
+ > 对于事件目标上的事件监听器来说,事件会处于“目标阶段”,而不是冒泡阶段或者捕获阶段。捕获阶段的事件监听器会在任何非捕获阶段的事件监听器之前被调用。
56
58
57
59
- ` wantsUntrusted ` {{optional_inline}} {{Non-standard_inline}}
58
60
- : 如果为 ` true ` ,则事件处理程序会接收网页自定义的事件。此参数只适用于 Gecko({{glossary("chrome")}} 的默认值为 ` false ` ,其他常规网页的默认值为 ` true ` ),主要用于附加组件的代码和浏览器本身。
@@ -639,13 +641,15 @@ myButton.addEventListener("click", () => {
639
641
console .log (someString); // 预期输出:'Data'(不可能是 'Data Again')
640
642
```
641
643
642
- > ** 备注:** 虽然内部作用域可以访问到外部 ` const ` 和 ` let ` 所声明的变量,但你在事件监听器内对变量所做的任何修改都不能在外部作用域内体现。为什么呢?因为在事件监听器被执行时,其外部作用域已经执行完毕了。
644
+ > [ !NOTE]
645
+ > 虽然内部作用域可以访问到外部 ` const ` 和 ` let ` 所声明的变量,但你在事件监听器内对变量所做的任何修改都不能在外部作用域内体现。为什么呢?因为在事件监听器被执行时,其外部作用域已经执行完毕了。
643
646
644
647
#### 使用对象进行数据交换
645
648
646
649
与 JavaScript 中的大部分函数不同,一个对象只要有被引用计数,它就会一直存在于内存之中。并且,对象可以拥有自己的属性,属性又可以被引用形式传递,使得它有潜力成为在作用域间传值的候选。让我们来试试。
647
650
648
- > ** 备注:** 实际上,在 JavaScript 中,函数也是对象的一种。(因此,函数也可以有自己的对象,甚至可以在其执行结束后依旧存在于内存中,只要将其分配到一个永久存在于内存中的变量即可。)
651
+ > [ !NOTE]
652
+ > 实际上,在 JavaScript 中,函数也是对象的一种。(因此,函数也可以有自己的对象,甚至可以在其执行结束后依旧存在于内存中,只要将其分配到一个永久存在于内存中的变量即可。)
649
653
650
654
因为只需一个变量引用就可以使对象的属性将数据存储在内存之中,你可以使用它与事件监听器进行数据交换,并且更改后的数据会被保留。请看下面这个例子:
651
655
@@ -669,9 +673,11 @@ setInterval(() => {
669
673
670
674
在这一例子中,虽然事件监听器和定时函数的作用域都在 ` someObject.aProperty ` 的值变更前执行完毕,但 ` someObject ` 仍被事件监听器和定时函数所* 引用* 而存在于内存中,这两个函数依然能访问到同样的数据(也就是说,当其中一方改变了数据,另一方可以对这一改变做出响应)。
671
675
672
- > ** 备注:** 对象的是以引用方式存储于变量中的,也即变量中存储的只是对象的内存地址而已。在其他方面上,这也意味着“存储”这个对象的变量可以对其他引用(或“存储”)同一个对象的变量产生影响。当两个变量引用同一对象时(比如 ` let a = b = {aProperty: 'Yeah'}; ` ),仅对其中一个变量进行更改仍然会影响到另一个变量。
676
+ > [ !NOTE]
677
+ > 对象的是以引用方式存储于变量中的,也即变量中存储的只是对象的内存地址而已。在其他方面上,这也意味着“存储”这个对象的变量可以对其他引用(或“存储”)同一个对象的变量产生影响。当两个变量引用同一对象时(比如 ` let a = b = {aProperty: 'Yeah'}; ` ),仅对其中一个变量进行更改仍然会影响到另一个变量。
673
678
674
- > ** 备注:** 基于对象存储于变量中的“引用”逻辑,你可以在一个函数执行完毕后返回一个对象以使其“保活”(使其保留在内存中且不丢失数据)。
679
+ > [ !NOTE]
680
+ > 基于对象存储于变量中的“引用”逻辑,你可以在一个函数执行完毕后返回一个对象以使其“保活”(使其保留在内存中且不丢失数据)。
675
681
676
682
### 内存问题
677
683
@@ -737,7 +743,8 @@ window.addEventListener(
737
743
738
744
为了避免这一问题,大部分浏览器(Safari 和 Internet Explorer 除外)将文档级节点 {{domxref("Window")}}、{{domxref("Document")}} 和 {{domxref("Document.body")}} 上的 {{domxref("Element/wheel_event", "wheel")}}、{{domxref("Element/mousewheel_event", "mousewheel")}}、{{domxref("Element/touchstart_event", "touchstart")}} 和 {{domxref("Element/touchmove_event", "touchmove")}} 事件的 ` passive ` 默认值更改为 ` true ` 。如此,事件监听器便不能[ 取消事件] ( /zh-CN/docs/Web/API/Event/preventDefault ) ,也不会在用户滚动页面时阻止页面呈现。
739
745
740
- > ** 备注:** 若你想要了解哪些浏览器(或特定浏览器的哪一个版本)具体实现了上述功能,请参见下方的浏览器兼容性表。
746
+ > [ !NOTE]
747
+ > 若你想要了解哪些浏览器(或特定浏览器的哪一个版本)具体实现了上述功能,请参见下方的浏览器兼容性表。
741
748
742
749
因此,当你想要覆盖这一行为并确认 ` passive ` 在所有浏览器中都被设为 ` false ` ,你必须显式地将其设为 ` false ` ,而不是依赖浏览器的默认设置。
743
750
0 commit comments