DOM自定义事件

自定义事件虽然用的不多,但是理解他有助于理解事件绑定的原理,本质上是基于 EventTarget,系统已经内置比较完善的事件类型,比如:

  • UIEvent (用户界面事件)
    • MouseEvent
    • TouchEvent
    • FocusEvent
    • KeyboardEvent
    • WheelEvent
    • InputEvent
    • CompositionEvent

EventTarget 实现也是比较简单的:

var EventTarget = function() {
  this.listeners = {};
};

EventTarget.prototype.listeners = null;
EventTarget.prototype.addEventListener = function(type, callback) {
  if (!(type in this.listeners)) {
    this.listeners[type] = [];
  }
  this.listeners[type].push(callback);
};

EventTarget.prototype.removeEventListener = function(type, callback) {
  if (!(type in this.listeners)) {
    return;
  }
  var stack = this.listeners[type];
  for (var i = 0, l = stack.length; i < l; i++) {
    if (stack[i] === callback){
      stack.splice(i, 1);
      return;
    }
  }
};

EventTarget.prototype.dispatchEvent = function(event) {
  if (!(event.type in this.listeners)) {
    return true;
  }
  var stack = this.listeners[event.type].slice();

  for (var i = 0, l = stack.length; i < l; i++) {
    stack[i].call(this, event);
  }
  return !event.defaultPrevented;
};

1. 预备知识

  • Document.createEvent() 创建一个指定类型的事件。其返回的对象必须先初始化并可以被传递给 element.dispatchEvent;
  • Event.initEvent() 用来初始化由 Document.createEvent() 创建的 event 实例;
  • EventTarget.dispatchEvent() Dispatches an Event at the specified EventTarget;
  • EventTarget is a DOM interface implemented by objects that can receive events and may have listeners for them;

2. 代码演示

// 创建事件
var event = document.createEvent('Event');

// 定义事件名为'build'.
event.initEvent('build', true, true);

// 监听事件
elem.addEventListener('build', function (e) {
  // e.target matches elem
}, false);

// 触发对象可以是任何元素或其他事件目标
elem.dispatchEvent(event);

推荐使用下面的方式来创建 Event 对象:

// 创建一个支持冒泡且不能被取消的look事件
var ev = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(ev);

// 事件可以在任何元素触发,不仅仅是document
myDiv.dispatchEvent(ev);

下面是下载文件的例子:

// 下载文件
export function download(href, name) {
  const a = document.createElement('a');
  a.href = href;
  a.download = name; // 设置下载文件名

  const e = document.createEvent('MouseEvents');
  e.initEvent('click', false, false);

  a.dispatchEvent(e);
}

你可能感兴趣的:(DOM自定义事件)