JavaScript 给 DOM 元素相同事件绑定多函数

JavaScript 给 DOM 元素相同事件绑定多函数

八月 30, 2013

给 DOM 元素的同一事件绑定多个处理函数

今天,同事问“一个 DOM 元素的同一事件如何绑定多个方法”,为什么这么问,因为在 javascript 中有一个规律,如果某元素的某事件多次赋值,那么只有最后一次赋值生效,如下代码将只弹出”second.”。

1
2
3
4
5
6
document.body.onclick=function(){
alert("first.");
};
document.body.onclick=function(){
alert("second.");
};

说起这个问题,我首先想到的是 jQuery, 它的 bind(type,[data],fn) 方法可以实现同一事件函数叠加的效果,那么, js 如何实现呢?如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 给 DOM 元素的同一事件绑定多个方法
*
* @param {Object} obj DOM 对象
* @param {Object} type 事件类型
* @param {Object} fn 处理函数
*/
function addEventFns(_obj,_type,_fn){
var oldEvent = _obj[_type];
if(typeof _obj[_type] == "function"){
_obj[_type] = function(){
oldEvent();
_fn();
}
}else{
_obj[_type] = _fn;
}
}

在 Dom 节点加载完毕之后这样调用 addEventFns(_obj,_type,_fn)

  • _obj: 需要添加事件的 DOM 对象,比如:document.getElementById(“container”)document.body;
  • _type: 事件类型的字符串,比如:onclickonmouseover;
  • _fn: 绑定到 DOM 元素的事件上面的处理函数。
    1
    2
    3
    addEventFns(obj,"onclick",function(){
    alert("Fired the event.");
    });

项目中用到的一些工具函数

公司 xx 项目就失业子系统变更 coding 告一段落,收获颇多,主要涉及校验,和业务的理解,可谓是循序渐进,环环相扣。coding 过程走火入魔算不上,但出入分明。总结几个常用 javascript 校验,菜鸟级别,仅供参考!

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/**
* 获取两个时间相差月数
*
* @param {Object} start 开始时间 (yyyy-MM)
* @param {Object} end 结束时间 (yyyy-MM)
* @return {TypeName}
*/
function getDiffOfMonth(start,end){
var diff;
if(start==""||end==""){
diff = "";
}
var startArr = start.split('-');
var endArr = end.split('-');
if(startArr[0]==endArr[0]){
diff = endArr[1]-startArr[1];
}else{
diff = (endArr[0]-startArr[0])*12+(endArr[1]-startArr[1]);
}
return Math.abs(diff)+1;
}

/**
* 根据月份区间获取所有月份集合
*
* @param {Object} start 开始时间 (yyyy-MM)
* @param {Object} end 结束时间 (yyyy-MM)
* @return {TypeName}
*/
function getAllMonth(start, end) {
var months = new Array(start);
var month = "";
var length = getDiffOfMonth(start, end);
var start = start.split('-');
var end = end.split('-');
var temp;
for ( var i = 0; i < length - 1; i++) {
temp = new Date(start[0], parseInt(start[1]) + i);
month = new String(temp.getMonth() + 1).length == 1 ? "0"
+ (temp.getMonth() + 1) : (temp.getMonth() + 1);
months.push(temp.getFullYear() + "-" + month);
}
return months;
}

/**
* 获取两个时间相差天数
*
* @param {Object} start 开始时间 (yyyy-MM-dd)
* @param {Object} end 结束时间 (yyyy-MM-dd)
* @return {TypeName}
*/
function getDiffOfDay(start,end){
var diff;
if(start==""||end==""){
diff = "";
}
diff = Math.abs(new Date(start)-new Date(end));
return diff/(1000*3600*24)
}

/**
* 一次性领取失业保险金明细记录唯一性校验
* 判重思路:循环数组各元素,如果在该数组出现两次则重复
* 关键方法:jQuery.inArray(value,array,[fromIndex])
*
* @return {TypeName}
*/
function ycxmxUnique() {
var flag = true;
var length = $("[name='lx']").last().attr("id"); // 最后一条明细的 id
var start = "";
var end = "";
var tempArr = new Array();

// 封装数组
for ( var i = 1; i <= length; i++) {
if (typeof ($("[name='ksny'][id=" + i + "]").val()) == "undefined") {
continue;
}
start = $("[name='jsny'][id=" + i + "]").val();
end = $("[name='ksny'][id=" + i + "]").val();
tempArr = tempArr.concat(getAllMonth(start, end));
}
tempArr.sort();
// 判断重复
for ( var i = 0; i < tempArr.length; i++) {
if (tempArr[i].length == 7
&& jQuery.inArray(tempArr[i], tempArr, i + 1) > -1) {
alert("一次性返回年月有重复,请重新输入!");
flag = false;
break;
}
}
return flag;
}