十个最常用的JavaScript自定义函数

JavaScript自定义函数在平时的开发过程中比较实用,这里介绍的是个最常用的十个JavaScript自定义函数主要涉及添加事件与移除事件等等。

(10)addEvent

网上最流行的版本是Scott Andrew的,据说javascript界曾举行一场比赛(此事件我们可以在Pro Javascript Techniques100页看到)或浏览PPK的网站,征求添加事件与移除事件的函数,他就是其获奖者。下面就是他的实现:

1.  function addEvent(elm, evType, fn, useCapture) {   
2.    if (elm.addEventListener) {   
3.      elm.addEventListener(evType, fn, useCapture);//DOM2.0   
4.      return true;   
5.    }   
6.    else if (elm.attachEvent) {   
7.      var r = elm.attachEvent('on' + evType, fn);//IE5+   
8.      return r;   
9.    }   
10.   else {   
11.     elm['on' + evType] = fn;//DOM 0   
12.   }   
13. } 

下面是Dean Edwards的版本

1.  // addEvent/removeEvent written by Dean Edwards, 2005   
2.  // with input from Tino Zijdel   
3.  // http://dean.edwards.name/weblog/2005/10/add-event/   
4.  function addEvent(element, type, handler) {   
5.      //为每一个事件处理函数分派一个唯一的ID   
6.      if (!handler.$$guid) handler.$$guid = addEvent.guid++;   
7.      //为元素的事件类型创建一个哈希表   
8.      if (!element.events) element.events = {};   
9.      //为每一个"元素/事件"对创建一个事件处理程序的哈希表   
10.     var handlers = element.events[type];   
11.     if (!handlers) {   
12.         handlers = element.events[type] = {};   
13.         //存储存在的事件处理函数(如果有)   
14.         if (element["on" + type]) {   
15.             handlers[0] = element["on" + type];   
16.         }   
17.     }   
18.     //将事件处理函数存入哈希表   
19.     handlers[handler.$$guid] = handler;   
20.     //指派一个全局的事件处理函数来做所有的工作   
21.     element["on" + type] = handleEvent;   
22. };   
23. //用来创建唯一的ID的计数器   
24. addEvent.guid = 1;   
25. function removeEvent(element, type, handler) {   
26.     //从哈希表中删除事件处理函数   
27.     if (element.events && element.events[type]) {   
28.         delete element.events[type][handler.$$guid];   
29.     }   
30. };   
31. function handleEvent(event) {   
32.     var returnValue = true;   
33.     //抓获事件对象(IE使用全局事件对象)   
34.     event = event || fixEvent(window.event);   
35.     //取得事件处理函数的哈希表的引用   
36.     var handlers = this.events[event.type];   
37.     //执行每一个处理函数   
38.     for (var i in handlers) {   
39.        this.$$handleEvent = handlers[i];   
40.         if (this.$$handleEvent(event) === false) {   
41.            returnValue = false;   
42.         }     }   
43.     return returnValue;   
44. };   
45. //为IE的事件对象添加一些“缺失的”函数   
46. function fixEvent(event) {   
47.     //添加标准的W3C方法   
48.     event.preventDefault = fixEvent.preventDefault;   
49.     event.stopPropagation = fixEvent.stopPropagation;   
50.     return event;   
51. };   
52. fixEvent.preventDefault = function() {   
53.     this.returnValue = false;   
54. };   
55. fixEvent.stopPropagation = function() {   
56.     this.cancelBubble = true;   
57. }; 

功能非常强悍,解决IEthis指向问题,event总是作为第一个参数传入,跨浏览器就更不在话下。

另,我还珍藏了一个HTML5工作组的版本:

1.  var addEvent=(function(){   
2.      if(document.addEventListener){   
3.          return function(el,type,fn){   
4.              if(el.length){   
5.                  for(var i=0;i  
6.                      addEvent(el[i],type,fn);   
7.                  }   
8.              }else{   
9.                  el.addEventListener(type,fn,false);   
10.             }   
11.         };   
12.     }else{   
13.         return function(el,type,fn){   
14.             if(el.length){   
15.                 for(var i=0;i  
16.                     addEvent(el[i],type,fn);   
17.                 }   
18.             }else{   
19.                 el.attachEvent('on'+type,function(){   
20.                     return fn.call(el,window.event);   
21.                 });   
22.             }   
23.         };   
24.     }   
25. })(); 

9addLoadEvent()

我以前讨论过这函数,不细说,就是慢了一点,各大类库基本无视它,自行实现domReady版本。下面是Simon Willison的实现:

1.  var addLoadEvent = function(fn) {   
2.    var oldonload = window.onload;   
3.    if (typeof window.onload != 'function') {   
4.      window.onload = fn;   
5.    }else {   
6.      window.onload = function() {   
7.        oldonload();   
8.        fn();   
9.      }   
10.   }   
11. } 

8 getElementsByClass()

我有收集癖,手头上拥有许多版本,最后集思广益自己实现了一个。下面是我的实现:

1.  var getElementsByClassName = function (searchClass, node,tag) {   
2.      if(document.getElementsByClassName){   
3.          return  document.getElementsByClassName(searchClass)   
4.      }else{   
5.          node = node || document;   
6.          tag = tag || "*";   
7.          var classes = searchClass.split(" "),   
8.          elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag),   
9.          patterns = [],   
10.         returnElements = [],   
11.         current,   
12.         match;   
13.         var i = classes.length;   
14.         while(--i >= 0){   
15.             patterns.push(new RegExp("(^|\\s)" + classes[i] + "(\\s|$)"));   
16.         }   
17.         var j = elements.length;   
18.         while(--j >= 0){   
19.             current = elements[j];   
20.             match = false;   
21.             for(var k=0, kl=patterns.length; k  
22.                 match = patterns[k].test(current.className);   
23.                 if (!match)  break;   
24.             }   
25.             if (match)  returnElements.push(current);   
26.         }   
27.         return returnElements;   
28.     }   
29. } 

