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 监听函数

  1. HTML 标签 on-属性:<body onload="doSomething()">
    • 监听只会在冒泡阶段触发;
    • on-属性的值只是监听代码,不是监听函数,如果要执行函数必须在加上括号;
    • 回调函数内部的this指向全局对象,因为只是调用函数执行;
  2. Element 节点的时间属性:window.onload = doSomething;
    • 监听只会在冒泡阶段触发;
    • 重复定义,之前定义的回被覆盖
    • 回调函数内部的thiselement节点;
  3. addEventListener方法
    • 可以针对同一个时间添加多个监听
    • 能够制定在事件的哪个阶段触发回调函数
    • 可以添加在windowXMLHttpRequest等对象上面
    • 回调函数内部的thiselement节点;

1.3 事件的传播(propagation)

一个事件发生后会在不同的 DOM 节点之间传播

  1. 事件传播的三个阶段
    1. 捕获阶段(capture):从window对象传导到目标节点;
    2. 目标阶段(target):在目标节点上触发;
    3. 冒泡阶段(bubbling):从目标节点传回window对象;
  2. 事件代理:由于事件会在冒泡阶段向上传导到父节点,因此可以把子节点的监听函数定义到父节点上,由父节点监听函数统一处理多个子节点的事件;事件代理有以下优点:
    1. 只需要添加一个监听函数
    2. 后添加进来的子节点也可以响应事件

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);

TODO:Node 事件机制

TODO:观察者模式与事件机制

参考文献

Event 对象-阮一峰

results matching ""

    No results matching ""