javascript 最常用的10个自定义函数[推荐]


Posted in Javascript onDecember 26, 2009

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

function addEvent(elm, evType, fn, useCapture) { 
if (elm.addEventListener) { 
elm.addEventListener(evType, fn, useCapture);//DOM2.0 
return true; 
} 
else if (elm.attachEvent) { 
var r = elm.attachEvent('on' + evType, fn);//IE5+ 
return r; 
} 
else { 
elm['on' + evType] = fn;//DOM 0 
} 
}

下面是Dean Edwards 的版本
// addEvent/removeEvent written by Dean Edwards, 2005 
// with input from Tino Zijdel 
// http://dean.edwards.name/weblog/2005/10/add-event/ 
function addEvent(element, type, handler) { 
//为每一个事件处理函数分派一个唯一的ID 
if (!handler.$$guid) handler.$$guid = addEvent.guid++; 
//为元素的事件类型创建一个哈希表 
if (!element.events) element.events = {}; 
//为每一个"元素/事件"对创建一个事件处理程序的哈希表 
var handlers = element.events[type]; 
if (!handlers) { 
handlers = element.events[type] = {}; 
//存储存在的事件处理函数(如果有) 
if (element["on" + type]) { 
handlers[0] = element["on" + type]; 
} 
} 
//将事件处理函数存入哈希表 
handlers[handler.$$guid] = handler; 
//指派一个全局的事件处理函数来做所有的工作 
element["on" + type] = handleEvent; 
}; 
//用来创建唯一的ID的计数器 
addEvent.guid = 1; 
function removeEvent(element, type, handler) { 
//从哈希表中删除事件处理函数 
if (element.events && element.events[type]) { 
delete element.events[type][handler.$$guid]; 
} 
}; 
function handleEvent(event) { 
var returnValue = true; 
//抓获事件对象(IE使用全局事件对象) 
event = event || fixEvent(window.event); 
//取得事件处理函数的哈希表的引用 
var handlers = this.events[event.type]; 
//执行每一个处理函数 
for (var i in handlers) { 
this.$$handleEvent = handlers[i]; 
if (this.$$handleEvent(event) === false) { 
returnValue = false; 
} 
} 
return returnValue; 
}; 
//为IE的事件对象添加一些“缺失的”函数 
function fixEvent(event) { 
//添加标准的W3C方法 
event.preventDefault = fixEvent.preventDefault; 
event.stopPropagation = fixEvent.stopPropagation; 
return event; 
}; 
fixEvent.preventDefault = function() { 
this.returnValue = false; 
}; 
fixEvent.stopPropagation = function() { 
this.cancelBubble = true; 
};

功能非常强悍,解决IE的this指向问题,event总是作为第一个参数传入,跨浏览器就更不在话下。
另,我还珍藏了一个HTML5工作组的版本:
var addEvent=(function(){ 
if(document.addEventListener){ 
return function(el,type,fn){ 
if(el.length){ 
for(var i=0;i<el.length;i++){ 
addEvent(el[i],type,fn); 
} 
}else{ 
el.addEventListener(type,fn,false); 
} 
}; 
}else{ 
return function(el,type,fn){ 
if(el.length){ 
for(var i=0;i<el.length;i++){ 
addEvent(el[i],type,fn); 
} 
}else{ 
el.attachEvent('on'+type,function(){ 
return fn.call(el,window.event); 
}); 
} 
}; 
} 
})();

(9)addLoadEvent()
我以前讨论过这函数,不细说,就是慢了一点,各大类库基本无视它,自行实现domReady版本。下面是Simon Willison 的实现:
var addLoadEvent = function(fn) { 
var oldonload = window.onload; 
if (typeof window.onload != 'function') { 
window.onload = fn; 
}else { 
window.onload = function() { 
oldonload(); 
fn(); 
} 
} 
}

(8) getElementsByClass()
我有收集癖,手头上拥有许多版本,最后集思广益自己实现了一个。下面是我的实现:
var getElementsByClassName = function (searchClass, node,tag) { 
if(document.getElementsByClassName){ 
return document.getElementsByClassName(searchClass) 
}else{ 
node = node || document; 
tag = tag || "*"; 
var classes = searchClass.split(" "), 
elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag), 
patterns = [], 
returnElements = [], 
current, 
match; 
var i = classes.length; 
while(--i >= 0){ 
patterns.push(new RegExp("(^|\\s)" + classes[i] + "(\\s|$)")); 
} 
var j = elements.length; 
while(--j >= 0){ 
current = elements[j]; 
match = false; 
for(var k=0, kl=patterns.length; k<kl; k++){ 
match = patterns[k].test(current.className); 
if (!match) break; 
} 
if (match) returnElements.push(current); 
} 
return returnElements; 
} 
}

