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 相关文章推荐
JS 实现获取打开一个界面中输入的值
Mar 19 Javascript
jQuery bxCarousel实现图片滚动切换效果示例代码
May 15 Javascript
js生成动态表格并为每个单元格添加单击事件的方法
Apr 14 Javascript
javascript常用函数归纳整理
Oct 31 Javascript
JavaScript实现自动变换表格边框颜色
May 08 Javascript
js中函数声明与函数表达式
Jun 03 Javascript
IE10中flexigrid无法显示数据的解决方法
Jul 26 Javascript
jQuery点击改变class并toggle及toggleClass()方法定义用法
Dec 11 Javascript
jquery捕捉回车键及获取checkbox值与异步请求的方法
Dec 24 Javascript
AngularJS自定义控件实例详解
Dec 13 Javascript
JavaScript监听手机物理返回键的两种解决方法
Aug 14 Javascript
原生JavaScrpit中异步请求Ajax实现方法
Nov 03 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
DC《神奇女侠2》因疫情推迟上映 温子仁新恐怖片《恶性》撤档
2020/04/09 欧美动漫
php 特殊字符处理函数
2008/09/05 PHP
ThinkPHP写第一个模块应用
2012/02/20 PHP
PHP检测链接是否存在的代码实例分享
2016/05/06 PHP
php封装的page分页类完整实例
2016/10/18 PHP
php mysql操作mysql_connect连接数据库实例详解
2016/12/26 PHP
php基于Redis消息队列实现的消息推送的方法
2018/11/28 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
Javascript 类与静态类的实现(续)
2010/04/02 Javascript
用JQuery模仿淘宝的图片放大镜显示效果
2011/09/15 Javascript
jquery 中的each()跳出循环的语句
2014/05/23 Javascript
javascript二维数组转置实例
2015/01/22 Javascript
jQuery实现的左右移动焦点图效果
2016/01/14 Javascript
js注入 黑客之路必备!
2016/09/14 Javascript
玩转NODE.JS(四)-搭建简单的聊天室的代码
2016/11/11 Javascript
微信小程序 传值取值的几种方法总结
2017/01/16 Javascript
ReactNative踩坑之配置调试端口的解决方法
2017/07/28 Javascript
详谈JS中数组的迭代方法和归并方法
2017/08/11 Javascript
VueJS组件之间通过props交互及验证的方式
2017/09/04 Javascript
vue-cli 如何打包上线的方法示例
2018/05/08 Javascript
webpack的 rquire.context用法实现工程自动化的方法
2020/02/07 Javascript
element中el-container容器与div布局区分详解
2020/05/13 Javascript
[01:10:02]IG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python发送邮件实例分享
2017/07/28 Python
Python实现动态图解析、合成与倒放
2018/01/18 Python
pandas修改DataFrame列名的方法
2018/04/08 Python
Python爬虫的两套解析方法和四种爬虫实现过程
2018/07/20 Python
python 数据分析实现长宽格式的转换
2020/05/18 Python
英国灯具和灯泡网上商店:Lights.co.uk
2018/02/02 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
先进班级集体事迹材料
2014/01/30 职场文书
积极贯彻学习两会精神总结
2014/03/17 职场文书
项目投资合作意向书
2014/07/29 职场文书
2014年班组建设工作总结
2014/12/01 职场文书
php实现自动生成验证码的实例讲解
2021/11/17 PHP
面试中老生常谈的MySQL问答集锦夯实基础
2022/03/13 MySQL