论坛首页 Web前端技术论坛

Prototype修改版本,比jQuery还好用的事件注册器

浏览 5108 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-10-18  
Prototype非常强大,但是jQuery也非常好用,Prototype当然也象jQuery学习了,比如$$的css选择器,可是使用起来依然不是那么方便,并且随着1.60出现,Prototype库越来越大,我有个想法,想在一定程度上修改Prototype,增加一些有用的功能,去掉一些没用的东西,第一个版本,我扩展了事件的注册机制
原本在Prototype里面如果想注册事件,必须这样
$("id").observe("click",function(){alert("hello world")})
注册多个元素一般这样
$$("div img").each(function(node){node.observe("click",function(){alert("hello")})})
相当的麻烦,那我扩展出了$E函数,专门接受特殊事件伪类选择器添加事件处理函数,可以这样用
$E("#id::click")(function(){alert("hello world")});
甚至
$E("#id::click")("alert('hello world')");
怎么样,简单吧,其实就是原来的css选择器文本加"::"伪类标志,加事件名,比如"click",还添加了Chain.bindEvent方法,可以实现一次大量元素添加事件,比如,现在我想给很多元素添加事件,看下面代码
var target={
"#bbb::click":"alert(234);return false",
"#bbb2::mouseover":function(){alert("haha")},
"#bbb3::mouseout":"prompt()",
"input::mouseover":"confirm('eee')"
}
Chain.bindEvent(target)
这样就全搞定了,以后你所要维护的就是页面当中的一个事件参数列表了,甚至这个列表可以象css一样在各个页面当中复用,本修改版是基于1.5.11版本
  • chain.rar (20.8 KB)
  • 描述: Chain 版本0.01
  • 下载次数: 64
   发表时间:2007-10-19  
其实此版本重点就是$E函数的扩展,主要是扩展了事件伪类,毕竟jQuery除了XPath CSS也支持自己独创的比如:odd :even,那我独创个事件伪类,并且这样的代码
$E("div span::mouseover")("this.select('img').invoke('hide')")
$E("div span::mouseout")("this.select('img').invoke('show')")
也非常清晰,并且使用Chain.bindEvent通过对象列表,基本可以实现事件处理函数不用写成inline的形式,并且我还在考虑是否使用1.6 rc1里面的dom:ready进行事件注册,此版本为事件测试版本,大家看看有没有什么bug
0 请登录后投票
   发表时间:2007-10-19  
对于
$E("div span::['mouseover','mouseout','click']")("dosomething()")
这样的语法,多事件同一事件处理函数,以及
$E("div span::['mouseover','mouseout','click']")("test1()","test2()","test3()")
这样的语法,多事件,多事件处理函数,各位网友认为是不是有必要呢?
另外上个例子当中使用的select语法是1.6里面的方法,这个版本里面没有
0 请登录后投票
   发表时间:2007-10-19  
Prototype原来的写法很好啊,而且,就这句来说:
js 代码
 
  1. $$("div img").each(function(node){node.observe("click",function(){alert("hello")})})

有个提高效率的技巧,调用invoke可以避免创建闭包
js 代码
 
  1. $$("div img").invoke("observe","click",handler)  

而且,不知道楼主考虑过没有,如果你修改了添加事件监听的api,那也该提供一个对应的删除事件监听的api吧?


所以,我还是习惯原来的写法。另外现在1.6版还未正式定下来,以后的改变可能会很大,比如类继承的设计,还是先等等再用了。比较期待新的自定义事件的功能:)

