JavaScript DOM事件模型

简介: JavaScript DOM事件模型早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的DOM事件模型及事件处理程序的分类。

JavaScript DOM事件模型

早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的DOM事件模型及事件处理程序的分类。

  1、DOM事件模型。DOM事件模型分为两种:事件冒泡和事件捕获。事件冒泡最初是微软提出的DOM事件流的模型,顾名思义,就是值浏览器的事件流如同冒泡一样,从最低处到最高处。最低处对应的是DOM中最具体的元素,最高处则是最外层元素,最外层元素一般就是document元素。

  a、事件冒泡模型:

     如下图,当点击最底层的span元素时,在冒泡模型中触发的事件流为:span的click事件触发---->父级元素div的click事件触发---->顶层的document元素的click事件触发。

 

   b、事件捕获模型:

    如下图,当点击span元素时,在事件捕获模型中触发的事件流为:最顶层的document的click事件首先被触发---->子容器div(同时也是span的父容器)的click事件被触发

---->最底层的span元素的click事件触发。

 

    可见,事件冒泡和事件捕获的事件触发流程是完全相反的。

 

  2、DOM事件处理程序的分类。DOM事件处理程序分为三种:HTML事件处理程序、DOM 0级事件处理程序、DOM 2级事件处理程序(注意:、没有DOM1级事件处理程序)。

  a、HTML事件处理程序:

    指的是事件绑定直接写在HTML上,如:

1 <input type="button' value="button" onclick="alert('button clicked!')" />

    这里button的click事件的绑定直接写在HTML中,这种写法即是HTML事件处理程序。由于这种写法造成HTML和JavaScript的紧耦合,当需要调整JavaScript事件时,不得不调整HTML代码(就算不修改JavaScript函数名,只修改函数的内部实现,仍然不推荐使用这种语法绑定事件,会增加不必要的维护成本)。

 

   b、DOM 0级事件处理程序:

    指的是通过给JavaScript对象的事件参数属性赋值的模式,如:

复制代码
1 <input id="btn" type="button" value="button" />
2 <script>
3     var btn = document.getElementById("btn");
4     btn.onclick = function(){
5         alert("button clicked!");
6     }
7 </script>
复制代码

    这里通过直接给btnDOM对象的onclick属性赋值的形式来绑定click事件就是DOM 0级事件处理程序,赋值可以使用匿名函数的形式,也可以使用具名函数的形式,如下:

复制代码
1 <input id="btn" type="button" value="button" />
2 <script>
3     var btn = document.getElementById("btn");
4     btn.onclick clickHandle;
5     function clickHandle(){
6         alert("something clicked!");
7     }
8 </script>
复制代码

    如需注销,只需将该属性设置为null即可,如下:

复制代码
1 <input id="btn" type="button" value="button" />
2 <script>
3     var btn = document.getElementById("btn");
4     btn.onclick clickHandle;
5     function clickHandle(){
6         alert("something clicked!");
7     }
8     btn.onclick = null;
9 </script>
复制代码

    注意:如果绑定使用的是匿名函数的形式,通过给事件属性赋值null仍然可以注销该事件。

 

  c、DOM 2级事件处理程序:

    指的是使用 addEventListener("eventName","eventHandle",false),其中eventName表示事件名称、eventHandle表示事件处理函数,false表示是否启用事件捕获模式,默认为false。使用addEventListener函数来给DOM元素绑定事件处理程序,如:

复制代码
1 <input id="btn" type="button" value="button" />
2 <script>
3     var btn = document.getElementById("btn");
4     btn.addEventListener("click",function(){
5         alert("something clicked!");
6     },false);
7 </script>
复制代码

    同样,这里既可以使用匿名函数的形式也可以使用具名函数的形式,如:

复制代码
1 <input id="btn" type="button" value="button" />
2 <script>
3     var btn = document.getElementById("btn");
4     btn.addEventListener("click",clickHandle,false);
5     function clickHandle(){
6         alert("something clicked!");
7     }
8 </script>
复制代码

    注意:通过addEventListener绑定的事件只能通过removeEventListener来注销,不能使用DOM 0级中的方式注销事件处理程序,注销事件如下:

复制代码
1 <input id="btn" type="button" value="button" />
2 <script>
3     var btn = document.getElementById("btn");
4     btn.addEventListener("click",clickHandle,false);
5     function clickHandle(){
6         alert("something clicked!");
7     }
8     btn.removeEventListener("click",clickHandle);
9 </script>
复制代码

    如果绑定时使用的是匿名函数,则注销操作比较麻烦,可以通过事件参数的callee属性获取当前正在执行的函数,但必须使用在事件绑定的函数内,如:

