《JS原理、方法与实践》- DOM事件

简介: 《JS原理、方法与实践》- DOM事件

事件就是用来完成“当...时做...”的功能,也就是起监听作用。事件给我们提供了一个跟文档对象进行沟通的接口。

事件主要由三部分组成:事件的目标(EventTarget)、事件监听器(EventListener)和事件本身(Event)。事件的目标可以理解为事件的主人,也就是谁的事件,在DOM中就是各种Node节点;DOM中的事件监听器可以理解为处理事件的函数;事件就是当事件目标(EventTarget)上特定的事件发生之后发送给事件监听器的信息。

#### 事件流

Events子标准中规定事件的传递首先从最外层节点(Document)开始,然后逐层向内部传播,一直传到最内层节点之后再逐层往外返回。整个传播流程可以 分为两个过程和三个阶段:

###### 两个过程分别叫做:捕获过程和冒泡过程

捕获过程时从外向内传播的过程,冒泡过程则是从内向外的过程

###### 三个阶段分别叫做: 捕获阶段,目标阶段和冒泡阶段

捕获阶段和冒泡阶段分别对应的时捕获过程和冒泡过程,目标阶段指的时事件传递到最内层节点时的阶段。

###### DOM标准中默认的事件处理是在冒泡过程中进行的!

