DOM事件模型
- 从技术上来说,W3C的DOM标准并不支持上述最原始的添加事件监听函数的方式,这些都是在DOM标准形成前的事件模型。尽管没有正式的W3C标准,但这种事件模型仍然得到广泛应用,这就是我们通常所说的0级DOM。
<input type="button" id="myButton" onclick="alert('Button Click')" />
或
document.getElementById("myButton").onclick = function () {
alert("Button Click");
}
- 没有1级DOM。DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。
- 在2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的2级DOM事件模型。
document.getElementById("myButton").addEventListener("click",
function (event) {
alert("Button Click");
console.log(event)
},
true)
// 回调的第一个参数是被触发的事件对象,下面会简单介绍Event
DOM事件流
描述的就是从页面中接受事件的顺序。分有事件冒泡与事件捕获两种。
DOM事件流有三个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段

可以通过addEventListener
注册事件时声明捕获还是冒泡阶段,处于捕获阶段的事件会比冒泡阶段先发生
相关API
-
Event(typeArg, eventInit)
- type
- target
- currentTarget
- clientX, clientY
- screenX, screenY
- CustomEvent(typeArg, eventInitDict)
-
addEventListener
- 注册事件监听器
- 常用格式
target.addEventListener(type, listener, useCapture)
- 回调listener的第一个参数可以是event对象
- useCapture表示注册的是捕获阶段(true)还是冒泡阶段(false,默认)
- stopPropagation,阻止事件传递
-
preventDefault,阻止事件默认行为,下面两个例子
- 阻止复选框被勾选
- 阻止input写入内容
简单说一下,Event的eventInit和CustomEvent的eventInitDict的区别
Event的eventInit有三个属性可以选择:bubbles表示是否可以冒泡,cancelable表示是否可以被取消,还有一个不常用的composed;
CustomEvent的eventInitDict,除了上面的bubbles和cancelable,还有一个details,它可以传入你自定义的一些数据,供给注册事件监听器时在回调里面可以调用的一些数据
重点解析
bubbles
默认为false,当为false时不发生事件冒泡,也就是说,如果注册的事件监听器是冒泡阶段捕获的话,将不会发生
var button = document.getElementById('clickMe');
var myEvent = new CustomEvent('demoEvent', {
bubbles: false,
cancelable: false,
detail: {
index: 'hello demo'
}
})
button.addEventListener('click', function () {
console.log('1. You click Button')
button.dispatchEvent(myEvent)
}, true);
document.body.addEventListener('demoEvent', function () {
console.log('2. You click body')
}, false);
document.addEventListener('demoEvent', function (e) {
console.log('3. You click document')
}, true);
window.addEventListener('demoEvent', function (e) {
console.log('4. You click window')
}, false);
上面的2和3不会发生,因为事件demoEvent的bubbles是false,事件没有冒泡阶段
cancelable
如果该事件的 cancelable 属性为 false, 则该事件的监听器无法阻止默认行为, 调用preventDefault() 将产生错误
自定义事件
逻辑如下:
- 新建一个事件对象,Event或者CustomEvent都行,但是变量名不要取event,因为在回调里会因为作用域问题被屏蔽
- 用一个节点对象发起事件(dispatch),该节点就算是事件流里的目标对象
- 在事件流里的所有注册了该事件的节点对象,都会调用回调
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Bubbling</title>
</head>
<body>
<button id="clickMe">Click Me</button>
</body>
</html>
<script>
var button = document.getElementById('clickMe');
var myEvent = new CustomEvent('demoEvent', {
bubbles: true,
cancelable: false,
detail: {
index: 'hello demo'
}
})
button.addEventListener('click', function () {
console.log('1. You click Button')
button.dispatchEvent(myEvent)
}, true);
document.body.addEventListener('demoEvent', function () {
console.log('2. You click body')
}, false);
document.addEventListener('demoEvent', function (e) {
console.log('3. You click document')
}, true);
window.addEventListener('demoEvent', function (e) {
console.log('4. You click window')
}, false);
</script>
参考
这篇博客是参考了很多博客和API文档,总结出来的。
包括但不限于:
事件模型浅析
Event
CustomEvent
创建和触发 events
网友评论