DOM 事件的深入浅出(一)


Posted in Javascript onDecember 05, 2016

在项目开发时,我们时常需要考虑用户在使用产品时产生的各种各样的交互事件,比如鼠标点击事件、敲击键盘事件等。这样的事件行为都是前端DOM事件的组成部分,不同的DOM事件会有不同的触发条件和触发效果。本文就将带大家深入浅出地了解DOM事件的那些属性和方法。

首先在介绍DOM事件之前我们先来认识下DOM的不同级别。针对不同级别的DOM,我们的DOM事件处理方式也是不一样的。

DOM级别与DOM事件

DOM级别一共可以分为4个级别:DOM0级,DOM1级,DOM2级和 DOM3级,而DOM事件分为3个级别:DOM0级事件处理,DOM2级事件处理和DOM3级事件处理。如下图所示:

DOM 事件的深入浅出(一)

有人可能会问,为什么没有DOM1级事件处理呢?因为1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。

关于DOM级别这里不做详细的介绍,下面主要介绍下不同级别DOM中的不同事件。

1.DOM0级事件

在了解DOM0级事件之前,我们有必要先了解下HTML事件处理程序,也是最早的这一种的事件处理方式,代码如下:

<button type="button" onclick="showFn()"></button>
<script>
 function showFn() {
 alert('Hello World');
 }
</script>

以上代码我们通过直接在HTML代码里定义了一个onclick的属性触发showFn方法,这样的事件处理程序最大的缺点就是HTML于JS强耦合,我们一旦需要修改函数名就得修改两个地方。当然其优点是不需要操作DOM来完成事件的绑定。

那么什么是DOM0级处理事件呢?DOM0级事件就是将一个函数赋值给一个事件处理属性,比如:

<button id="btn" type="button"></button>
<script>
 var btn = document.getElementById('btn');
 btn.onclick = function() {
 alert('Hello World');
 }
 // btn.onclick = null; 解绑事件 
</script>

以上代码我们给button定义了一个id,通过JS获取到了这个id的按钮,并将一个函数赋值给了一个事件处理属性onclick,这样的方法便是DOM0级处理事件的体现。我们可以通过给事件处理属性赋值null来解绑事件。

DOM0级事件处理程序的缺点在于一个处理程序无法同时绑定多个处理函数,比如我还想在按钮点击事件上加上另外一个函数。

2.DOM2级事件

DOM2级事件在DOM0级事件的基础上弥补了一个处理程序无法同时绑定多个处理函数的缺点,允许给一个处理程序添加多个处理函数。代码如下:

<button id="btn" type="button"></button>
<script>
 var btn = document.getElementById('btn');
 function showFn() {
 alert('Hello World');
 }
 btn.addEventListener('click', showFn, false);
 // btn.removeEventListener('click', showFn, false); 解绑事件 
</script>

DOM2级事件定义了addEventListener和removeEventListener两个方法,分别用来绑定和解绑事件,方法中包含3个参数,分别是绑定的事件处理属性名称(不包含on)、处理函数和是否在捕获时执行事件处理函数。如果我们还需要添加一个鼠标移入的方法,只需要:

btn.addEventListener('mouseover', showFn, false);

这样点击按钮和鼠标移入时都将触发showFn方法。

需要注意的是IE8级以下版本不支持addEventListener和removeEventListener,需要用attachEvent和detachEvent来实现:

btn.attachEvent('onclick', showFn); // 绑定事件 
btn.detachEvent('onclick', showFn); // 解绑事件

这里我们不需要传入第三个参数,因为IE8级以下版本只支持冒泡型事件。

3.DOM3级事件

DOM3级事件在DOM2级事件的基础上添加了更多的事件类型,全部类型如下:

  1. UI事件,当用户与页面上的元素交互时触发,如:load、scroll
  2. 焦点事件,当元素获得或失去焦点时触发,如:blur、focus
  3. 鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
  4. 滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
  5. 文本事件,当在文档中输入文本时触发,如:textInput
  6. 键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
  7. 合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
  8. 变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified

同时DOM3级事件也允许使用者自定义一些事件。

DOM事件流

上文中讲到了addEventListener的第三个参数为指定事件是否在捕获或冒泡阶段执行,设置为true表示事件在捕获阶段执行,设置为true表示事件在捕获阶段执行,而设置为false表示事件在冒泡阶段执行。那么什么是事件冒泡和事件捕获呢?可以用下图来解释:

DOM 事件的深入浅出(一)

1.事件冒泡

所谓事件冒泡就是事件像泡泡一样从最开始生成的地方一层一层往上冒,比如上图中a标签为事件目标,点击a标签后同时也会触发p、li上的点击事件,一层一层向上直至最外层的html或document。下面是代码示例:

<div id="box">
 <a id="child">事件冒泡</a>
</div>
<script>
 var box = document.getElementById('box'),
 child = document.getElementById('child');
 child.addEventListener('click', function() {
 alert('我是目标事件');
 }, false);
 box.addEventListener('click', function() {
 alert('事件冒泡至DIV');
 }, false);
</script>