![](https://upload-images.jianshu.io/upload_images/2789632-236aa4d7d2286131.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#### EventTarget

EventTarget指事件的目标(主人),即各种不同的节点,DOM中的节点都可以用作EventTarget。EventTarget中共有三个方法属性,如下所示。

* addEventListener(type, listener, capture): 给节点添加监听器,即事件处理程序

* removeEventListener(type, listener, capture): 删除节点相应的监听器

* dispatchEvent(event): 发布事件

其中,type指的是要监听的事件类型,listener就是要添加或删除的事件监听器EventListener,一般包含一个event参数的处理方法,capture为布尔类型,表示是否使用捕获过程,默认值为false。

代码示例:

```

<body style="width: 100%; height: 888px">

   <script>

       const body = document.querySelector('body');

       // 设置capture 为true, 则先执行window的监听事件,再执行body的监听事件

       window.addEventListener('click', function(){console.log('window click!')}, true);

       body.addEventListener('click', function(){console.log('body click!')});

   </script>

</body>

```

![测试结果](https://upload-images.jianshu.io/upload_images/2789632-ffab6b099ea484a1.gif?imageMogr2/auto-orient/strip)

#### EventListener

EventListener是事件监听器接口,用于对接到的事件具体执行处理。其中只有一个方法handleEvent(event)用于具体处理事件。EventListener接口在实际使用中就是一个包含Event参数的方法。

#### Event

Event是事件接口,用来包含事件中的信息,例如事件所在的事件目标、事件类型。如果是单及事件,那么还会包含鼠标单击时的坐标信息等,事件监听器函数在处理事件时都会接收到一个Event参数。

Event是总的事件接口,DOM2中共有4种具体的事件类型,分别是UIEvents、MouseEvents、MutationEvents和HTMLEvents。可以使用DOMImplementation的hasFeature方法来判断浏览器是否支持某种类型事件,调用时第一个参数传入要检查的事件类型,第二个参数传入2.0就可以了。

![事件类型的继承关系](https://upload-images.jianshu.io/upload_images/2789632-666994258d9c75de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### Event接口

Event接口时所有事件类型的总接口,因此Event中的属性在所有的事件中都可以使用。Event包含7个只读属性、3个方法属性和3个常量属性:

* type: 事件类型,例如click、load等

* target: 事件目标,即直接发出事件的节点

* currentTarget: 当前目标,指的是在捕获或者冒泡过程中处理事件时的当前节点

* eventPhase: 事件所处的阶段

* cancelable: 事件是否可以被取消

* timeStamp: 事件创建事件

* stopPropagation(): 停止事件流传播

* preventDefault(): 阻止默认操作,例如,submit事件提交表单、a标签的click事件打开链接等

* initEvent(type, canBubble, cancelable): 初始化属性

* CAPTURE_PHASE = 1: 捕获阶段

* AT_TARGET = 2: 目标阶段

* BUBBLING_PHASE=3:冒泡阶段

其中,最后三个属性为常量属性,用于表示eventPhase属性的接口。

Event中的stopPropagation方法用来停止事件流的传播,无论在哪个阶段,只要在事件处理方法中调用了事件的stopPropagation方法事件流,就不再接着向下传播了。

Event中的preventDefault方法用来阻止当前节点执行默认操作,但它并不会终止事件流传播,当事件的cancelbale为false时,preventDefault方法将不起作用。

###### UIEvents事件

UIEvents事件对应UIEvents接口。UIEvents继承自Event接口,在Event接口的基础上增加了两个只读属性和一个方法属性。只读属性时view和detail,分别表示视图和详细信息,view为Views子标准中的AbstractView类型,在浏览器中一般就是window对象;detail为整数类型,表示事件的相关信息,所表示的内容跟具体事件相关。新增的方法为initEvent, 它在原来的initEvent方法上添加了两个自己的属性,它的作用是新建UIEvent类型的事件,调用语法如下:

```

event.initEvent(type, canBubble, cancelable, view, detail);

```

![UIEvents事件的三种类型](https://upload-images.jianshu.io/upload_images/2789632-0e8523960a4a2e22.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

表中是否可冒泡和是否可取消分别对应canBubble和cancelable两个属性。

###### MouseEvents事件

MouseEvents事件对应MouseEvents接口。MouseEvent继承自UIEvent接口,它在UIEvent的基础上新增加了10个只读属性和一个方法属性。

![](https://upload-images.jianshu.io/upload_images/2789632-5a09dd093aba3877.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 10个只读属性如下:

* screenX: 单击位置以屏幕左上角为原点的横坐标

* screenY: 单击位置以屏幕左上角为原点的纵坐标

* clientX: 单击位置以浏览器内容区域左上角为原点的横坐标

* clientY: 单击位置以浏览器内如区域左上角为原点的纵坐标

* ctrlKey: 布尔类型,表示点击鼠标时是否按了Ctrl键

* shiftKey: 布尔类型,表示单击鼠标时是否按了Shift键

* altKey: 布尔类型,表示单击鼠标时是否按了Alt键

* metaKey: 布尔类型,表示单击鼠标时是否按了Meta键,Meta键在普通的键盘上是没有的

* button: 鼠标的哪个健被单击了,0表示左键,1表示中键,2表示右键

* relatedTarget: 与事件相关联的节点,主要用于mouseover与mouseout事件。

MouseEvent接口中新增的方法为initMouseEvent,它在原来initUIEnent方法上将新增的10个属性加到参数中,它的作用是创建MouseEvent类型的事件,调用语法如下:

event.initMouseEvent(type,canBubble,cancelable,view,detail,.....);

###### MouseEvents事件的类型

* click: 单击

* mousedown: 按下鼠标

* mouseup:松开鼠标

* mouseover: 鼠标进入

* mousemove: 鼠标移动

* mouseout: 鼠标移出

#### MutationEvents事件

MutationEvents事件对应MutationEvent接口。Mutation接口继承自Event接口,它在原来的基础上添加了5个只读属性、一个方法属性和3个常量属性。

######5个只读属性

* relatedNode: 相关节点

* prevValue: 之前的值

* newValue: 新值

* attrName:属性名

* attrChange: 属性变化类型

###### 事件类型

* DOMAttrModified

* DOMAttributeNameChanged

* DOMCharacterDataModified

* DOMElementNameChanged

* DOMNodeInserted

* DOMNodeInsertedIntoDocument

* DOMNodeRemoved

* DOMNodeRemovedFromDocument

* DOMSubtreeModified

#### HTMLEvents事件

HTMLEvents事件没有自己单独的接口,也就是说,它直接使用Event接口。HTMLEvents事件共有12种类型,如下:

![HTMLEvents事件的类型](https://upload-images.jianshu.io/upload_images/2789632-c17941113259a58c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#### DOM0级事件

Events子标准实在DOM2种才加入的。其实,在DOM标准发布之前浏览器种就已经可以使用事件了,此类型事件一般叫做DOM0级事件。

DOM0级事件是通过节点的属性来实现的,属性的名称为“on+事件名”的格式,其中,事件名的首字母不需要大写,例如,onclick、onload、onfocus等。DOM0级事件的添加有两种方式,一种是直接作为属性写在标签中,另一种是在脚本中通过节点对象的属性 来添加。

代码示例:

```

<body onload="listener(event);">

   <div id='a'>excellib</div>

   <script>

       function listener(event){

           console.log(event.type);

       }

       var div = document.getElementById('a');

       div.onclick = listener;

   </script>

</body>

```

![测试结果](https://upload-images.jianshu.io/upload_images/2789632-eb0623dbcee85366.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

目录
相关文章
|
2月前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
22天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
2月前
|
缓存 监控 前端开发
JavaScript 实现大文件上传的方法
【10月更文挑战第17天】通过以上步骤和方法,我们可以实现较为可靠和高效的大文件上传功能。当然,具体的实现方式还需要根据实际的应用场景和服务器要求进行调整和优化。
|
7天前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
101 52
|
21天前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
21天前
|
缓存 JavaScript UED
js中BOM中的方法
【10月更文挑战第31天】
|
10天前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
|
21天前
|
JavaScript 前端开发
.js方法参数argument
【10月更文挑战第26天】`arguments` 对象为JavaScript函数提供了一种灵活处理参数的方式,能够满足各种不同的参数传递和处理需求,在实际开发中具有广泛的应用价值。
36 7
|
22天前
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。
|
22天前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。