首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

最惯用的javascript自定义函数

2012-07-22 
最常用的javascript自定义函数如果不使用类库或者没有自己的类库,储备一些常用函数总是有好处的。以下的函

最常用的javascript自定义函数

如果不使用类库或者没有自己的类库,储备一些常用函数总是有好处的。以下的函数就是我们平时用的各个库(Jquery,dojo,Prototype等)里封装好的平时没去关心的函数罢了

(1)addEvent

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);
??????????????? });
??????????? }
??????? };
??? }
})();
(2)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();
????? }
??? }
? }
(3) 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;
??? }
}

(5)toggle()

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

function toggle(obj) {
??? var el = document.getElementById(obj);
??? if ( el.style.display != ‘none‘ ) {
??????? el.style.display = ‘none‘;
??? }
??? else {
??????? el.style.display = ”;
??? }
}
(6)insertAfter()

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

function insertAfter(parent, node, referenceNode) {
??? parent.insertBefore(node, referenceNode.nextSibling);
}

?

(7)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;
};
(8) 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‘;
}
(9)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混杂在一起。

(10)$()

实至名归,最值钱的函数,可以节省多少流量啊。最先由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;
}

?

?

?

?

热点排行