首页 > 其他分享 >浏览器端的EventEmitter

浏览器端的EventEmitter

时间:2022-11-26 19:13:37浏览次数:32  
标签:function eventName 浏览器 端的 EventEmitter listener listeners return

  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>

 

标签:function,eventName,浏览器,端的,EventEmitter,listener,listeners,return
From: https://www.cnblogs.com/gdluck/p/16928075.html

相关文章

  • Linux系列---【linux服务器监控和浏览器客户端连接工具-Cockpit】
    linux服务器监控和浏览器客户端连接工具-Cockpit1.Cockpit的用途(1)Cockpit是一个免费且开源的基于web的Linux服务器管理工具。并且在CentOS8和RHEL8中,Cockpit更......
  • 浏览器打印方案
    浏览器打印方案 前言在web端打印是比较常见的需求,实际工作中也接触了不少,在这里对工作中用到的做一下总结1.通过媒体查询隐藏元素通过style标签内联引入,或者使用媒......
  • 浏览器打印方案
    前言在web端打印是比较常见的需求,实际工作中也接触了不少,在这里对工作中用到的做一下总结1.通过媒体查询隐藏元素通过style标签内联引入,或者使用媒体查询media="print"......
  • 浏览器直接修改网站的js代码
    1.按下F12打开控制台,找到源代码,然后是替换2.在本地创建一个文件夹,会提示风险,点击允许3.再找到你要修改的js文件代码,右击选择保存并覆盖这样代码会保存到你刚刚创......
  • 谷歌翻译最新修复(可用谷歌浏览器,idea)
    谷歌翻译突然宣布退出中国,这就给许多用户习惯了在浏览器中使用右键菜单然后选择“翻译成中文”的网页翻译操作带来了不便,因为现在已经无法直接的获得翻译结果了,返回的只能......
  • PHP判断访客是否移动端浏览器访问的四种方法
    在平常工作开发中,我们通常需要开发出PC端和移动端两个不同的系统,从而根据访问端的不同进入到不同的操作界面中。这就需要我们首先要对访问的客户端进行判断是PC端还是移动端......
  • 浏览器上传图片
     asyncuploadImage(e){   let_this=this;   //上传图片并预览   letfile=e.target.files[0];//获取第一个文件   letfileSize=......
  • 检查浏览器类型
    varbrowser={versions:function(){varu=navigator.userAgent,app=navigator.appVersion;return{//移动终端浏览器版本信息trident:u.indexOf('Trident......
  • springboot+vue+element-ui实现前后端的全部校验
    1、前端校验el-form的表单校验<el-form:model="ruleForm"status-icon:rules="rules"ref="ruleForm"label-width="100px"class="demo-ruleForm"><el-form-itemlabel......
  • 浏览器访问url会自动下载图片
    有时候我们会发现,在浏览器地址输入图片链接,浏览器可以直接下载,或者直接展示图片如果指定了Content-Type是image/jpeg,则产生的外链是在浏览器上直接显示如果设置的Conte......