在 js 和 JQuery 里都可以自定义事件, 在我看来自定义事件的核心就是发布订阅模式的实现所谓的发布订阅模式是 JavaScript 设计模式的一种, 它的核心在于两点: 1. 创造一个事件的共享储存空间 2. 添加 on/off/tirgger 等接口实现挂载移除触发等动作
在 js 和 jQuery 里已经为我们准备好了挂载触发事件的一系列 api, 在 jQuery 里:
- $(element).on(event,handler) // 实现挂载或者叫监听
- $(element).trigger(event) // 触发
- $(element).off(event) // 移除
在 js 中通过 CustomEvent 构造函数来创建一个自定义事件, 通过 addEventListener() 和 dispatchEvent() 这两个 api 来实现事件的发布订阅 dispatchEvent 作用是为节点分派一个合成事件
- var EventCenter = {
- on: function(event, handler) {
- document.addEventListener(event, handler)
- },
- fire: function(event, data) {
- return document.dispatchEvent(new CustomEvent(event, {
- detail: data
- }))
- }
- }
- EventCenter.on('hello',
- function(e) {
- console.log(e.detail)
- }) EventCenter.fire('hello', '你好')
此例中共享的储存空间就是 document 对象
如何不依赖 web api 封装一个发布订阅模式的类呢?
- class PubSubHandler {
- constructor() {
- this.eventPool = {};
- }
- // 移除
- off(topicName) {
- delete this.eventPool[topicName]
- }
- // 发布
- trigger(topicName, ...args) {
- this.eventPool[topicName] && this.eventPool[topicName].forEach(callback = >{
- callback(...args)
- });
- }
- // 订阅
- on(topicName, callback) {
- let topic = this.eventPool[topicName]
- if (!topic) {
- this.eventPool[topicName] = []
- }
- this.eventPool[topicName].push(callback)
- }
- }
来源: http://www.jianshu.com/p/61ac999faaff