7cssQuery()

别名为getElementsBySeletor,由Dean Edwards最先实现,Prototype.jsJQuery等类库都有相应实现,其中JQuery把它整合到$()选择器中,名声盖过其前辈。不过IE8等新锐浏览器已经实现querySelectorquerySelectorAll方法,待到IE6IE7报废之日,它就无用了。无忧里有它的实现原理讲解。由于太长,就不粘出来了,具体可到原作者网站看看。

6toggle()

用来显示或隐藏一个DOM元素。

1.  function toggle(obj) {   
2.      var el = document.getElementById(obj);   
3.      if ( el.style.display != 'none' ) {   
4.          el.style.display = 'none';   
5.      }   
6.      else {   
7.          el.style.display = '';   
8.      }   
9.  } 

5insertAfter()

DOM只提供了insertBefore,我们很有必要自己实现insertAfter。不过我认为 insertAdjacentElement是更好的选择,现在除了火狐其他浏览器都实现这个方法。下面是JeremyKeith的版本:

1.  function insertAfter(parent, node, referenceNode) {   
2.      parent.insertBefore(node, referenceNode.nextSibling);   
3.  } 

4inArray()

用于判断检查数组中是否存在某个值,下面方法取自Prototype类库。

1.  Array.prototype.inArray = function (value) {   
2.      for (var i=0,l = this.length ; i   
3.          if (this[i] === value) {   
4.              return true;   
5.          }   
6.      }   
7.      return false;   
8.  }; 

(3)getCookie(), setCookie(), deleteCookie()

BBS与商业网站的应该经常用到,无理由每次都要让用户输入密码登录吧。我们需要借助cookie实现自动登录功能。

1.  function getCookie( name ) {   
2.      var start = document.cookie.indexOf( name + "=" );   
3.      var len = start + name.length + 1;   
4.      if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {   
5.          return null;   
6.      }   
7.      if ( start == -1 ) return null;   
8.      var end = document.cookie.indexOf( ';', len );   
9.      if ( end == -1 ) end = document.cookie.length;   
10.     return unescape( document.cookie.substring( len, end ) );   
11. }   
12. function setCookie( name, value, expires, path, domain, secure ) {   
13.     var today = new Date();   
14.     today.setTime( today.getTime() );   
15.     if ( expires ) {   
16.         expires = expires * 1000 * 60 * 60 * 24;   
17.     }   
18.     var expires_date = new Date( today.getTime() + (expires) );   
19.     document.cookie = name+'='+escape( value ) +   
20.         ( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()   
21.         ( ( path ) ? ';path=' + path : '' ) +   
22.         ( ( domain ) ? ';domain=' + domain : '' ) +   
23.         ( ( secure ) ? ';secure' : '' );   
24. }   
25. function deleteCookie( name, path, domain ) {   
26.     if ( getCookie( name ) ) document.cookie = name + '=' +   
27.             ( ( path ) ? ';path=' + path : '') +   
28.             ( ( domain ) ? ';domain=' + domain : '' ) +   
29.             ';expires=Thu, 01-Jan-1970 00:00:01 GMT';   
30. } 

2getStyle()setStyle()

所有UI控件都应该存在的函数,动态设置样式与获取样式。这个可以写得很短,也可以写得很长,但要精确取得样式,一个字:难!但我发现许多问题都是发端于IE,微软的开发人员好像从来不打算给出getComputedStyle这样的函数,与之相近的currentStyle会返回autoinhert ' '等让你哭笑不得的值,这还没有算上IE怪癖模式带来的难度呢!各类库的实现是非常长与难分离出来的,下面是我实现的版本:

1.  function setStyle(el,prop,value){   
2.     if(prop == "opacity" && !+"\v1"){   
3.       //IE7 bug:filter 滤镜要求 hasLayout=true 方可执行(否则没有效果)   
4.       if (!el.currentStyle || !el.currentStyle.hasLayout) el.style.zoom = 1;   
5.       prop = "filter";   
6.       if(!!window.XDomainRequest){   
7.         value ="progid:DXImageTransform.Microsoft.Alpha(style=0,opacity="+value*100+")";   
8.       }else{   
9.         value ="alpha(opacity="+value*100+")" 
10.      }   
11.    }   
12.    el.style.cssText += ';' + (prop+":"+value);   
13.  }   
14.  function getStyle(el, style){   
15.    if(!+"\v1"){   
16.      style = style.replace(/\-(\w)/g, function(all, letter){   
17.        return letter.toUpperCase();   
18.      });   
19.      return el.currentStyle[style];   
20.    }else{   
21.      return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)   
22.    }   
23.  } 

有关setStyle还可以看我另一篇博文,毕竟现在设置的样式都是内联样式,与html混杂在一起。

1$()

实至名归,最值钱的函数,可以节省多少流量啊。最先由Prototype.js实现的,那个洪荒时代遗留下来的珍兽,现在有许多变种。

1.  function $() {   
2.      var elements = [];   
3.      for (var i = 0; i < arguments.length; i++) {   
4.          var element = arguments[i];   
5.          if (typeof element == 'string')   
6.              element = document.getElementById(element);   
7.          if (arguments.length == 1)   
8.              return element;   
9.          elements.push(element);   
10.     }   
11.     return elements;   
12. } 


本文来自司徒正美博客园文章《javascript十个最常用的自定义函数

http://developer.51cto.com/art/200909/149248.htm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值