早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的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. hdu 3480 Division(四边形不等式优化)

    Problem Description Little D is really interested in the theorem of sets recently. There’s a problem ...

  2. POJ--3974 Palindrome(回文串,hash)

    链接:点击这里 #include<iostream> #include<algorithm> #include<stdio.h> #include<cstri ...

  3. 学习Git过程中常用命令的总结

    复制远程库git clone git@github.com:Hconly/learngit.git在GitHub上,可以任意Fork开源仓库:自己拥有Fork后的仓库的读写权限:可以推送pull re ...

  4. 批量ping 检测linux主机是否可以通

    批量ping 检测linux主机是否可以通 # 1.配置列表 [root@db137 liweiwie]# cat /home/dbatlbb/script/liweiwie/ping_ip.txt ...

  5. Python项目读取配置的几种方式

    1. 将配置写在Python文件中 配置文件(config.py 或 settings.py) 通常放置在程序源代码的目录,方便引用 配置文件 # settings.py class Config(o ...

  6. Python list和 np.Array 的转换关系

    一.List转String 1.str list转 string a_list = ["h","e","l","l",& ...

  7. 深入jar包:从jar包中读取资源文件getResourceAsStream

    一.背景 我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等). 在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不 ...

  8. Fiddler--Composer

    Composer选项卡支持手动构建和发请求:也可以在Session列表中拖拽Session放到Composer中,把该Session的请求复制到用户界面: 点击"execute"按 ...

  9. docker的安装与基本使用

    安装docker curl -s https://get.docker.com|sh 好慢....一个小时吧... 启动docker 先执行命令docker version来来一下: docker v ...

  10. HBase读写的几种方式(一)java篇

    1.HBase读写的方式概况 主要分为: 纯Java API读写HBase的方式: Spark读写HBase的方式: Flink读写HBase的方式: HBase通过Phoenix读写的方式: 第一种 ...