上面的代码运行后我们点击a标签,首先会弹出'我是目标事件'提示,然后又会弹出'事件冒泡至DIV'的提示,这便说明了事件自内而外向上冒泡了。

那么我们如何阻止事件冒泡呢?这里就涉及事件的Event对象中的stopPropagation方法,如下:

child.addEventListener('click', function(e) {
 alert('我是目标事件');
 e.stopPropagation();
}, false);

加上stopPropagation方法后,我们再次点击a标签就不会触发div上的click事件了。

2.事件捕获

和事件冒泡相反,事件捕获是自上而下执行,我们只需要将addEventListener的第三个参数改为true就行。

<div id="box">
 <a id="child">事件冒泡</a>
</div>
<script>
 var box = document.getElementById('box'),
 child = document.getElementById('child');
 child.addEventListener('click', function() {
 alert('我是目标事件');
 }, true);
 box.addEventListener('click', function() {
 alert('事件冒泡至DIV');
 }, true);
</script>

此时我们点击a标签,首先弹出的是'事件冒泡至DIV',其次弹出的是'我是目标事件',正好与事件冒泡相反。

总结

本文主要介绍了不同DOM级别下的事件处理程序,同时介绍了事件冒泡和捕获的触发原理和方法。熟练地使用不同级别的DOM事件并且解决相应的浏览器兼容性问题对我们的前端项目开发会很有帮助。在下篇文章中,我将给大家介绍DOM事件中Event对象的属性和方法。

以上就是本文的全部内容,希望对大家有所帮助,有兴趣的朋友可以看下《DOM 事件的深入浅出(二)》同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
用JavaScript编写COM组件的步骤
Mar 17 Javascript
关于javascript 回调函数中变量作用域的讨论
Sep 11 Javascript
显示js对象所有属性和方法的函数
Oct 16 Javascript
javascript下利用arguments实现string.format函数
Aug 24 Javascript
js获得页面的高度和宽度的方法
Feb 23 Javascript
jquery禁用右键单击功能屏蔽F5刷新
Mar 17 Javascript
JavaScript实现16进制颜色值转RGB的方法
Feb 09 Javascript
js实现文本框选中的方法
May 26 Javascript
JS返回只包含数字类型的数组实例分析
Dec 16 Javascript
JavaScript实现瀑布流图片效果
Jun 30 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
Mar 28 Javascript
vue中英文切换实例代码
Jan 21 Javascript
使用微信小程序开发前端【快速入门】
Dec 05 #Javascript
学习vue.js表单控件绑定操作
Dec 05 #Javascript
JavaScript易错知识点整理
Dec 05 #Javascript
JS 对java返回的json格式的数据处理方法
Dec 05 #Javascript
原生js实现键盘控制div移动且解决停顿问题
Dec 05 #Javascript
bootstrap快速制作后台界面
Dec 05 #Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
Dec 04 #Javascript
You might like
PHP的拦截器实例分析
2014/11/03 PHP
thinkPHP5框架接口写法简单示例
2019/08/05 PHP
JS input 数字验证代码
2009/07/30 Javascript
jQuery dialog 异步调用ashx,webservice数据的代码
2010/08/03 Javascript
javascript的内存管理详解
2013/08/07 Javascript
浅谈jQuery中setInterval()方法
2015/07/07 Javascript
jquery实现实时改变网页字体大小、字体背景色和颜色的方法
2015/08/05 Javascript
如何消除inline-block属性带来的标签间间隙
2016/03/31 Javascript
chrome下判断点击input上标签还是其余标签的实现方法
2016/09/18 Javascript
分享一个原生的JavaScript拖动方法
2016/09/25 Javascript
JavaScript实现简易的天数计算器实例【附demo源码下载】
2017/01/18 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
在页面中引入js的两种方法(推荐)
2017/08/29 Javascript
vue按需加载组件webpack require.ensure的方法
2017/12/13 Javascript
python海龟绘图实例教程
2014/07/24 Python
Python 加密的实例详解
2017/10/09 Python
python基于twisted框架编写简单聊天室
2018/01/02 Python
Python使用Pickle库实现读写序列操作示例
2018/06/15 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
Python清空文件并替换内容的实例
2018/10/22 Python
Python自定义一个类实现字典dict功能的方法
2019/01/19 Python
python实现抖音点赞功能
2019/04/07 Python
搞清楚 Python traceback的具体使用方法
2019/05/13 Python
Python 使用type来定义类的实现
2019/11/19 Python
Pytorch 中retain_graph的用法详解
2020/01/07 Python
关于keras中keras.layers.merge的用法说明
2020/05/23 Python
python实现图片素描效果
2020/09/26 Python
灵活运用CSS3特性绘制简易版围棋效果
2016/09/28 HTML / CSS
美国家居装饰购物网站:Amanda Lindroth
2020/03/25 全球购物
经理秘书求职自荐信范文
2014/03/23 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
教师节寄语2015
2015/03/23 职场文书
学生党支部工作总结2015
2015/05/26 职场文书
学生会部长竞选稿
2015/11/19 职场文书