倒是对Prototype的迭代方法有点不满,怎么不传入一个处理函数,在第一次循环节点的时候处理每个节点呢?那样就不用循环两次了,所以,我写了个自己的获取某个元素子节点的方法来代替,可以在收集元素的同时对节点做处理,比如添加事件处理函数,可以查某元素的所有子节点、特定标签的子节点、第一个或者最后一个子节点,并在查找过程中处理,提高运行效率:
js 代码
 
  1. var findChild = function(element,option){  
  2.     var element = $(element);  
  3.     var option = Object.extend({tagName:null,position:"all",iterator:null},option);  
  4.     option.tagName = option.tagName ? option.tagName.toLowerCase():null;  
  5.     if(option.position=="all"){  
  6.         var elements = [];  
  7.         if (!(element = element.firstChild)) return elements;  
  8.         if(!option.tagName){  
  9.             while (element){  
  10.                 if(element.nodeType==1){                      
  11.                     (typeof option.iterator != "function") ? null : option.iterator(element = $(element));  
  12.                     elements.push(element);  
  13.                 }  
  14.                 element = element.nextSibling;  
  15.             }                         
  16.         }else{  
  17.             while (element){  
  18.                 if(element.nodeType==1&&element.tagName.toLowerCase()==option.tagName){   
  19.                     (typeof option.iterator != "function") ? null : option.iterator(element = $(element));  
  20.                     elements.push(element);  
  21.                 }  
  22.                 element = element.nextSibling;  
  23.             }  
  24.         }  
  25.         return elements;                  
  26.     }else if(option.position=="last"){  
  27.         if(!(element = element.lastChild)) return null;  
  28.         if(!option.tagName){  
  29.             while (element){  
  30.                 if(element.nodeType==1){                          
  31.                     (typeof option.iterator != "function") ? null : option.iterator(element = $(element));  
  32.                     return element;  
  33.                 }  
  34.                 element = element.previousSibling;  
  35.             }                         
  36.         }else{  
  37.             while (element){  
  38.                 if(element.nodeType==1&&element.tagName.toLowerCase()==option.tagName){                       
  39.                     (typeof option.iterator != "function") ? null : option.iterator(element = $(element));  
  40.                     return element;  
  41.                 }  
  42.                 element = element.previousSibling;  
  43.             }  
  44.         }  
  45.     }else{  
  46.         if (!(element = element.firstChild)) return null;  
  47.         if(!option.tagName){  
  48.             while (element){  
  49.                 if(element.nodeType==1){                          
  50.                     (typeof option.iterator != "function") ? null : option.iterator(element = $(element));  
  51.                     return element;  
  52.                 }  
  53.                 element = element.nextSibling;  
  54.             }                         
  55.         }else{  
  56.             while (element){  
  57.                 if(element.nodeType==1&&element.tagName.toLowerCase()==option.tagName){                       
  58.                     (typeof option.iterator != "function") ? null : option.iterator(element = $(element));  
  59.                     return element;  
  60.                 }  
  61.                 element = element.nextSibling;  
  62.             }  
  63.         }  
  64.     }  
  65. }  

赶时间写的没有做过优化,不过这个思想应该没错,实际使用中能明显看到效率改进。
0 请登录后投票
   发表时间:2007-10-20  
确实是没考虑如何删除事件,但是,这样的写法
$E("#id::click")("alert('hello world')"); 

以及
var target={   
"#bbb::click":"alert(234);return false",   
"#bbb2::mouseover":function(){alert("haha")},   
"#bbb3::mouseout":"prompt()",   
"input::mouseover":"confirm('eee')"  
}   
Chain.bindEvent(target) 

这样的批量注册事件,我看在语法上还是新颖的,删除事件的话,我也想用类似语法,比如
$E("#id::click")(false);

或者类似的
0 请登录后投票
   发表时间:2007-10-20  
1. 1.6 rci基本就是最后版本了,"Barring any heinous bugs, RC1 will be our last release candidate, and you can expect the final version of 1.6.0 to land in early November.
"
2.类继承经过讨论已经按照讨论结果修改了,不会再变动了
3.Hash表从写了,现在都是closure,避免与继承的属性冲突
4.自定义事件必须有namespace
看讨论,基本就是release了,当然我在建议$$最后一个参数支持context,虽然现在有select方法
0 请登录后投票
   发表时间:2008-07-24  
我想知道上面的 Java 代码怎么加上去的,嘿嘿,是不是太菜了??
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics