JavaScript事件代理(委托)一般用于以下情况:
1. 事件注册在祖先级元素上,代理其子级元素。可以减少事件注册数量,节约内存开销,提高性能。
之前一直用各种js库的事件代理,如 jQuery,非常方便实用。今天尝试用原生 js 实现该功能。
rush:js;">
var addEvent = (function () {
if (document.addEventListener) {
return function (element,type,handler) {
element.addEventListener(type,handler,false);
};
} else if (document.attachEvent) {
return function (element,handler) {
element.attachEvent('on' + type,function () {
handler.apply(element,arguments);
});
};
} else {
return function (element,handler) {
element['on' + type] = function () {
return handler.apply(element,arguments);
};
};
}
})(),getClassElements = function (parentElement,classname) {
var all,element,classArr = [],classElements = [];
if (parentElement.getElementsByClassName) {
return parentElement.getElementsByClassName(classname);
} else {
all = parentElement.getElementsByTagName('*');
for (var i = 0,len = all.length; i < len; i++) {
element = all[i];
classArr = element && element.className && element.className.split(' ');
if (classArr) {
for (var j = 0; j < classArr.length; j++) {
if (classArr[j] === classname) {
classElements.push(element);
}
}
}
}
return classElements;
}
},delegate = function () { // 参数:element,[selector,] handler
var args = arguments,element = args[0],type = args[1],handler;
if (args.length === 3) {
handler = args[2];
return addEvent(element,handler);
}
if (args.length === 4) {
selector = args[2];
handler = args[3];
return addEvent(element,function (event) {
var event = event || window.event,target = event.target || event.srcElement,quickExpr = /^(?:[a-zA-Z]*#([\w-]+)|(\w+)|[a-zA-Z]*\.([\w-]+))$/,match,idElement,elements,tagName,count = 0,len;
if (typeof selector === 'string') {
match = quickExpr.exec(selector);
if (match) {
// #ID selector
if (match[1]) {
idElement = document.getElementById(match[1]);
tagName = match[0].slice(0,match[0].indexOf('#'));
// tag selector
} else if (match[2]) {
elements = element.getElementsByTagName(selector);
// .class selector
} else if (match[3]) {
elements = getClassElements(element,match[3]);
tagName = match[0].slice(0,match[0].indexOf('.'));
}
}
if (idElement) {
if ( tagName ? tagName === idElement.nodeName.toLowerCase() && target === idElement : target === idElement ) {
return handler.apply(idElement,arguments);
}
} else if (elements) {
for (len = elements.length; count < len; count++) {
if ( tagName ? tagName === elements[count].nodeName.toLowerCase() && target === elements[count] : target === elements[count] ) {
return handler.apply(elements[count],arguments);
}
}
}
}
});
}
};
主要是用 apply 改变 this 的指向
rush:js;">
handler.apply(idElement,arguments);
handler.apply(elements[count],arguments);
测试一下:
rush:css;">