javascript十个最常用的自定义函数(中文版)


Posted in Javascript onSeptember 07, 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 相关文章推荐
用js判断浏览器是否是IE的比较好的办法
May 08 Javascript
将json当数据库一样操作的javascript lib
Oct 28 Javascript
js实现获取焦点后光标在字符串后
Sep 17 Javascript
JavaScript如何动态创建table表格
Aug 02 Javascript
纯JS打造网页中checkbox和radio的美化效果
Oct 13 Javascript
微信小程序 特效菜单抽屉效果实例代码
Jan 11 Javascript
BootStrap实现带关闭按钮功能
Feb 15 Javascript
Vue.js:使用Vue-Router 2实现路由功能介绍
Feb 22 Javascript
JS实现电商放大镜效果
Aug 24 Javascript
JS扁平化输出数组的2种方法解析
Sep 17 Javascript
Vue 禁用浏览器的前进后退操作
Sep 04 Javascript
微信小程序实现轮播图指示器
Jun 25 Javascript
javascript 获取select下拉列表值的代码
Sep 07 #Javascript
Javascript中的var_dump函数实现代码
Sep 07 #Javascript
jquery tools系列 expose 学习
Sep 06 #Javascript
jquery tools 系列 scrollable(2)
Sep 06 #Javascript
jquery tools 系列 scrollable学习
Sep 06 #Javascript
javascript事件问题
Sep 05 #Javascript
js跨域和ajax 跨域问题的实现思路
Sep 05 #Javascript
You might like
PHP COOKIE设置为浏览器进程
2009/06/21 PHP
使用GROUP BY的时候如何统计记录条数 COUNT(*) DISTINCT
2011/04/23 PHP
PHP采集静态页面并把页面css,img,js保存的方法
2014/12/23 PHP
php中使用url传递数组的方法
2015/02/11 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
基于thinkPHP框架实现留言板的方法
2016/10/17 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
java解析json方法总结
2019/05/16 PHP
数组Array进行原型prototype扩展后带来的for in遍历问题
2010/02/07 Javascript
IE6背景图片不缓存问题解决方案及图片使用策略多个方法小结
2012/05/14 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
jQuery表格插件ParamQuery简单使用方法示例
2013/12/05 Javascript
在Ubuntu上安装最新版本的Node.js
2014/07/14 Javascript
实现无刷新联动例子汇总
2015/05/20 Javascript
一个非常好用的文字滚动的案例,鼠标悬浮可暂停[两种方案任选]
2016/12/01 Javascript
Js apply方法详解
2017/02/16 Javascript
jQuery ajax实现省市县三级联动
2021/03/07 Javascript
浅谈基于Vue.js的移动组件库cube-ui
2017/12/20 Javascript
使用异步组件优化Vue应用程序的性能
2019/04/28 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
2019/11/14 Javascript
javascript局部自定义鼠标右键菜单
2020/12/08 Javascript
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
[01:08:44]NB vs VP 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python实现过滤单个Android程序日志脚本分享
2015/01/16 Python
python中偏函数partial用法实例分析
2015/07/08 Python
详解Python中pandas的安装操作说明(傻瓜版)
2019/04/08 Python
利用selenium爬虫抓取数据的基础教程
2019/06/10 Python
django数据库自动重连的方法实例
2019/07/21 Python
python elasticsearch从创建索引到写入数据的全过程
2019/08/04 Python
keras中epoch,batch,loss,val_loss用法说明
2020/07/02 Python
Python logging自定义字段输出及打印颜色
2020/11/30 Python
Pycharm 设置默认解释器路径和编码格式的操作
2021/02/05 Python
“四风”问题自我剖析材料思想汇报
2014/09/23 职场文书
2014年人力资源工作总结
2014/11/19 职场文书
2015年扶贫帮困工作总结
2015/05/20 职场文书
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
2022/04/30 Vue.js