7个基本的js函数我记得早期的JavaScript,要完成任何事情几乎都绕不开一些简单的函数,因为浏览器提供商实现功能有所差异,而且不只是边缘功能,基础功能也一样,如addEventListener和attachEvent。虽然时代变了,但仍有一些函数是每个开发者都应该掌握的,以便于完成某些功能和提高性能。对于高耗能事件,debounce函数是一种不错解决方案。如果你不对scroll、resize、和key*事件使用debounce函数,那么你几乎等同于犯了错误。下面的debounce函数能让你的代码保持高效:返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用N毫秒后,再次调用它才会得到执行。如果有传递‘immediate’参数,会马上将函数安排到执行队列中,而不会延迟。
functiondebounce(func,wait,immediate){
var timeout;
returnfunction(){
var context=this,
args=arguments;
var later=function(){
timeout=null;
if(!immediate)func.apply(context,args);
};
var callNow=immediate&&!timeout;
clearTimeout(timeout);
timeout=setTimeout(later,wait);
if(callNow)func.apply(context,args);
};
};
用法
var myEfficientFn=debounce(function(){
所有繁重的操作
},250);
window.addEventListener(‘resize’,myEfficientFn);
123456789101112131415161718192021返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用N毫秒后,再次调用它才会得到执行。如果有传递‘immediate’参数,会马上将函数安排到执行队列中,而不会延迟。
functiondebounce(func,wait,immediate){
var timeout;
returnfunction(){
var context=this,
args=arguments;
var later=function(){
timeout=null;
if(!immediate)func.apply(context,args);
};
var callNow=immediate&&!timeout;
clearTimeout(timeout);
timeout=setTimeout(later,wait);
if(callNow)func.apply(context,args);
};
};
用法
var myEfficientFn=debounce(function(){
所有繁重的操作
},250);
window.addEventListener(‘resize’,myEfficientFn);
debounce函数不允许回调函数在指定时间内执行多于一次。当为一个会频繁触发的事件分配一个回调函数时,该函数显得尤为重要。尽管上面我提及了debounce函数,但如果事件不存在时,你就不能插入一个事件以判断所需的状态,那么就需要每隔一段时间去检查状态是否达到你的要求。
functionpoll(fn,callback,errback,timeout,interval){
var endTime=Number(newDate())+(timeout||2000);
interval=interval||100;
(functionp(){
如果条件满足,则执行!
if(fn()){
callback();
}
如果条件不满足,但并未超时,再来一次
elseif(Number(newDate())<endTime){
setTimeout(p,interval);
}
不匹配且时间消耗过长,则拒绝!
else{
errback(newError(‘timedoutfor’+fn+’:’+arguments));
}
})();
}
用法:确保元素可见poll(function(){
returndocument.getElementById(‘lightbox’).offsetWidth>0;
},function(){
执行,成功的回调函数
},function(){
错误,失败的回调函数
});
1234567891011121314151617181920212223242526272829303132
functionpoll(fn,callback,errback,timeout,interval){
var endTime=Number(newDate())+(timeout||2000);
interval=interval||100;
(functionp(){
如果条件满足,则执行!
if(fn()){
callback();
}
如果条件不满足,但并未超时,再来一次
elseif(Number(newDate())<endTime){
setTimeout(p,interval);
}
不匹配且时间消耗过长,则拒绝!
else{
errback(newError(‘timedoutfor’+fn+’:’+arguments));
}
})();
}
用法:确保元素可见poll(function(){
returndocument.getElementById(‘lightbox’).offsetWidth>0;
},function(){
执行,成功的回调函数
},function(){
错误,失败的回调函数
});
Polling在web中已被应用很长时间了,并在将来仍会被使用。有时候,你想让一个给定的功能只发生一次,类似于onload事件。下面的代码提供了你所说的功能:
functiononce(fn,context){
var result;
returnfunction(){
if(fn){
result=fn.apply(context||this,arguments);
fn=null;
}
returnresult;
};
}
用法
var canOnlyFireOnce=once(function(){
console.log(‘Fired!’);
});
canOnlyFireOnce();
“Fired!”
canOnlyFireOnce();
nada没有执行指定函数123456789101112131415161718192021
functiononce(fn,context){
var result;
returnfunction(){
if(fn){
result=fn.apply(context||this,arguments);
fn=null;
}
returnresult;
};
}
用法
var canOnlyFireOnce=once(function(){
console.log(‘Fired!’);
});
canOnlyFireOnce();
“Fired!”
canOnlyFireOnce();
nada没有执行指定函数once函数确保给定函数只能被调用一次,从而防止重复初始化!从一个字符串变量得到一个绝对URL,并不是你想象中这么简单。对于某些URL构造器,如果你不提供必要的参数就会出问题(而有时候你真的不知道提供什么参数)。下面有一个优雅的技巧,只需要你传递一个字符串就能得到相应的绝对URL。
var getAbsoluteUrl=(function(){
var a;
returnfunction(url){
if(!a)a=document.createElement(‘a’);
a.href=url;
returna.href;
};
})();
用法getAbsoluteUrl(‘/something’);
http://davidwalsh.name/something12345678910111213
var getAbsoluteUrl=(function(){
var a;
returnfunction(url){
if(!a)a=document.createElement(‘a’);
a.href=url;
returna.href;
};
})();
用法getAbsoluteUrl(‘/something’);
http://davidwalsh.name/somethinga元素的href处理和url处理看似无意义,而
return语句返回了一个可靠的绝对URL。如果你想知道一个指定函数是否是原生的,或者能不能通过声明来覆盖它。下面这段便于使用的代码能给你答案:;
(function(){
用于处理传入参数value的内部`[[Class]]`
var toString=Object.prototype.toString;
用于解析函数的反编译代码
var fnToString=Function.prototype.toString;
用于检测宿主构造器(Safari>4;
真的输出特定的数组)
var reHostCtor=/^[object.+?Constructor]$/;
用一个标准的原生方法作为模板,编译一个正则表达式。我们选择’Object#toString’
因为它一般不会被污染。
var reNative=RegExp(‘^’+将’Object#toString’
强制转为字符串String(toString)转义所有指定的正则表达式字符.replace(/[.*+?^${}()|[]/]/g,’$&’)用’.*?’
替换提及的’toString’,
以保持模板的通用性。将’for…’
之类的字符替换掉,以兼容Rhino等环境,因为这些环境添加了额外的信息,如方法参数数量。.replace(/toString|(function).*?(?=()|for.+?(?=])/g,’$1.*?’)+’$’);
functionisNative(value){
var type=typeofvalue;
returntype==’function’
用’Function#toString’(
fnToString)绕过了值(value)本身的’toString’
方法,以免被伪造所欺骗。?reNative.test(fnToString.call(value))回退到宿主对象的检查,因为某些环境(浏览器)将类型数组(typedarrays)之类的东西当作DOM方法,此时可能不遵循标准的原生正则表达式。:(value&&type==’object’&&reHostCtor.test(toString.call(value)))||false;
}
导出函数module.exports=isNative;
}());
用法isNative(alert);
trueisNative(myCustomFunction);
false123456789101112131415161718192021222324252627282930313233343536373839;
(function(){
用于处理传入参数value的内部`[[Class]]`
var toString=Object.prototype.toString;
用于解析函数的反编译代码
var fnToString=Function.prototype.toString;
用于检测宿主构造器(Safari>4;
真的输出特定的数组)
var reHostCtor=/^[object.+?Constructor]$/;
用一个标准的原生方法作为模板,编译一个正则表达式。我们选择’Object#toString’
因为它一般不会被污染。
var reNative=RegExp(‘^’+将’Object#toString’
强制转为字符串String(toString)转义所有指定的正则表达式字符.replace(/[.*+?^${}()|[]/]/g,’$&’)用’.*?’
替换提及的’toString’,
以保持模板的通用性。将’for…’
之类的字符替换掉,以兼容Rhino等环境,因为这些环境添加了额外的信息,如方法参数数量。.replace(/toString|(function).*?(?=()|for.+?(?=])/g,’$1.*?’)+’$’);
functionisNative(value){
var type=typeofvalue;
returntype==’function’
用’Function#toString’(
fnToString)绕过了值(value)本身的’toString’
方法,以免被伪造所欺骗。?reNative.test(fnToString.call(value))回退到宿主对象的检查,因为某些环境(浏览器)将类型数组(typedarrays)之类的东西当作DOM方法,此时可能不遵循标准的原生正则表达式。:(value&&type==’object’&&reHostCtor.test(toString.call(value)))||false;
}
导出函数module.exports=isNative;
}());
用法isNative(alert);
trueisNative(myCustomFunction);
false这个函数虽不完美,但它能完成任务!我们都知道能通过选择器(通过document.querySelectorAll)获取一个NodeList,并可为每个元素设置样式,但有什么更高效的方法为选择器设置样式呢(例如你可以在样式表里完成):
var sheet=(function(){
创建<style>标签
var style=document.createElement(‘style’);
如果你需要指定媒介类型,则可以在此添加一个media(和/或mediaquery)style.setAttribute(‘media’,’screen’)style.setAttribute(‘media’,’onlyscreenand(max-width:1024px)’)WebKithack:(style.appendChild(document.createTextNode(”));将<style>元素添加到页面document.head.appendChild(style);
returnstyle.sheet;
})();用法sheet.insertRule(“header{float:left;opacity:0.8;}”,1);12345678910111213141516171819
var sheet=(function(){
创建<style>标签
var style=document.createElement(‘style’);
如果你需要指定媒介类型,则可以在此添加一个media(和/或mediaquery)style.setAttribute(‘media’,’screen’)style.setAttribute(‘media’,’onlyscreenand(max-width:1024px)’)WebKithack:(style.appendChild(document.createTextNode(”));将<style>元素添加到页面document.head.appendChild(style);
returnstyle.sheet;
})();用法sheet.insertRule(“header{float:left;opacity:0.8;}”,1);这对于一个动态且重度依赖AJAX的网站来说是特别有用的。如果你为一个选择器设置样式,那么你就不需要为每个匹配到的元素都设置样式(现在或将来)。我们经常会在进行下一步操作前进行输入校验,以确保是一个可靠值,或确保表单数据是有效的,等等。但我们平时是怎么确保一个元素是否有资格进行进一步操作呢?如果一个元素有给定匹配的选择器,那么你可以使用matchesSelector函数来校验:
functionmatchesSelector(el,selector){
var p=Element.prototype;
var f=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.msMatchesSelector||function(s){
return[].indexOf.call(document.querySelectorAll(s),this)!==-1;
};
returnf.call(el,selector);
}
用法matchesSelector(document.getElementById(‘myDiv’),’div.someSelector[some-attribute=true]’)12345678910
functionmatchesSelector(el,selector){
var p=Element.prototype;
var f=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.msMatchesSelector||function(s){
return[].indexOf.call(document.querySelectorAll(s),this)!==-1;
};
returnf.call(el,selector);
}
用法matchesSelector(document.getElementById(‘myDiv’),’div.someSelector[some-attribute=true]’)就这样啦,上述7个JavaScript函数是每个开发者都应该时刻记着的。
有哪个函数我错过了呢?
评论前必须登录!
注册