(7)cssQuery()
别名为getElementsBySeletor,由Dean Edwards最先实现,Prototype.js,JQuery等类库都有相应实现,其中JQuery把它整合到$()选择器中,名声盖过其前辈。不过IE8等新锐浏览器已经实现querySelector与querySelectorAll方法,待到IE6与IE7报废之日,它就无用了。无忧里有它的实现原理讲解。由于太长,就不粘出来了,具体可到原作者网站看看。
(6)toggle()
用来显示或隐藏一个DOM元素。
function toggle(obj) { 
var el = document.getElementById(obj); 
if ( el.style.display != 'none' ) { 
el.style.display = 'none'; 
} 
else { 
el.style.display = ''; 
} 
}

(5)insertAfter()
DOM只提供了insertBefore,我们很有必要自己实现insertAfter。不过我认为 insertAdjacentElement是更好的选择,现在除了火狐其他浏览器都实现这个方法。下面是Jeremy Keith的版本:
function insertAfter(parent, node, referenceNode) { 
parent.insertBefore(node, referenceNode.nextSibling); 
}

(4)inArray()
用于判断检查数组中是否存在某个值,下面方法取自Prototype类库。
Array.prototype.inArray = function (value) { 
for (var i=0,l = this.length ; i <l ; i++) { 
if (this[i] === value) { 
return true; 
} 
} 
return false; 
};

另一个版本:
var inArray = function (arr,value) { 
for (var i=0,l = arr.length ; i <l ; i++) { 
if (arr[i] === value) { 
return true; 
} 
} 
return false; 
};

(3) getCookie(), setCookie(), deleteCookie()
做BBS与商业网站的应该经常用到,无理由每次都要让用户输入密码登录吧。我们需要借助cookie实现自动登录功能。
function getCookie( name ) { 
var start = document.cookie.indexOf( name + "=" ); 
var len = start + name.length + 1; 
if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) { 
return null; 
} 
if ( start == -1 ) return null; 
var end = document.cookie.indexOf( ';', len ); 
if ( end == -1 ) end = document.cookie.length; 
return unescape( document.cookie.substring( len, end ) ); 
} 
function setCookie( name, value, expires, path, domain, secure ) { 
var today = new Date(); 
today.setTime( today.getTime() ); 
if ( expires ) { 
expires = expires * 1000 * 60 * 60 * 24; 
} 
var expires_date = new Date( today.getTime() + (expires) ); 
document.cookie = name+'='+escape( value ) + 
( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString() 
( ( path ) ? ';path=' + path : '' ) + 
( ( domain ) ? ';domain=' + domain : '' ) + 
( ( secure ) ? ';secure' : '' ); 
} 
function deleteCookie( name, path, domain ) { 
if ( getCookie( name ) ) document.cookie = name + '=' + 
( ( path ) ? ';path=' + path : '') + 
( ( domain ) ? ';domain=' + domain : '' ) + 
';expires=Thu, 01-Jan-1970 00:00:01 GMT'; 
}

(2)getStyle()与setStyle()
所有UI控件都应该存在的函数,动态设置样式与获取样式。这个可以写得很短,也可以写得很长,但要精确取得样式,一个字:难!但我发现许多问题都是发端于IE,微软的开发人员好像从来不打算给出getComputedStyle这样的函数,与之相近的currentStyle会返回auto,inhert, ' '等让你哭笑不得的值,这还没有算上IE怪癖模式带来的难度呢!各类库的实现是非常长与难分离出来的,下面是我实现的版本:
function setStyle(el,prop,value){ 
if(prop == "opacity" && !+"\v1"){ 
//IE7 bug:filter 滤镜要求 hasLayout=true 方可执行(否则没有效果) 
if (!el.currentStyle || !el.currentStyle.hasLayout) el.style.zoom = 1; 
prop = "filter"; 
if(!!window.XDomainRequest){ 
value ="progid:DXImageTransform.Microsoft.Alpha(style=0,opacity="+value*100+")"; 
}else{ 
value ="alpha(opacity="+value*100+")" 
} 
} 
el.style.cssText += ';' + (prop+":"+value); 
} 
function getStyle(el, style){ 
if(!+"\v1"){ 
style = style.replace(/\-(\w)/g, function(all, letter){ 
return letter.toUpperCase(); 
}); 
return el.currentStyle[style]; 
}else{ 
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style) 
} 
}

