函数的防抖和节流
防抖和节流
- 防抖: 立即执行和非立即执行;执行一次;经常用于搜索框;
- 节流: 时间戳 和定时器版; 控制每隔一段时间执行一次;稀释执行的频率; window.onscroll
函数的防抖
- 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,
则会重新计算函数执行时间。
<div id="box" style="width:100px;height:100px;background: red;text-align: center;
line-height: 100px;">0</div>
<script>
// 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,
则会重新计算函数执行时间。
//1非立即执行版:
// 非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,
如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
// let box = document.getElementById("box");
// let num =1;
// function add(a,b,c){
// //console.log(this);
// box.innerHTML =num++;
// }
// // 在n秒内就触发一次;
// // 事件不会一直触发,当停下以后1s之后再触发这个函数;
// function debounce(fn,wait){
// let timer;
// return function(){
// // 每次进到这个函数中,需要把上次定制的定时器任务给清除掉
// if(timer){
// clearTimeout(timer);
// }
// timer=setTimeout(()=>{
// fn.apply(this)// 通过apply修改了fn执行时里面的this指向,让它指向绑定那个元素
// },wait);
// }
// }
// box.οnmοusemοve=debounce(add,1000);
//2 立即执行版:
// 立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
// let num = 1;
// let content = document.getElementById('box');
// function count() {
// content.innerHTML = num++;
// };
// content.onmousemove = debounce(count,1000);
// function debounce(func, wait) {
// let timeout;
// return function () {
// let context = this;
// let args = arguments;
// if (timeout) clearTimeout(timeout);
// let callNow = !timeout;
// timeout = setTimeout(() => {
// timeout = null;
// }, wait)
// if (callNow) func.apply(context, args)
// }
// }
// 双剑合璧版:
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
// function debounce(func, wait, immediate) {
// let timeout;
// return function () {
// let context = this;
// let args = arguments;
// if (timeout) clearTimeout(timeout);
// if (immediate) {
// var callNow = !timeout;
// timeout = setTimeout(() => {
// timeout = null;
// }, wait)
// if (callNow) func.apply(context, args)
// } else {
// timeout = setTimeout(function () {
// func.apply(context, args)
// }, wait);
// }
// }
// }
函数的节流
- 节流(throttle)
- 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
// 节流(throttle)
// 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
let num = 1;
let content = document.getElementById('box');
function count() {
content.innerHTML = num++;
};
// 时间戳版:
// 在持续触发事件的过程中,函数会立即执行,并且每 1s 执行一次。
// function throttle(func, wait) {
// let previous = 0;
// return function () {
// let now = Date.now();
// let context = this;
// let args = arguments;
// if (now - previous > wait) {
// func.apply(context, args);
// previous = now;
// }
// }
// }
// content.onmousemove = throttle(count, 1000);
// 定时器版:
// 在持续触发事件的过程中,函数不会立即执行,并且每 1s 执行一次,在停止触发事件后,函数还会再执行一次。
function throttle(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
// 双剑合璧版:
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 表时间戳版,2 表定时器版
*/
function throttle(func, wait, type) {
if (type === 1) {
var previous = 0;
} else if (type === 2) {
var timeout;
}
return function () {
let context = this;
let args = arguments;
if (type === 1) {
let now = Date.now();
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
}
函数防抖与节流(简约)
<body>
<div id="box" style="width:100px;height:100px;background: red;text-align: center;line-height: 100px;">0</div>
<script>
//什么是防抖 节流
//你的项目中哪个地方中用到了防抖和节流
//防抖
//
let box = document.getElementById("box");
let num = 1;
function add() {
this.innerHTML = num++;
}
非立即执行
function debounce(fn, time) {
let timer;
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.call(this)
}, time)
}
}
box.onmousemove = debounce(add, 1000);
立即执行
立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
function debounce(fn, time) {
let timer;
return function () {
clearTimeout(timer)
if (!timer) {
fn.call(this);
}
timer = setTimeout(() => {
timer = null;
}, time)
}
}
box.onmousemove = debounce(add, 1000);
二合一
function debounce(fn, time, immediate) {
let timer;
return function () {
let context = this;
let args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
if (!timer) {
fn.call(this);
}
timer = setTimeout(() => {
timer = null;
}, time)
} else {
timer = setTimeout(() => {
fn.call(this)
}, time)
}
}
}
box.onmousemove = debounce(add, 1000, false); // true 表立即执行
节流
onmousemove onscroll onreset//可视窗口变化触发事件
时间戳
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
function throttle(fn, time) {
let pervious = 0;
return function () {
let now = Date.now();
if (now - pervious > time) {
fn.call(this);
pervious = now;
}
}
}
box.onmousemove = throttle(add, 2000); // true 表立即执行
定时器版
在持续触发事件的过程中,函数不会立即执行,并且每 1s 执行一次,在停止触发事件后,函数还会再执行一次
function throttle(fn, time) {
let timer;
return function () {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn.call(this)
}, time)
}
}
}
box.onmousemove = throttle(add, 2000); // true 表立即执行
//二合一
function throttle(fn, time, type) {
if (type === 1) {
var pervious = 0;
} else if (type === 2) {
var timer;
}
return function () {
if (type === 1) {
let now = Date.now();
if (now - pervious > time) {
fn.call(this);
pervious = now;
}
} else if (type === 2) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn.call(this)
}, time)
}
}
}
}
box.onmousemove = throttle(add, 2000, 1); // true 表立即执行
</script>
</body>