- A+
DOM 事件是处理 Web 页面交互的基础,是掌握前端开发技术的基础。
DOM 事件模型包括 4 个级别的规范:DOM0级,DOM1级,DOM2级和 DOM3级。 DOM1标准中不涉及事件。
1.DOM0级事件
DOM0 级事件处理就是将一个函数赋值给一个事件处理属性,如下
<button type="button" onclick="showFn()"></button> <script> function showFn() { alert('Hello World'); } </script>
<button id="btn" type="button"></button> <script> var btn = document.getElementById('btn'); btn.onclick = function() { alert('Hello World'); } // btn.onclick = null; 解绑事件 </script>
优点:
简单快速
缺点:
1、是HTML于JS 强耦合,绑定在一起
2、一个处理程序无法同时绑定多个处理函数
2.DOM2级事件
DOM2级标准中,事件定义了addEventListener和removeEventListener两个方法,分别用来绑定和解绑事件。
方法中包含3个参数,分别是绑定的事件处理属性名称(不包含on)、处理函数和是否在捕获时执行事件处理函数。
DOM2级事件允许给一个处理程序添加多个处理函数。代码如下:
<button id="btn" type="button"></button> <script> var btn = document.getElementById('btn'); function showFn() { alert('Hello World'); } btn.addEventListener('click', showFn, false); btn.addEventListener('mouseover', showFn, false); // 添加一个鼠标移入的方法 // btn.removeEventListener('click', showFn, false); 解绑事件 </script>
如果是 IE8 以下需要用attachEvent和detachEvent来实现
btn.attachEvent('onclick', showFn); // 绑定事件 btn.detachEvent('onclick', showFn); // 解绑事件 \ 这里我们不需要传入第三个参数,因为IE8级以下版本只支持冒泡型事件。
3.DOM3级事件
DOM3级事件在DOM2级事件的基础上添加了更多的事件类型,全部类型如下:
UI事件,当用户与页面上的元素交互时触发,如:load、scroll
焦点事件,当元素获得或失去焦点时触发,如:blur、focus
鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
文本事件,当在文档中输入文本时触发,如:textInput
键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified
同时DOM3级事件也允许使用者自定义一些事件。
DOM事件流
上文中讲到了addEventListener的第三个参数为指定事件是否在捕获阶段执行,设置为true表示事件在捕获阶段执行,而设置为false表示事件在冒泡阶段执行。那么什么是事件冒泡和事件捕获呢?可以用下图来解释:
1.事件冒泡
所谓事件冒泡就是事件像泡泡一样从最开始生成的地方一层一层往上冒,比如上图中a标签为事件目标,点击a标签后同时也会触发p、li上的点击事件,一层一层向上直至最外层的html或document。下面是代码示例:
上面的代码运行后我们点击a标签,首先会弹出’我是目标事件’提示,然后又会弹出’事件冒泡至DIV’的提示,这便说明了事件自内而外向上冒泡了。
那么我们如何阻止事件冒泡呢?这里就涉及事件的Event对象中的stopPropagation方法,如下:
child.addEventListener('click', function(e) {
alert('我是目标事件');
e.stopPropagation();
}, false);
加上stopPropagation方法后,我们再次点击a标签就不会触发div上的click事件了。
2.事件捕获
和事件冒泡相反,事件捕获是自上而下执行,我们只需要将addEventListener的第三个参数改为true就行。