Javascript 事件机制
事件是一种异步编程的实现方式。
一、DOM 事件模型
1.1 EventTarget 接口
Element 节点、document节点和window对象都实现了EventTarget接口,EventTarget接口定义了 DOM 事件的监听、取消和触发。
- 绑定事件的监听函数:
addEventListener(type, listener, useCapture)type: 事件名称,大小写敏感;listener: 回调函数;useCapture: 布尔值,表示监听函数是否在捕获阶段(capture)触发,默认为false;- 可以为对一个对象的一个事件添加多个监听函数,各监听函数会按照添加数据执行;
- 为同一事件多次添加同一监听,监听不会重复执行;
- 移除事件的监听函数:
removeEventListener(type, listener, useCapture) - 触发事件:
dispatchEvent(event)event: Event 对象- 该方法返回一个布尔值,只要有一个监听函数调用了
Event.prototype.preventDefault(),则返回值为false,否则为true。
1.2 监听函数
- HTML 标签 on-属性:
<body onload="doSomething()">- 监听只会在冒泡阶段触发;
on-属性的值只是监听代码,不是监听函数,如果要执行函数必须在加上括号;- 回调函数内部的
this指向全局对象,因为只是调用函数执行;
- Element 节点的时间属性:
window.onload = doSomething;- 监听只会在冒泡阶段触发;
- 重复定义,之前定义的回被覆盖
- 回调函数内部的
this指element节点;
addEventListener方法- 可以针对同一个时间添加多个监听
- 能够制定在事件的哪个阶段触发回调函数
- 可以添加在
window、XMLHttpRequest等对象上面 - 回调函数内部的
this指element节点;
1.3 事件的传播(propagation)
一个事件发生后会在不同的 DOM 节点之间传播
- 事件传播的三个阶段
- 捕获阶段(capture):从
window对象传导到目标节点; - 目标阶段(target):在目标节点上触发;
- 冒泡阶段(bubbling):从目标节点传回
window对象;
- 捕获阶段(capture):从
- 事件代理:由于事件会在冒泡阶段向上传导到父节点,因此可以把子节点的监听函数定义到父节点上,由父节点监听函数统一处理多个子节点的事件;事件代理有以下优点:
- 只需要添加一个监听函数
- 后添加进来的子节点也可以响应事件
1.4 Event 对象
事件发生后会生成一个事件对象,作为参数传递个监听函数;
事件对象创建,通过浏览器原生Event对象创建,event = new Event(typeArg, eventInit);
typeArg:事件名称,字符串eventInit:事件对象配置bubbles:布尔值,可选,默认为 false,表示事件对象是否冒泡。cancelable:布尔值,可选,默认为 false,表示事件是否可以被取消。
事件对象的属性
bubbles:布尔值,只读,表示当前事件是否会冒泡eventPhase:整数值,表示事件目前所处的阶段cancelable:布尔值,表示事件是否可以取消。defaultPrevented:布尔值,表示该事件是否调用过 preventDefault 方法currentTarget:返回事件当前所在的节点target:返回触发事件的那个节点,即事件最初发生的节点type:字符串,表示事件类型,大小写敏感detail:数值,表示事件的某种信息timeStamp:毫秒时间戳,表示事件发生的时间。isTrusted:布尔值,表示该事件是否为真实用户触发。
事件对象方法:
preventDefault:取消浏览器对当前事件的默认行为stopPropagation:阻止事件在 DOM 中继续传播stopImmediatePropagation:阻止同一个事件的其他监听函数被调用
1.5 自定义事件
// 新建事件实例
var event = new Event('build');
// 添加监听函数
elem.addEventListener('build', function (e) { ... }, false);
// 触发事件
elem.dispatchEvent(event);
// CustomEvent支持创建带参数的事件对象
var event = new CustomEvent('build', { 'detail': 'hello' });
function eventHandler(e) {
console.log(e.detail);
}
// 事件模拟
var event = new MouseEvent('click', {
'bubbles': true,
'cancelable': true
});
var cb = document.getElementById('checkbox');
cb.dispatchEvent(event);