西红柿爱番茄

Feed Rss

delegate事件

04.23.2010, Javascript, by .

这几天在负责帮助中心改版的项目,其中左栏(浏览下面的测试页面)有一个显示隐藏导航的功能,这个跟scrollTab不同了,它只涉及到一个ul显示隐藏,并且还是li的childNodes,所以可以给li添加事件,来触发ul的显示隐藏。

由于公司内使用YUI作为开发的基础库,所以开始的时候也就从YUI的delegate事件来实现功能了:《效果页面》,并且下面的代码有一个优化效果:记录前面点击过的元素,在点击下一个tab的时候隐藏之前点击过的tab。
[javascript]
<script src="http://k.kbcdn.com/global/utilities/utilities_1_4_24.js"></script>
<script>
(function(){
var _E=YK.E,_D=YK.D,tempEl=null;
YK.load(["event-delegate"],function(){
if(_D.inDocument("question-catagroy")){
_E.delegate("question-catagroy","click",function(e,matchEl,root){
if(matchEl.className === "catagroy-title"){
var temp=null;
temp=matchEl.parentNode;
if(!tempEl){
tempEl=_D.getFirstChild(root);
}
//判断是否重复点击了当前tab,从而来切换当前tab的显示隐藏
if(temp == tempEl){
if(temp.className.indexOf("catagroy-active")!=-1){
temp.className=tempEl.className.replace("catagroy-active","");
}else{
temp.className+=" catagroy-active";
}
}else{
tempEl.className=tempEl.className.replace("catagroy-active","");
temp.className+=" catagroy-active";
}
tempEl=temp;
temp=null;
_E.preventDefault(e);
}
},"a");
}
});
})();
</script>
[/javascript]

delegate事件对给列表添加事件有了非常好的优化作用,这样就不需要给每一个li都添加事件,而是在它的父元素添加相关的事件,来监听哪个子元素触发了该事件。

既然delegate事件强大的很,我当然也就会心痒痒的想要自己实现个delegate函数啦,下面是我编写的delega事件函数:
[javascript]
/*
* @author Shanpeng
* @copyright: Shanpeng,All rights reserved.
* @website:http://www.ilovejs.net
* @e-mail:supersha@foxmail/shanpeng@taobao.com/supershafeng@gmail.com
* @QQ:770104121
* @my word:Here,believe what browsers display,and believe yourself
*/
////////////////////// Javascript’s code below ///////////////////////
/*
* @type:event type.
* @fn:handle function,argument[0] is target Element,"this" reference to @elem.
* @elem:the aim DOM Element to add an event(elem || id).
* @subTag: sub DOM Elements’s tagName.
*/
var delegate = (function(){
var $ = function(id){
return typeof id === "string" ? document.getElementById(id) : id;
}
var addListener = function(el, type, fn){
if (el.addEventListener) {
el.addEventListener(type, fn, false);
}
else {
el.attachEvent("on" + type, function(e){
fn.call(el, e);
});
}
return false;
}
return function(type, fn, elem, subTag){
addListener($(elem), type, function(e){
var e = e || window.event;
var el = e.srcElement || e.target;
var nodeName = el.nodeName.toLowerCase();
if (nodeName === subTag) {
fn.call(elem, el);
//if subTag is a "A" element,preventDefault;
if (nodeName === "a") {
try {
e.preventDefault();
}
catch (o) {
e.returnValue = false;
}
}
}
});
}
})();
[/javascript]
上面的delegate函数跟YUI的delegate编写方式一样,只是没有了YUI强大的selector筛选功能而已啦,还有如果需要监听的是A超链接元素,会阻止超链接的默认行为。具体说明在源代码的注释中已有说明,下面就是一个测试页面:《效果页面》。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>