谈谈JS的观察者模式(自定义事件)
来源:互联网 发布:ant构建 tomcat源码 编辑:程序博客网 时间:2024/06/05 20:47
观察者模式:
这是一种创建松散耦合代码的技术。它定义对象间 一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。由主体和观察者组成,主体负责发布事件,同时观察者通过订阅这些事件来观察该主体。主体并不知道观察者的任何事情,观察者知道主体并能注册事件的回调函数。
例子:
假如我们正在开发一个商城网站,网站里有header头部、nav导航、消息列表、购物车等模块。这几个模块的渲染有一个共同的前提条件,就是必须先用ajax异步请求获取用户的登录信息。这是很正常的,比如用户的名字和头像要显示在header模块里,而这两个字段都来自用户登录后返回的信息。这个时候,我们就可以把这几个模块的渲染事件都放到一个数组里面,然后待登录成功之后再遍历这个数组并且调用每一个方法。
function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler){ if (typeof this.handlers[type] == "undefined"){ this.handlers[type] = []; } this.handlers[type].push(handler); }, fire: function(event){ if (!event.target){ event.target = this; } if (this.handlers[event.type] instanceof Array){ var handlers = this.handlers[event.type]; for (var i=0, len=handlers.length; i < len; i++){ handlers[i](event); } } }, removeHandler: function(type, handler){ if (this.handlers[type] instanceof Array){ var handlers = this.handlers[type]; for (var i=0, len=handlers.length; i < len; i++){ if (handlers[i] === handler){ break; } } handlers.splice(i, 1); } }};
大概意思就是,创建一个事件管理器。handles是一个存储事件处理函数的对象。
addHandle:是添加事件的方法,该方法接收两个参数,一个是要添加的事件的类型,一个是这个事件的回调函数名。调用的时候会首先遍历handles这个对象,看看这个类型的方法是否已经存在,如果已经存在则添加到该数组,如果不存在则先创建一个数组然后添加。
fire方法:是执行handles这个对象里面的某个类型的每一个方法。
removeHandle:是相应的删除函数的方法。
var Event = { // 通过on接口监听事件eventName // 如果事件eventName被触发,则执行callback回调函数 on: function (eventName, callback) { //我的代码 if(!this.handles){ this.handles={}; } if(!this.handles[eventName]){ this.handles[eventName]=[]; } this.handles[eventName].push(callback); }, // 触发事件 eventName emit: function (eventName) { //你的代码 if(this.handles[arguments[0]]){ for(var i=0;i<this.handles[arguments[0]].length;i++){ this.handles[arguments[0]][i](arguments[1]); } } }};
var person1 = {};var person2 = {};Object.assign(person1, Event);Object.assign(person2, Event);person1.on('call1', function () { console.log('person1');});person2.on('call2', function () { console.log('person2');});person1.emit('call1'); // 输出 'person1'person1.emit('call2'); // 没有输出person2.emit('call1'); // 没有输出person2.emit('call2'); // 输出 'person2'
完整版
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <script src='./mapbox-gl.js'></script><link href='./mapbox-gl.css' rel='stylesheet' /><style>.pageCover { width:100%; height:100%; position:absolute; z-index:10; background-color:#666; opacity:0.5; display:block; }</style></head><body> <button id="button1">butn1</button> <button id="button2">butn2</button> <div class="pageCover"></div></body></html><script> var Event = { _listeners: {}, addEvent: function(type, fn) { if (typeof this._listeners[type] === "undefined") { this._listeners[type] = []; } if (typeof fn === "function") { this._listeners[type].push(fn); } return this; }, fireEvent: function(type) { var arrayEvent = this._listeners[type]; if (arrayEvent instanceof Array) { for (var i=0, length=arrayEvent.length; i<length; i+=1) { if (typeof arrayEvent[i] === "function") { arrayEvent[i]({type: type}); } } } return this; }, removeEvent: function(type, fn) { if (typeof type === "string" && arrayEvent instanceof Array) { if (typeof fn === "function") { for (var i=0, length=this._listeners[type].length; i<length; i+=1){ if (this._listeners[type][i] === fn){ this._listeners[type].splice(i, 1); break; } } } else { delete this._listeners[type]; } } return this; }}; //test // // 添加自定义事件Event.addEvent("alert", fnAlert1 = function() { alert("第一个弹出!");}).addEvent("alert", fnAlert2 = function() { alert("第二个弹出!");});// // 按钮绑定事件,用来清除自定义事件var elButton1 = document.getElementById("button1"), elButton2 = document.getElementById("button2");elButton1.onclick = function() { Event.removeEvent("alert"); alert("alert事件清除成功!"); // 此时后一个按钮卧底了,故隐藏 elButton2.style.display = "none";};elButton2.onclick = function() { Event.removeEvent("alert", fnAlert1); alert("第一个alert清除成功!");};// 点击文档,触发自定义事件document.onclick = function(e) { e = e || window.event; var target = e.target || e.srcElement; // 如果文档点击元素标签名不是input if (!target || !/input|pre/i.test(target.tagName)) { Event.fireEvent("alert"); }};</script>
阅读全文
0 0
- 谈谈JS的观察者模式(自定义事件)
- 谈谈JS的观察者模式(自定义事件)
- 自定义事件(观察者模式)
- js学习心得之js的自定义事件-基于观察者模式的实现
- java事件处理机制(自定义事件)/观察者模式
- 谈谈观察者模式
- 事件机制 -- 典型观察者模式 js实现
- 观察者模式(自定义监听器)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- 观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
- 观察者设计模式(C#委托和事件的使用)
- 告诉你外语学习的真实方法及误区分析(整理)
- 2017年web前端面试题目汇总!
- 【秋天再见】2017秋季回顾--- “图论”“程序员”“红帽”比赛
- 正则表达式,日期 日历
- Machine Learning(4)—Lessons by Andrew Ng
- 谈谈JS的观察者模式(自定义事件)
- unity和HTML通信
- js常用方法使用总结
- 对于常用字符编码格式(ASCII/Unicode/UTF-8)简介
- js简单代码生成器
- SDNU__1082.观妹种菊
- java验证身份证
- webview支持H5中的选择图片方法
- 阈值操作