DOM2级事件模型
- 既存在事件冒泡过程,又存在事件捕获过程。
- 一般先执行事件捕获,后执行事件冒泡。如果在这个时刻(冒泡或者事件捕获),有对应的事件处理函数,则执行对应的事件处理函数。这个时刻的事件处理函数,按照注册的顺序依次执行。事件捕获过程,事件会从父元素向子元素传递,事件捕获过程则相反。在chrome 浏览器上测试的结果与firefox结果略有不同:
- chrome 浏览器上,子元素是先执行事件捕获,然后执行事件冒泡的。
- 在firefox和360 浏览器上,子元素是先执行事件冒泡,然后执行事件捕获的。具体可以参照后面的代码例子。
- 在chrome 浏览器上,可以看到DOM节点继承的和定义的所有事件。
- addEventListener 函数,默认是事件冒泡,如果第三个参数是true,则表示事件,注册在事件捕获阶段。
DOM 0级事件模型
- 不存在事件捕获过程,只存在事件冒泡过程。在父子元素上同时绑定click事件,可以看到先子元素执行,后父元素执行
代码如下:
<ul id="ulDemo">
<li id="liDemo">Acc</li>
<li>Bcc</li>
<li>Ccc</li>
</ul>
<script>
var ul = document.getElementById('ulDemo');
var li = document.getElementById('liDemo');
// 执行顺序,和父元素的事件绑定模型有关,如果父元素在冒泡阶段触发,则先执行子元素的事件,
// 如果父元素在捕获阶段触发,则先执行父元素的事件
// ul.addEventListener('click', function(e) {
// console.log(4444, 'e', e);
// // return false;
// }, false);
ul.onclick = function(e) {
console.log('ul', 'DOM 0 级事件', e);
};
// 覆盖了上面定义的onclick事件
ul.onclick = function(e) {
console.log('ul', 'DOM 0级事件绑定第二次', e);
}
li.onclick = function(e) {
console.log('li', 'DOM 0级事件 子元素执行事件111', e);
}
li.onclick = function(e) {
console.log('li', 'DOM 0级事件 子元素执行事件222', e);
};
在浏览器中观察到如下效果:
li DOM 0级事件 子元素执行事件222 MouseEvent {isTrusted: true, screenX: 175, screenY: 132, clientX: 57, clientY: 14, …}
ul DOM 0级事件绑定第二次 MouseEvent {isTrusted: true, screenX: 175, screenY: 132, clientX: 57, clientY: 14, …}
DOM2级事件和DOM0 级事件
- DOM 0级事件,如果重复定义,会覆盖彼此.
- DOM 2级事件,如果重复定义,会依次执行.
- DOM 0级事件和DOM2级可以同时存在。
实例Demo
<html>
<head>
<title>测试事件执行顺序</title>
</head>
<body>
<ul id="ulDemo">
<li id="liDemo">Acc</li>
<li>Bcc</li>
<li>Ccc</li>
</ul>
<script>
var ul = document.getElementById('ulDemo');
var li = document.getElementById('liDemo');
// 执行顺序,和父元素的事件绑定模型有关,如果父元素在冒泡阶段触发,则先执行子元素的事件,
// 如果父元素在捕获阶段触发,则先执行父元素的事件
ul.addEventListener('click', function(e) {
console.log(4444, 'e', e);
// return false;
}, false);
ul.onclick = function(e) {
console.log('0000', 'DOM 0 级事件', e);
};
// 覆盖了上面定义的onclick事件
ul.onclick = function(e) {
console.log('0000', 'DOM 0级事件绑定第二次', e);
}
li.addEventListener('click', function(e) {
console.log(2222, 'e', e);
}, false);
li.addEventListener('click', function(e) {
console.log(333, 'e', e);
}, true);
ul.addEventListener('click', function(e) {
console.log(1111, 'e', e);
//e.stopPropagation();
// return false;
}, true);
</script>
</body>
</html>
- 以上代码的执行结果
- 在chrome 浏览器上的执行结果为:
1111 'e' PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
333 'e' PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
2222 'e' PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
4444 'e' PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
- 在firefox 浏览器上和360上的执行结果为:
1111 "e" MouseEvent {isTrusted: true, screenX: 184, screenY: 140, clientX: 65, clientY: 21, …}
2222 "e" MouseEvent {isTrusted: true, screenX: 184, screenY: 140, clientX: 65, clientY: 21, …}
333 "e" MouseEvent {isTrusted: true, screenX: 184, screenY: 140, clientX: 65, clientY: 21, …}
4444 "e" MouseEvent {isTrusted: true, screenX: 184, screenY: 140, clientX: 65, clientY: 21, …}