DOM 事件深刻浅出(一)

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

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

DOM级别与DOM事件

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

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

关于DOM级别这里不作详细的介绍,下面主要介绍下不一样级别DOM中的不一样事件。java

1.DOM0级事件

在了解DOM0级事件以前,咱们有必要先了解下HTML事件处理程序,也是最先的这一种的事件处理方式,代码以下:浏览器

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

 

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

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

<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来解绑事件。dom

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表示事件在捕获阶段执行,而设置为false表示事件在冒泡阶段执行。那么什么是事件冒泡和事件捕获呢?能够用下图来解释:

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对象的属性和方法。

相关文章
相关标签/搜索