1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8     <title>Document</title>
  9 </head>
 10 
 11 <body>
 12     <script>
 13         // 浏览器端的EventEmitter
 14         /**
 15          * 采用的发布订阅模式-和vue中的eventBus类似
 16          * 将eventBus作为组件传递数据的桥梁,所有组件公用相同的事件中心,可以向该中心注册发送事件或接收事件,
 17          * 所有组件都可以收到通知,使用起来非常便利,其核心就是发布-订阅模式的落地实现
 18         */
 19         function EventEmitter(params) {
 20             this.__events = {}
 21         }
 22         EventEmitter.VERSION = '1.0.0'
 23         // 实现on方法
 24         EventEmitter.prototype.on = function (eventName, listener) {
 25             if (!eventName || !listener) return
 26             if (!isValidListener(listener)) {
 27                 throw new TypeError('listener must be a function')
 28 
 29             }
 30             var events = this.__events
 31             var listeners = events[eventName] = events[eventName] || []
 32             var listenerIsWrapped = typeof listener === 'object';
 33             // 不添加重复事件,判断是否有一样的
 34             if (indexOf(listeners, listener) === -1) {
 35                 listeners.push(listenerIsWrapped ? listener : {
 36                     listener: listener,
 37                     once: false
 38                 })
 39             }
 40             return this
 41         }
 42         // 判断
 43         function isValidListener(listener) {
 44             if (typeof listener === 'function') {
 45                 return true
 46             } else if (listener && typeof listener === 'object') {
 47                 return isValidListener(listener.listener)
 48             } else {
 49                 return false
 50             }
 51 
 52         }
 53         // 判断新增自定义事件是否存在
 54         function indexOf(array, item) {
 55             var result = -1;
 56             item = typeof item === "object" ? item.listener : item
 57             for (let i = 0; i < array.length; i++) {
 58                 const element = array[i].listener;
 59                 if (element === item) {
 60                     result = i
 61                     break
 62                 }
 63 
 64             }
 65             return result
 66 
 67         }
 68 
 69         EventEmitter.prototype.emit = function (eventName, args) {
 70             // 直接通过内部对象获取自定义事件的回调函数
 71             var listener = this.__events[eventName]
 72             if (!listeners) return
 73             for (let i = 0; i < listeners.length; i++) {
 74                 const element = listeners[i];
 75                 if (listener) {
 76                     listener.listener.apply(this, args || [])
 77                     // 给listener中的once为true的进行特殊处理
 78                     if (listener.once) {
 79                         this.off(eventName, listener.listener)
 80                     }
 81                 }
 82 
 83             }
 84             return this
 85         }
 86         EventEmitter.prototype.off = function (eventName, args) {
 87             var listeners = this.__events[eventName]
 88             if (!listeners) {
 89                 return
 90             }
 91             var index;
 92             for (var i = 0, len = listeners.length; i < len; i++) {
 93                if (listeners[i]&&listeners[i].listener===listener) {
 94                    index=i
 95                    break
 96                }
 97 
 98             }
 99             if (typeof index!=='undefined') {
100                 listeners.splice(index,1,null)
101             }
102             return this
103         }
104         EventEmitter.prototype.once = function (eventName, listener) {
105             // 直接调用on方法,once参数传入true,待执行之后进行once处理
106             return this.on(eventName,{
107                 listener:listener,
108                 once
109             })
110         }
111         EventEmitter.prototype.allOff = function (eventName) {
112             // 如果该eventName存在,则将其对应的listeners的数组直接清空
113             if (eventName&&this.__events[eventName]) {
114                 this.__events[eventName]=[]
115             }else{
116                 this.__events={}
117             }
118         }
119 
120     </script>
121 </body>
122 
123 </html>

 

原文地址:http://www.cnblogs.com/gdluck/p/16928075.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性