高级功能:很有用的javascript自定义事件
之前写了篇文章《原生javascript实现类似jquery on方法的行为监听》比较浅显,能够简单的使用场景。
这里的自定义事件指的是区别javascript默认的与DOM交互的事件,比如click,mouseover,change等,有时候我们需要监听某一行为是否发生,很显然默认的行为不够用,比如一个场景。我们写好了tab切换,点击后请求加载隐藏标签的内容。
tab切换是非常常用的一个功能,通常会写成组件,如果每次把请求写在组件里肯定对组件拓展和耦合性有影响。这时候我们可以在组件里自定义一个事件广播,在其他地方监听这个广播再执行请求就可以避免了。
以上只是使用场景,下面是具体实现:
1、简易代码,基础功能:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义事件</title>
</head>
<body>
<button id="demo">点我吧</button>
<script type="text/javascript">
function Observer(){
this._events={};
}
Observer.prototype={
on:function(eName,fn,scope){
eName=eName.toLowerCase();
this._events[eName]=[];
this._events[eName].push({fn:fn||null,scope:scope||null});
},
fireEvent:function(){
var args=Array.prototype.slice.call(arguments);//将参数转为数组
var eName=args.shift().toLowerCase();
var list=this._events[eName];
for(var i=0;i<list.length;i++){
var dict=list[i];
var fn=dict.fn;
var scope=dict.scope;
fn.apply(scope||null,args);//注册事件执行
}
}
}
var listener=new Observer();
listener.on("alert",function(name ,age){
console.log(name+":"+age);
});
listener.on("aha",function(name ,age){
console.log("这是另外一个事件"+name+":"+age);
});
var $btn=document.getElementById("demo")
$btn.onclick=function(){
listener.fireEvent('aha', '彼岸花再开', 28);
}
</script>
</body>
</html>
有点类似jquery里面的on方法,$(ele).on(type,fn)。上面的on是注册一个事件,这个事件是一个对象,存储当前的事件名称和函数。fireEvent可以理解为释放,发射,监听事件。
完整的实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义事件</title>
</head>
<body>
<button id="demo">点我吧</button>
<script type="text/javascript">
function Observer() {
this._events = {};
}
Observer.prototype = {
constructor: this,
addEvent: function(eName, fn) {
if (typeof(eName) === "string" && typeof(fn) === "function") {
eName = eName.toLowerCase();
if (typeof(this._events[eName]) === "undefined") {
this._events[eName] = [fn];
} else {
this._events[eName].push(fn);
}
}
return this;
},
addEvents: function(obj) { //绑定多事件
obj = typeof(obj) === "object" ? obj : {};
for (var eName in obj) {
if (eName && typeof(obj[eName] === "function")) {
this.addEvent(eName, obj[eName]);
}
}
return this;
},
fireEvent: function(eName) { //触发事件
if (eName && this._events[eName]) {
var events = {
eName: eName,
target: this
}; for (var length = this._events[eName].length, start = 0; start < length; start++) {
this._events[eName][start].call(this, events);
}
}
return this;
},
fireEvents: function(array) {
if (array instanceof Array) {
for (var i = 0, len = array.length; i < len; i++) {
this.fireEvent(array[i]);
}
}
return this;
},
removeEvent: function(eName, key) { //删除绑定的事件
var eventsList = this._events[eName];
if (eventsList instanceof Array) {
if (typeof(key) === "function") {
for (var i = 0, len = eventsList.length; i < len; i++) {
if (eventsList[i] === key) {//移除其中某个事件
eventsList.splice(i, 1);
break;
}
}
} else if (key instanceof Array) {//移除某个事件下面多个函数
for (var lis = 0, lenkey = key.length; lis < lenkey; lis += 1) {
this.removeEvent(type, key[lenkey]);
}
} else {//直接移除事件下所有函数
delete this._events[eName];
}
}
return this;
},
removeEvents: function(params) {
if (params instanceof Array) {
for (var i = 0, length = params.length; i < length; i += 1) {
this.removeEvent(params[i]);
}
} else if (typeof params === "object") {
for (var type in params) {
this.removeEvent(type, params[type]);
}
}
return this;
}
}
var listeners = new Observer();
listeners.addEvents({
"once": function() {
alert("该事件只会出现一次!");
this.removeEvent("once");
},
"infinity": function() {
alert("每次点击页面,该事件都会!");
}
});
document.onclick = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
if (!target || !/button/i.test(target.tagName)) {
listeners.fireEvents(["once", "infinity"]);
}
};
</script>
</body>
</html>
换apply实现,细心的你是否发现其中的差别呢:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义事件</title>
</head>
<body>
<button id="demo">点我吧</button>
<script type="text/javascript">
function Observer() {
this._events = {};//存储事件对象
}
Observer.prototype = {
constructor: this,
addEvent: function(eName, fn) {//绑定事件
if (typeof(eName) === "string" && typeof(fn) === "function") {
eName = eName.toLowerCase();
if (typeof(this._events[eName]) === "undefined") {
this._events[eName] = [{//将事件函数绑定到事件名称
fn: fn
}];
} else {
this._events[eName].push({
fn: fn
});
}
}
return this;
},
addEvents: function(obj) { //绑定多事件
obj = typeof(obj) === "object" ? obj : {};
for (var eName in obj) {
if (eName && typeof(obj[eName] === "function")) {
this.addEvent(eName, obj[eName]);
}
}
return this;
},
fireEvent: function(eName) {//广播事件,射吧!
var args = Array.prototype.slice.call(arguments);//将参数转为数组
var eName = args.shift().toLowerCase();//第一个参数是事件名,这里需要除时间名之外的参数
var list = this._events[eName];
if(list instanceof Array){
for (var i = 0; i < list.length; i++) {
var dict = list[i];
var fn = dict.fn;
fn.apply(null, args);
}
}
return this;
},
fireEvents: function(array) {
if (array instanceof Array) {
for (var i = 0, len = array.length; i < len; i++) {
this.fireEvent(array[i]);
}
}
return this;
},
removeEvent: function(eName, key) {
var eventsList = this._events[eName];
if (eventsList instanceof Array) {
if (typeof(key) === "function") {
for (var i = 0, len = eventsList.length; i < len; i++) {
if (eventsList[i] === key) {
eventsList.splice(i, 1);
break;
}
}
} else if (key instanceof Array) {
for (var lis = 0, lenkey = key.length; lis < lenkey; lis += 1) {
this.removeEvent(type, key[lenkey]);
}
}else{
delete this._events[eName];
}
}
}
}
var listeners = new Observer();
listeners.addEvents({
"once": function() {
alert("该事件只会出现一次!");
listeners.removeEvent("once");
},
"infinity": function() {
alert("每次点击页面,该事件都会出现!");
}
}); document.onclick = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
if (!target || !/input|pre/i.test(target.tagName)) {
listeners.fireEvents(["once", "infinity"]);
}
};
</script>
</body>
</html>
高级功能:很有用的javascript自定义事件的更多相关文章
- Javascript自定义事件功能与用法实例分析
原文地址:https://www.jb51.net/article/127776.htm 本文实例讲述了javascript自定义事件功能与用法.分享给大家供大家参考,具体如下: 概述 自定义事件很难 ...
- 19个很有用的 JavaScript库推荐
流行的 JavaScript 库有jQuery,MooTools,Prototype,Dojo和YUI等,这些 JavaScript 库功能丰富,加上它们众多的插件,几乎能实现任何你需要的功能 然而需 ...
- Javascript事件模型系列(四)我所理解的javascript自定义事件
被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁了一 ...
- 理解的javascript自定义事件
理解的javascript自定义事件 被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情, ...
- 100多个很有用的JavaScript函数以及基础写法大集合
100多个很有用的JavaScript函数以及基础写法大集合 1.document.write("");为 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:docume ...
- javascript:自定义事件初探
javascript:自定义事件初探 http://www.cnblogs.com/jeffwongishandsome/archive/2008/10/27/1317148.html
- javascript 自定义事件 发布-订阅 模式 Event
* javascript自定义事件 var myEvent = document.createEvent("Event"); myEvent.initEvent("myE ...
- JavaScript自定义事件
很多DOM对象都有原生的事件支持,向div就有click.mouseover等事件,事件机制可以为类的设计带来很大的灵活性,相信.net程序员深有体会.随着web技术发展,使用JavaScript自定 ...
- Javascript 自定义事件 (custom event)
Javascript 中经常会用到自定义事件.如何创建一个简单的自定义事件呢?在创建自定义的事件之前,我们应该考虑一下和事件有关的东西.例如 click 事件,首先我们要能注册一个click事件(在一 ...
随机推荐
- jQuery Validation Plugin
使用方式很简单,简单测试代码如下: <html> <head> <script type="text/javascript" src="./ ...
- 2018新年 flag 了解一下(每月初更新...)
昨天(2018/3/2)是元宵节,这很恐怖,因为意味着 往后再也找不到这么冠冕堂皇的理由用来偷懒啦~ 嘤嘤嘤~ (我特么反手就是一拳,让你嘤嘤嘤) emm,跑题了. 正文 话说一日之计在于晨,一年之计 ...
- leetcode-917-仅仅反转字母
题目描述: 给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转. 示例 1: 输入:"ab-cd" 输出:"dc-b ...
- 点击按钮,生成一组一组combobox和slider时,避免控件Id相同,导致控件冲突的方法
如下效果图,点击一次添加按钮,动态生成一组combobox和slider.由于easyUI的下拉框和滑块使用相同的控件id,通过JS生成控件,如果两个id一样就会造成冲突,例如点击第一组的下拉框,第二 ...
- .Net Core Nuget还原失败
项目获取后发现所有项目的依赖项全部报黄.. 展开发现所有的Nuget包都没有引用.. 按错误窗口的提示使用解决方案上"Nuget包还原"来解决却没有任何进展.. 错误窗口报文 找不 ...
- (转)Mysql技术内幕InnoDB存储引擎-事务&备份&性能调优
事务 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC ...
- (转)教你手工mysql拆库
原文:http://www.cnblogs.com/cchust/p/3859967.html 互联网网站应用大多采用mysql作为DB存储,限于mysql单机性能的瓶颈,为了支撑更大容量和更大的访问 ...
- puppet的使用:puppet配置文件介绍
配置文件的产生 Puppet安装完后,配置文件就产生了,名称为puppet.conf,一般在/etc/puppet路径下. master也可以通过命令: puppet master --genconf ...
- 《Android应用性能优化》2——内存、CPU、性能测评
4.高效使用内存 4.1 说说内存 Android设备的性能主要取决于以下三因素: CPU如何操纵特定的数据类型: 数据和指令需占用多少存储空间: 数据在内存中的布局 4.2 数据类型 int和lon ...
- Fiddler Web Debugger的下载和安装(图文详解)
不多说,直接上干货! Fiddler是一个http协议调试代理工具,它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析请求数据.设置断点.调试web应用.修改请求的数据 ...