早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的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上,如:

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

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

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

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("button clicked!");
}
</script>

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.onclick clickHandle;
function clickHandle(){
alert("something clicked!");
}
</script>

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.onclick clickHandle;
function clickHandle(){
alert("something clicked!");
}
btn.onclick = null;
</script>

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

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

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
alert("something clicked!");
},false);
</script>

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click",clickHandle,false);
function clickHandle(){
alert("something clicked!");
}
</script>

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click",clickHandle,false);
function clickHandle(){
alert("something clicked!");
}
btn.removeEventListener("click",clickHandle);
</script>

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

 <script>
var dom=document.getElementById("content");
var clickNum=0;
dom.addEventListener("click",function(e){
clickNum++;
alert('你摸了我'+clickNum+'下了。最多摸2下哦');
if(clickNum>=2){
dom.removeEventListener(e.type,arguments.callee,false);
console.log(this);
}
});
</script>

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

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

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click",clickHandle1,false);
btn.addEventListener("click",clickHandle2,false);
function clickHandle1(){
alert("something clicked!");
}
function clickHandle2(){
alert("something clicked again!");
}
</script>

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

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

 <input id="btn" type="button" value="button" />
<script>
var btn = document.getElementById("btn");
btn.onclick = clickHandle1();
btn.onclick = clickHandle2();
function clickHandle1(){
alert("something clicked!");
}
function clickHandle2(){
alert("something clicked again!");
}
</script>

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

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

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

参考:

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

JavaScript DOM事件模型的更多相关文章

  1. JavaScript DOM 事件模型

    JavaScript DOM 事件模型 JavaScript 是基于面向对象和事件驱动的一门语言,事件模型是 DOM 中至关重要的内容,理解事件驱动机制.事件反馈.事件冒泡.事件捕获以及事件委托能帮助 ...

  2. 走进javascript——DOM事件

    DOM事件模型 在0级DOM事件模型中,它只是简单的执行你为它绑定的事件,比如你为某个元素添加了一个onclick事件,当事件触发时,它只是去调用我们绑定的那个方法,不再做其他的操作. 在2级DOM事 ...

  3. javascript中0级DOM和2级DOM事件模型浅析

    Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用: <input type="button&q ...

  4. javascript中0级DOM和2级DOM事件模型浅析 分类: C1_HTML/JS/JQUERY 2014-08-06 15:22 253人阅读 评论(0) 收藏

    Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用: <input type="button&q ...

  5. DOM事件模型浅析

    1.何为DOM DOM是"Document Object Model"的缩写,中文译为"文档对象模型".它是一种跨平台.跨语言的编程接口,将HTML,XHTML ...

  6. W3C DOM 事件模型(简述)

    1.事件模型 由于事件捕获与冒泡模型都有其长处和解释,DOM标准支持捕获型与冒泡型,能够说是它们两者的结合体.它能够在一个DOM元素上绑定多个事件处理器,而且在处理函数内部,thiskeyword仍然 ...

  7. JavaScript Dom 事件

    JavaScript  Dom 事件 对于事件需要注意的要点: // this标签当前正在操作的标签. this // event封装了当前事件的内容. even 常用事件 // 鼠标单击.触发事件 ...

  8. DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件

    前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...

  9. javascript之事件模型

    事件模型 冒泡型事件(Bubbling):事件由叶子节点沿祖先节点一直向上传递到根节点 捕获型事件(Capturing):由DOM树最顶元素一直到最精确的元素,与冒泡型事件相反 DOM标准事件模型:D ...

随机推荐

  1. luogu3346 诸神眷顾的幻想乡 (广义SAM)

    首先,让每一个叶节点做一次树根的话,每个路径一定至少有一次会变成直上直下的 于是对于每个叶节点作为根产生的20个trie树,把它们建到同一个广义SAM里 建法是对每个trie dfs去建,last就是 ...

  2. virtualBox centos 6.5 硬盘扩容

    1. 操作virtual Box 将该虚拟机关机,然后将打开管理->介质管理 调整硬盘大小 2. 操作Linux 1. 将放大的进行分区建立 2. 将分区建立分区表 3. 将该分区合并到root ...

  3. spring-boot-devtools在Idea中热部署方法

    1 pom.xml文件 注:热部署功能spring-boot-1.3开始有的 <!--添加依赖--> <dependency> <groupId>org.sprin ...

  4. 【机器学习】BP & softmax求导

    目录 一.BP原理及求导 二.softmax及求导 一.BP 1.为什么沿梯度方向是上升最快方向     根据泰勒公式对f(x)在x0处展开,得到f(x) ~ f(x0) + f'(x0)(x-x0) ...

  5. Entity Framework入门教程(7)--- EF中的查询方法

    这里主要介绍两种查询方法 Linq to entity(L2E)和Sql 1.L2E查询 L2E查询时可以使用linq query语法,或者lambda表达式,默认返回的类型是IQueryable,( ...

  6. 报表工具-ECharts 特性介绍

    ECharts 特性介绍 ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,S ...

  7. MongoDB实战性能优化

    1. 性能优化分类 mongodb性能优化分为软件层面和操作系统层面. 软件层面,一般通过修改mongodb软件配置参数来达到,这个需要非常熟悉mongodb里面的各种配置参数: 而操作系统层面,相对 ...

  8. jQuery AJAX 方法 success()后台传来的4种数据

    JAVA中的四种JSON解析方式详解 jQuery AJAX 方法 success()后台传来的4种数据 1.后台返回一个页面 js代码 /**(1)用$("#content-wrapper ...

  9. luogu 3084 单调队列+dp

    注意处理出两个数组: r[i] 能覆盖i点的区间的左端点最小值(覆盖左侧最远处) l[i] i不能覆盖的区间的左端点左端点最大值 在该区间内寻找用来更新f[i] 答案的 j 即 l[i]<= j ...

  10. safari中input、textarea无法输入的问题

    网址:https://www.cnblogs.com/xiayu25/p/6832748.html * { -webkit-box-sizing: border-box; -moz-box-sizin ...