复制代码
 1 <script>
 2     var dom=document.getElementById("content");
 3     var clickNum=0;
 4     dom.addEventListener("click",function(e){
 5     clickNum++;
 6     alert('你摸了我'+clickNum+'下了。最多摸2下哦');
 7     if(clickNum>=2){
 8         dom.removeEventListener(e.type,arguments.callee,false);
 9         console.log(this);
10     }
11 });
12 </script>
复制代码

 

  d、IE中DOM 2级事件处理程序的是通过attachevent来绑定的,语法与addEventListener完全一致。

 

  e、DOM 0级和DOM 2级事件处理程序的主要区别:

    DOM 2级事件处理程序可以给元素的事件绑定多个处理程序,如:

复制代码
 1 <input id="btn" type="button" value="button" />
 2 <script>
 3     var btn = document.getElementById("btn");
 4     btn.addEventListener("click",clickHandle1,false);
 5     btn.addEventListener("click",clickHandle2,false);
 6     function clickHandle1(){
 7         alert("something clicked!");
 8     }
 9     function clickHandle2(){
10         alert("something clicked again!");
11     }
12 </script>
复制代码

    此时,点击btn时将会依次触发clickHandle1、clickHandle2,注销事件处理程序也需要针对每个事件处理程序使用removeEventListener。

       DOM 0级事件处理程序如果以这种形式绑定事件,则后写的方法会覆盖掉之前的方法,即:

复制代码
 1 <input id="btn" type="button" value="button" />
 2 <script>
 3     var btn = document.getElementById("btn");
 4     btn.onclick = clickHandle1();
 5     btn.onclick = clickHandle2();
 6     function clickHandle1(){
 7         alert("something clicked!");
 8     }
 9     function clickHandle2(){
10         alert("something clicked again!");
11     }
12 </script>
复制代码

    这里实际只会绑定clickHandle2方法,clickHandle1被后面的clickHandle2覆盖掉。

 

   开发过程中推荐使用DOM 0级事件处理程序或者DOM 2级事件处理程序,如果只有一个事件处理程序DOM 0级就足够了,当然,如需绑定多个事件处理程序,则需使用DOM 2级事件处理程序。

  为了屏蔽各浏览器之间的实现差异,推荐使用一些JavaScript库来辅助完成事件绑定。推荐使用jQuery,针对不同的浏览器,可以使用统一的接口来完成这一过程。

参考:

  js如何移除匿名函数的事件绑定 - https://www.cnblogs.com/sichaoyun/p/6776310.html

原文地址https://www.cnblogs.com/Westin-Chen/p/10549684.html

相关文章
|
30天前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
15天前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
16天前
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。
|
26天前
|
XML 编解码 JavaScript
DOM(文档对象模型)和 BOM(浏览器对象模型)
【10月更文挑战第19天】在前端开发中,理解 DOM(文档对象模型)和 BOM(浏览器对象模型)是至关重要的。它们是 Web 开发的基础,为我们提供了与网页文档和浏览器进行交互的能力。
|
1月前
|
存储 JavaScript 前端开发
js事件队列
【10月更文挑战第15天】
47 6
|
8天前
|
JavaScript 前端开发
深入理解Node.js中的异步编程模型
【10月更文挑战第39天】在Node.js的世界里,异步编程是核心所在,它如同自然界的水流,悄无声息却又无处不在。本文将带你探索Node.js中异步编程的概念、实践以及如何优雅地处理它,让你的代码像大自然的流水一样顺畅和高效。
|
1月前
|
移动开发 JavaScript 前端开发
原生js如何获取dom元素的自定义属性
原生js如何获取dom元素的自定义属性
50 4
|
1月前
|
Web App开发 JavaScript 前端开发
深入理解Node.js事件循环和异步编程模型
【10月更文挑战第9天】在JavaScript和Node.js中,事件循环和异步编程是实现高性能并发处理的基石。本文通过浅显易懂的语言和实际代码示例,带你一探究竟,了解事件循环的工作原理及其对Node.js异步编程的影响。从基础概念到实际应用,我们将一步步解锁Node.js背后的魔法,让你的后端开发技能更上一层楼!
|
1月前
|
JavaScript API
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
106 0
|
1月前
|
JavaScript 前端开发 API
深入理解jQuery:高效DOM操作与事件处理
【10月更文挑战第11天】深入理解jQuery:高效DOM操作与事件处理
18 0