早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的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. shell之获取终端信息

    #!/bin/bash #tput和stty是两款终端处理工具 #获取列数和行数 tput cols tput lines #打印当前终端名 tput longname #移动光标 移动光标到100 ...

  2. C# LINQ语法详解

    1.简单的linq语法 var ss = from r in db.Am_recProScheme select r; var ss1 = db.Am_recProScheme; string sss ...

  3. 微服务之路由网关—zuul

    Zuul 简介Zuul 是 Netflix 公司开发的一个开源 APIGateway,其本质上是一个 WebServlet 应用.Zuul 的核心是一系列的 Filter. 为什么要使用 Zuul微服 ...

  4. CMDB资产管理系统开发【day27】:理解RESTful架构

    理解RESTful架构 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(hig ...

  5. 第一次连接数据库mongodb踩的坑

    类型匹配错误,参数要写对了,name与age一一对应. 如果没找到错误就把异常打印出来. await person.save(function(err) { if(err) console.log(e ...

  6. JGUI源码:Accordion鼠标中键滚动和手机端滑动实现(2)

    本文是抽屉组件在PC端滚动鼠标中键.手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,IE8+等浏览器. 演示在:www.jgui.com Github地址:ht ...

  7. 液晶流在齐次 Besov 空间中的正则性准则

    在 [Zhang, Zujin. Regularity criteria for the three dimensional Ericksen–Leslie system in homogeneous ...

  8. [Kubernetes]深入解析Pod对象

    k8s集群搭建是比较容易的,但是我们为什么要搭建,里面涉及到的内容,我们为什么需要? 这篇文章就尝试来讲讲,我们为什么需要一个Pod,对Pod对象来一个深入解析. 我们为什么需要Pod 我们先来谈一个 ...

  9. DCM、PLL、PMCD、MMCM相关

    摘自网上 : http://xilinx.eetop.cn/viewnews-1482 The DCM is a Digital Clock Manager - at its heart it is ...

  10. Linux Django项目测试

    步骤 django项目: 依赖包 [root@web01 ~]# yum install openssl-devel bzip2-devel expat-devel gdbm-devel readli ...