有关setStyle还可以看我另一篇博文,毕竟现在设置的样式都是内联样式,与html混杂在一起。
(1)$()
实至名归,最值钱的函数,可以节省多少流量啊。最先由Prototype.js实现的,那是洪荒时代遗留下来的珍兽,现在有许多变种。
function $() { 
var elements = []; 
for (var i = 0; i < arguments.length; i++) { 
var element = arguments[i]; 
if (typeof element == 'string') 
element = document.getElementById(element); 
if (arguments.length == 1) 
return element; 
elements.push(element); 
} 
return elements; 
}
Javascript 相关文章推荐
javascript document.referrer 用法
Apr 30 Javascript
juqery 学习之三 选择器 子元素与表单
Nov 25 Javascript
用JavaScript实现一个代码简洁、逻辑不复杂的多级树
May 23 Javascript
javascript获取系统当前时间的方法
Nov 19 Javascript
BootStrap中的table实现数据填充与分页应用小结
May 26 Javascript
很棒的js Tab选项卡切换效果
Aug 30 Javascript
jQuery插件fullPage.js实现全屏滚动效果
Dec 02 Javascript
微信小程序使用npm包的方法步骤
Aug 13 Javascript
详解如何在Javascript和Sass之间共享变量
Nov 13 Javascript
node.js express捕获全局异常的三种方法实例分析
Dec 27 Javascript
Vue使用screenfull实现全屏效果
Sep 17 Javascript
微信小程序开发数据缓存基础知识辨析及运用实例详解
Nov 06 Javascript
默认让页面的第一个控件选中的javascript代码
Dec 26 #Javascript
js tab效果的实现代码
Dec 26 #Javascript
javascript 计算两个整数的百分比值
Dec 26 #Javascript
用Javascript同时提交多个Web表单的方法
Dec 26 #Javascript
再谈javascript 动态添加样式规则 W3C校检
Dec 25 #Javascript
javascript 处理事件绑定的一些兼容写法
Dec 24 #Javascript
Javascript 键盘keyCode键码值表
Dec 24 #Javascript
You might like
Linux操作系统安装LAMP环境
2015/06/26 PHP
php可扩展的验证类实例(可对邮件、手机号、URL等验证)
2015/07/09 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
2019/10/22 PHP
网上抓的一个特效
2007/05/11 Javascript
JavaScript实现的多个图片广告交替显示效果代码
2015/09/04 Javascript
jQuery仅用3行代码实现的显示与隐藏功能完整实例
2015/10/08 Javascript
JavaScript tab选项卡插件实例代码
2016/02/23 Javascript
微信小程序 vidao实现视频播放和弹幕的功能
2016/11/02 Javascript
vuejs响应用户事件(如点击事件)
2017/03/14 Javascript
Angular2 组件间通过@Input @Output通讯示例
2017/08/24 Javascript
vue项目中应用ueditor自定义上传按钮功能
2018/04/27 Javascript
vue配置文件实现代理v2版本的方法
2019/06/21 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
Python深入学习之装饰器
2014/08/31 Python
Python简单遍历字典及删除元素的方法
2016/09/18 Python
Python2随机数列生成器简单实例
2017/09/04 Python
Python 控制终端输出文字的实例
2019/07/12 Python
Pytorch中accuracy和loss的计算知识点总结
2019/09/10 Python
Pytorch之parameters的使用
2019/12/31 Python
关于Tensorflow分布式并行策略
2020/02/03 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
Python列表的深复制和浅复制示例详解
2021/02/12 Python
80年代复古T恤:TruffleShuffle
2018/07/02 全球购物
工商学院毕业生自荐信
2013/11/12 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
入党积极分子思想汇报范文
2014/01/05 职场文书
财务会计人员求职的自我评价
2014/01/13 职场文书
个人党性剖析材料
2014/02/03 职场文书
入党积极分子学习两会心得体会范文
2014/03/17 职场文书
高三毕业寄语
2014/04/10 职场文书
分家协议书
2014/04/21 职场文书
个人借款协议书范本
2014/11/17 职场文书
小学语文复习计划
2015/01/19 职场文书
奖学金申请书(范文)
2019/08/14 职场文书
鲲鹏 CentOS 7 安装Python3.7
2022/05/11 Servers
MySQL表字段数量限制及行大小限制详情
2022/07/23 MySQL