函数防抖(debounce)
什么是防抖?短时间内多次触发同一个事件,只执行最后一次,或者只在开始时执行,中间不执行。
- 不使用防抖和节流,函数不断被触发,数字一直增加
//变量初始化
var xcd = document.getElementById('xcd'),
count = 1;
//要执行的操作 数字+1
function doSomething() {
xcd.innerHTML = count++;
};
//触发onmousemove事件 正常情况下
xcd.onmousemove = doSomething;
- 使用防抖之绿色基础版
//绿色基础版:
function debounce(doSomething,wait){
var timeout;//需要一个外部变量,为增强封装,所以使用闭包
return function(){
var _this = this,
_arguments = arguments;//arguments中存着e
clearTimeout(timeout);
timeout = setTimeout(function(){
doSomething.apply(_this,_arguments);
},wait);
}
}
//触发onmousemove事件
xcd.onmousemove = debounce(doSomething,1000);
- 使用防抖之立即执行版
//立即执行版
function debounce(doSomething,wait,isImmediate){
var timeout;
return function(){
var _this = this,
_arguments = arguments;
clearTimeout(timeout);
if(isImmediate){
var isTrigger = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
isTrigger&&doSomething.apply(_this,_arguments);
}else{
timeout = setTimeout(function(){
doSomething.apply(_this,_arguments);
},wait);
}
}
}
//触发onmousemove事件
xcd.onmousemove = debounce(doSomething,1000,true);
函数节流(throttle)
什么是节流?节流是连续触发事件的过程中以一定时间间隔执行函数。节流会稀释你的执行频率,比如每间隔1秒钟,只会执行一次函数,无论这1秒钟内触发了多少次事件。
- 使用节流之时间戳版
//绿色基础版之时间戳版
function throttle(doSomething,wait){
var _this,
_arguments,
initTime = 0;
return function(){
var now = +new Date();//将new date()转化为时间戳
_this = this;
_arguments = arguments;
if(now - initTime>wait){
doSomething.apply(_this,_arguments);
initTime = now;
}
}
}
//触发onmousemove事件
xcd.onmousemove = throttle(doSomething,1000);
- 使用节流之定时器版
//绿色基础版之定时器版
function throttle(doSomething,wait){
var timeout;
return function(){
var _this = this;
_arguments = arguments;
if(!timeout){
timeout = setTimeout(function(){
timeout = null;
doSomething.apply(_this,_arguments);
},wait);
};
}
}
//触发onmousemove事件
xcd.onmousemove = throttle(doSomething,1000);
- 使用节流之双剑合璧版
//节流之双剑合璧版
function throttle(doSomething, wait) {
var timeout, _this, _arguments,
previous = 0;
var later = function() {
previous = +new Date();
timeout = null;
doSomething.apply(_this, _arguments)
};
var throttled = function() {
var now = +new Date();
//下次触发 doSomething 剩余的时间
var remaining = wait - (now - previous),
_this = this;
_arguments = arguments;
// 如果没有剩余的时间了
if (remaining <= 0) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
doSomething.apply(_this, _arguments);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
};
return throttled;
}
//触发onmousemove事件
xcd.onmousemove = throttle(doSomething,1000);