防抖原理:
在事件被触发规定的时间后才执行一次,如果在规定的时间内又一次触发了事件则重新计时。
应用场景:1.scroll事件滚动触发 2.搜索框输入查询 3.浏览器窗口缩放,resize事件
防抖实现:
function debounce(func,wait,bool){
let timeout;
let result; //有需求的时候,调用的时候需要一个返回结果,
let decounced = function(){
//定义this,改变this的指向
let that = this;
//定义arguments,改变arguments的指向
let args = arguments;
if (timeout) clearTimeout(timeout)
//判断bool是不是为true 如果为true立即执行
if(bool){
// 3.timeout有值了所有为false再取反就为true
let callNow = !timeout //1.因为代码一执行的时候,timeout是undefined
//2.执行完定时器后timeout就有值了 这个闭包函数就会一直被执行 bool就为true
timeout = setTimeout(() => {
timeout = null
},wait);
//立即执行,如果callNow为true则立即执行 //立即执行的时候,赋值给result
if(callNow) result = func.apply(that,args)
}else{
//如果为false执行下面代码
timeout = setTimeout(function(){
func.apply(that,args);
},wait);
}
return result; //最后返回出去
}
//定制取消的方法
decounced.cancel = function(){
clearTimeout(timeout);
//因为decounced是个闭包所有容易造成内存泄漏,需要把timeout置为空
timeout = null
}
return decounced;
}
let count = 0;
let container = document.querySelector('#container');
let btn = doucument.quertSelector('#btn'); //取消防抖按钮
function fuc(){
container.innerHTML = count++;
}
//取消防抖方法
let doSome = debounce(fuc,5000);
btn.onclick = function(){
doSome.cancel()
}
container.onmousemove = doSome;
简单手写防抖
function debounce(fn,wait){
let timeout;
return function(){
let that = this;
let args = arguments;
clearTimerout(timeout);
timeout = setTimerout(function(){
fn.apply(that,args)
},wait)
}
}
function sayHi(){
console.logo('防抖成功')
}
var container = document.querySelector('#container')
container.onmousemove = debounce(sayHi,300)
节流原理:
当持续触发事件时,保证一段时间内执行一次事件。
实现函数节流有两种方式一种是时间戳,一种是定时器
时间戳:第一次会触发,最后一次调用不会触发
function throttke(fn,wait){
let old = 0; //之前的时间戳
return function(){
let that = this;
let args = arguments;
let now = new Date().valeOf();
if(now - old > wait){
fn.apply(that,args)
old = now;
}
}
}
定时器:第一次不会触发,最后一次调用会触发
function throttle(fn,wait){
let that,args,timeout;
return function(){
that = this;
args = arguments;
if(!timeout){
timeout = setTimeout(() => {
fn.apply(that,args);
timeout = null
},wait)
}
}
}