什么是DOM?
文档对象模型,HTML 是一棵树,DOM 也是一棵树。对 DOM 的理解,可以暂时先抛开浏览器的内部因素,先从 JS 着手,即可以认为 DOM 就是 JS 能识别的 HTML 结构,一个普通的 JS 对象或者数组。
DOM事件:浏览器或者用户执行的动作
DOM事件流/DOM事件模型:就是冒泡和捕获
DOM有四次版本更新,产生了3种不同的DOM事件定义 DOM0级、DOM2级、DOM3级。由于DOM1级中没有事件的相关内容,所以没有DOM1级事件。
DOM0级事件
<p onclick="alert('click')">HTML事件处理程序</p>
或者
var btn = document.getElementById('btn');
btn.onclick = function(){
alert(this.innerHTML);
}
HTML代码域JavaScript代码紧密的耦合在一起,使用这个方法指定的监听函数,只会在冒泡阶段触发。并且不能给一个元素添加多个相同的事件。
<!-- 正确 -->
<body onload="doSomething()">
<!-- 错误 -->
<body onload="doSomething">
on-属性的值是原样传入JavaScript引擎执行。因此如果要执行函数,必须加上一对圆括号。
DOM2级事件
addEventListener和attachEvent
el.addEventListener(event-name, callback, useCapture)
useCapture:默认为false(监听函数只在冒泡阶段被触发)
addEventListener方法可以为当前对象的同一个事件,添加多个监听函数。这些函数按照添加顺序触发,即先添加先触发。如果为同一个事件多次添加同一个监听函数,该函数只会执行一次。并且监听函数内部的this对象总是指向触发事件的那个节点。
DOM3事件
DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件。DOM3级还定义了自定义事件,自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件。要创建的自定义事件可以由createEvent("CustomEvent");
DOM事件流
DOM的结构是一个树形,每当HTML元素产生事件时,该事件就会在树的根节点和元素节点之间传播,所有经过的节点都会收到该事件。捕获-->目标元素 --> 冒泡
DOM事件模型
DOM事件模型分为两类:一类是IE所使用的冒泡型事件(Bubbling);另一类是DOM标准定义的冒泡型与捕获型(Capture)的事件。除IE外的其他浏览器都支持标准的DOM事件处理模型。
事件的传播
传播的三个阶段
-
第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
-
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
-
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)
这种三阶段的传播模型,会使得一个事件在多个节点上触发。比如,假设点击<div>之中嵌套一个<p>节点。
<div>
<p>Click Me</p>
</div>
如果对这两个节点的click事件都设定监听函数,则click事件会被触发四次。因为<p>节点的捕获阶段和冒泡阶段各1次,<div>节点的捕获阶段和冒泡阶段各1次。事件传播的最上层对象是window,接着依次是document。所以我们平时写代码都确认是冒泡还是捕获。
事件的代理
把子元素的事件代理到父元素上。父节点的监听函数统一处理多个子元素的事件。
如果希望事件到某个节点为止,不再传播,可以使用事件对象的stopPropagation方法。
自定义事件
/ 新建事件实例
var event = new Event('build');
// 添加监听函数
elem.addEventListener('build', function (e) { ... }, false);
// 触发事件
elem.dispatchEvent(event);
Event构造函数只能指定事件名,不能在事件上绑定数据。如果需要在触发事件的同时,传入指定的数据,需要使用CustomEvent构造函数生成自定义的事件对象。
var myEvent = new CustomEvent("myevent", {
detail: {
foo: "bar"
},
bubbles: true,
cancelable: false
});
el.addEventListener('myevent', function(event) {
console.log('Hello ' + event.detail.foo);
});
el.dispatchEvent(myEvent);
event.preventDefault(),阻止默认行为
event.stopPropagation(),阻止事件冒泡
event.stopImmediatePropagation(),阻止剩余的事件处理函数执行并且防止事件冒泡到DOM树上,这个方法不接受任何参数。
网友评论