js自定义事件

1. html如下:

1
2
<div class="test1" lay-filter="data1"></div>
<div class="test2" lay-filter="data2"></div>

2. 创建构造函数InitClass,options参数包含传过来的选择器el,render函数为生成dom,evt函数为绑定的事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function InitClass(options) {
this.options=options;
this.filter=document.querySelector(options.el).getAttribute("lay-filter");
this.render();
}
InitClass.prototype.render=function() {
document.querySelector(this.options.el).innerHTML='<input type="text"><button>获取</button>';
this.evt();
}
InitClass.prototype.evt=function() {
var that=this;
var childs=document.querySelector(this.options.el).children;
childs[1].onclick=function() {
var val=childs[0].value;
// 如果input为空或不是数字,则不返回数据
if(val && !isNaN(val)){
// testModule: 对外暴漏的变量,getNumberInp: 自定义事件名,filter: 不同的dom对象,最后一个参数为回调函数的参数,并且返回的this为当前按钮对象
InitClass.event.call(this, "testModule", 'getNumberInp('+that.filter+')', {
value: Number(val)
});
}
}
}

3. 添加自定义事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 事件存储的变量
InitClass.config={
event: {}
}
InitClass.onevent=function(modName, events, callback) {
if (typeof modName !== 'string' || typeof callback !== 'function') return this;
return InitClass.event(modName, events, null, callback);
}
InitClass.event=function(modName, events, params, fn) {
var that = this
,filter = events.match(/\((.*)\)$/) || [] //提取事件过滤器字符结构,如:select(xxx)
,eventName = (modName + '.' + events).replace(filter[0], '') //获取事件名称,如:form.select
,filterName = filter[1] || ''; //获取过滤器名称,,如:xxx

//添加事件
if (fn) {
InitClass.config.event[eventName] = InitClass.config.event[eventName] || {};
InitClass.config.event[eventName][filterName] = fn;
return this;
}

//执行事件回调
for(var key in InitClass.config.event[eventName]){
//执行指定事件
key === filterName && InitClass.config.event[eventName][key].call(that, params);
}
}

4. 对外暴漏的变量

1
2
3
4
5
6
7
8
var testModule = {
on: function(events, callback) {
return InitClass.onevent.call(this, 'testModule', events, callback);
},
render: function(options) {
new InitClass(options);
}
}

5. 框架使用代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
testModule.render({
el: ".test1"
});
testModule.render({
el: ".test2"
});

testModule.on("getNumberInp(data1)", function(d) {
console.log("第一个对象返回的数据:"+d.value)
})
testModule.on("getNumberInp(data2)", function(d) {
console.log("第二个对象返回的数据:"+d.value)
})

6. 执行结果:


第一个input输入为数字时,点击第一个按钮,结果如下图:

输入非数字,则不执行回调,如下图:

第二个input输入为数字时,点击第二个按钮,结果如下图:

7. 完整js代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<div class="test1" lay-filter="data1"></div>
<div class="test2" lay-filter="data2"></div>

<script>
(function(window) {
function InitClass(options) {
this.options=options;
this.filter=document.querySelector(options.el).getAttribute("lay-filter");
this.render();
}
InitClass.prototype.render=function() {
document.querySelector(this.options.el).innerHTML='<input type="text"><button>获取</button>';
this.evt();
}
InitClass.prototype.evt=function() {
var that=this;
var childs=document.querySelector(this.options.el).children;
childs[1].onclick=function() {
var val=childs[0].value;
if(val && !isNaN(val)){
InitClass.event.call(this, "testModule", 'getNumberInp('+that.filter+')', {
value: Number(val)
});
}
}
}

InitClass.config={
event: {}
}
InitClass.onevent=function(modName, events, callback) {
if (typeof modName !== 'string' || typeof callback !== 'function') return this;
return InitClass.event(modName, events, null, callback);
}
InitClass.event=function(modName, events, params, fn) {
var that = this
,filter = events.match(/\((.*)\)$/) || [] //提取事件过滤器字符结构,如:select(xxx)
,eventName = (modName + '.' + events).replace(filter[0], '') //获取事件名称,如:form.select
,filterName = filter[1] || ''; //获取过滤器名称,,如:xxx

//添加事件
if (fn) {
InitClass.config.event[eventName] = InitClass.config.event[eventName] || {};
InitClass.config.event[eventName][filterName] = fn;
return this;
}

//执行事件回调
for(var key in InitClass.config.event[eventName]){
//执行指定事件
key === filterName && InitClass.config.event[eventName][key].call(that, params);
}
}

var testModule = {
on: function(events, callback) {
return InitClass.onevent.call(this, 'testModule', events, callback);
},
render: function(options) {
new InitClass(options);
}
}
window.testModule=testModule;
})(window)

// 使用
testModule.render({
el: ".test1"
});
testModule.render({
el: ".test2"
});


testModule.on("getNumberInp(data1)", function(d) {
console.log("第一个对象返回的数据:"+d.value)
})
testModule.on("getNumberInp(data2)", function(d) {
console.log("第二个对象返回的数据:"+d.value)
})
</script>