js 自定义事件观察者模式(发布/订阅)
/*
* 示例:
* Event.create("namespace1").listen('click', function(a){
* console.log(a);
* });
* Event.create("namespace1").trigger("click", 1);
*/
window.myEvent = (function() {
var global = this,
Event,
_default = 'default'; Event = function() {
var _listen,
_trigger,
_remove,
_slice = Array.prototype.slice,
_shift = Array.prototype.shift,
_unshift = Array.prototype.unshift,
namespaceCache = [],
_create,
find,
each = function( ary, fn) {
var ret;
for(var i = 0, l = ary.length; i < l; i++) {
var n = ary[i];
ret = fn.call(n, i, n);
}
return ret;
};
// 订阅
_listen = function(key, fn, cache) {
if(!cache[key]) {
cache[key] = [];
}
cache[key].push(fn);
};
// 移除订阅
_remove = function(key, cache, fn) {
if(cache[key]) {
if(fn) {
for(var i = cache[key].length; i >=0; i++) {
if(cache[key][i] === fn) {
cache[key].splice(i, 1);
}
}
}else {
cache[key] = [];
}
}
};
// 发布
_trigger = function() {
var cache = _shift.call(arguments),
key = _shift.call(arguments),
args = arguments,
_self = this,
ret,
stack = cache[key];
if(!stack || !stack.length) {
return;
}
return each(stack, function() {
return this.apply(_self, args);
});
};
// 创建命名空间
_create = function(namespace) {
var namespace = namespace || _default;
var cache = {},
offlineStack = [], // 离线事件
ret = {
listen: function (key, fn, last) {
_listen(key, fn, cache);
if (offlineStack == null) {
return;
}
if (last === 'last') {
offlineStack.length && offlineStack.pop()();
} else {
each(offlineStack, function () {
this();
});
}
offlineStack = null;
}, one: function (key, fn, last) {
_remove(key, cache);
this.listen(key, fn, last);
}, remove: function(key, fn, last) {
_remove(key, cache, fn);
}, trigger: function() {
var fn,
args,
_self = this;
_unshift.call(arguments, cache);
args = arguments;
fn = function() {
return _trigger.apply(_self, args);
};
if(offlineStack) {
return offlineStack.push(fn);
}
return fn();
}
}; return namespace ? (namespaceCache[namespace] ? namespaceCache[namespace] : namespaceCache[namespace] = ret) : ret;
}; return {
create: _create,
one: function(key, fn, last) {
var event = this.create();
event.one(key, fn, last);
},
remove: function(key, fn) {
var event = this.create();
event.remove(key, fn);
},
listen: function(key, fn, last) {
var event = this.create();
event.listen(key, fn, last);
},
trigger: function() {
var event = this.create();
event.trigger.apply(this, arguments);
}
};
}();
return Event;
})();
js 自定义事件观察者模式(发布/订阅)的更多相关文章
- Jquery 自定义事件实现发布/订阅
//用户点击logoff按钮时,广播一个自定义事件,给任何需要保存状态的感兴趣的观察者,然后导航到logoff页面 $('#logoff').click(function(){ $.event.tri ...
- javaScript 自定义事件、发布订阅设计模式
现在很多应用都允许用户根据自己的喜好订阅一些自己较为关注的信息,当应用更新了这些信息后将针对不同的订阅类型推送此类信息.例如xx招聘网,当你订阅了互联网IT技术相关分类的招聘信息推送后,当企业在该网站 ...
- js自定义事件、DOM/伪DOM自定义事件
一.说明.引言 我JS还是比较薄弱的,本文的内容属于边学边想边折腾的碎碎念,可能没什么条理,可能有表述不准确的地方,可能内容比较拗口生僻.如果您时间紧迫,或者JS造诣已深,至此您就可以点击右侧广告(木 ...
- 漫谈js自定义事件、DOM/伪DOM自定义事件
一.说明.引言 我JS还是比较薄弱的,本文的内容属于边学边想边折腾的碎碎念,可能没什么条理,可能有表述不准确的地方,可能内容比较拗口生僻.如果您时间紧迫,或者JS造诣已深,至此您就可以点击右侧广告(木 ...
- js 自定义事件 包含 添加、激活、销毁
1.思路 (1)构思 var eventTarget = { addEvent: function(){ //添加事件 }, fireEvent: function(){ //触发事件 }, remo ...
- C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命
使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...
- SpringBoot事件监听机制及观察者模式/发布订阅模式
目录 本篇要点 什么是观察者模式? 发布订阅模式是什么? Spring事件监听机制概述 SpringBoot事件监听 定义注册事件 注解方式 @EventListener定义监听器 实现Applica ...
- JS中什么是发布--订阅模式?
转载文章部分内容: 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. ...
- js自定义事件
自定义事件的本质,创建一个对象,然后把事件的名字作为对象的一个属性,然后value是一个[],把此事件的所以回调都push进去. 写一个很基本的,没有把对象暴露出去的js的自定义事件. var eve ...
随机推荐
- Codeforces Round #427 (Div. 2)—A,B,C,D题
A. Key races 题目链接:http://codeforces.com/contest/835/problem/A 题目意思:两个比赛打字,每个人有两个参数v和t,v秒表示他打每个字需要多久时 ...
- idea破解方法
1.http://idea.lanyus.com/ 下载破解文件 2.将下载的JetbrainsIdesCrack-3.4-release-enc.jar破解文件放在idea安装目录下的bin中: 3 ...
- jumpserver(0.3.2版本)开源跳板机系统部署
1. 介绍 JumpServer亮点: 集成Ansible,批量执行命令: 支持WebTerminal wiki地址:https://github.com/jumpserver/jumpserver/ ...
- nginx.conf常用配置解析
一.全局配置 user username groupname 运行用户及用户组 worker_processes auto 启动进程,通常设置成和cpu数量相等的一个数值,默认为1.可以设置为auto ...
- 安装python3 centos
1.在新centos中安装python3的步骤https://www.cnblogs.com/lclq/archive/2016/06/27/5620196.html 2.安装python3过程中报错 ...
- 项目中遇到的问题, ftp等
1:ftp 上传文件时的权限问题,需要将上传主目录下的文件权限设置为,这样用户就具有上传,操作,删除等权限 chmod 777 2: 当访问ftp时,出现以下提示.说明需要用户名和密码,这是在ft ...
- boost 智能指针intrusive_ptr
boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intru ...
- javascript 中的 parameter vs arguments
像往常一样简单粗暴地看码: A parameter is the variable which is part of the method’s signature (method declaratio ...
- windows计划任务定时运行synctoy的坑
每次设置好synctoy之后,需要让synctoy运行一次,windows的计划任务才能成功执行,如果变更了synctoy的设置,而没有让synctoy成功执行过,windows计划任务将执行失败,坑 ...
- IOS系统推送原理
IOS推送大致原理如下图 1.Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Provider可以理解为服务端[消息的发起者]): 2. ...