本文讲解一下节流和防抖的原理,和简单的使用。然后做一下节流与防抖的封装。
目录
前言
节流与防抖的原理
节流:
解释:
防抖:
解释:
节流的封装
防抖的封装
比如说我们写一个监听事件去监听鼠标在div里面的移动,或者监听滑块的移动,监听到变化就会触发函数。那么我们随便移动一下鼠标,拖动一下滑块,就会频繁触发函数去执行,执行几十甚至上百次。节流与防抖就是想办法,既能监听事件去执行函数,又可以避免频繁执行函数。
我们可以使用定时器来实现节流与防抖。
节流:就是减少函数的执行频率,一定时间内就执行一次。
比如说我写一个按钮,点击这个按钮就打印输出数字。每点击一下按钮,点击事件内的函数,函数内定义的变量num就要自增1,点击10次后,打印输出的就会是1.
而我不停的点击,在每隔一秒也会打印一次数字。
如下:
let btn = document.querySelector("button");
let flag = true,
number = 0;
btn.onclick = function() {
if (flag) {
flag = false;
number++;
setTimeout(() => {
flag = true;
console.log(number);
}, 1000);
}
}
我们在注册监听的函数里面,在监听到事件源发生改变的时候,其延时执行函数。使用定时器去延时执行函数。
我们使用"先关后开"的原理,先写一个开关,每次监听到事件源发生改变,就判断开关是否打开,如果打开就执行下一步,然后把开关关上,执行定时器,1s后定时器内函数开始执行,这时候在定时器内把开关打开。
再去触发事件源,因为开关被我们手动关上了,就不会再去执行下一步的东西,定时器也是不会再次执行,只有定时器执行的时候把开关打开,才能再去触发事件源再次执行定时器内的函数。
防抖:在一定时间内,函数只执行最后一次。
比如说我写一个按钮,点击这个按钮就打印输出数字。每点击一下按钮,点击事件内的函数,函数内定义的变量num就要自增1,点击10次后,打印输出的就会是10.
而我不停的点击,只有在点击结束后才能打印出数字。
如下:
var btn = document.querySelector("button");
var number = 0;
var timer;
btn.onclick = function() {
number++;
clearTimeout(timer)
timer = setTimeout(() => {
show()
}, 1000);
}
function show() {
console.log(number);
}
我们在注册监听的函数里面,在监听到事件源发生改变的时候,其延时执行函数。使用定时器去延时执行函数。
我们使用"先清后开"的原理,每次监听到事件源发生改变,就先清空定时器,然后再去执行定时器,定时器在延时1s后执行内部代码打印数字。每次去触发事件源就会清空上一次触发事件源产生的定时器,"就是不断的去取消上一次的点击"。
所以,我们在频繁去触发事件源的时候,只有最后一次才是有用的。
其实封装了两个,一个点击事件+节流的函数。先设置事件监听(addEventListener)的封装,在给触发事件源后的函数设置了节流的封装。
let btn = document.querySelector('button')//获取button
//把函数赋值给fun,这是节流后要执行的函数
let fun = function () { console.log('标准浏览器') }
//controls是元素,events是事件,buer是布尔值决定是否支持冒泡
function Throttling(controls, events, buer) {//节流的封装与传参
//事件添加的封装,fn是节流函数
controls.addEventListener(events, fn(fun), buer)
}
function fn(fun) {//节流函数,传的参是防抖后需要执行的函数
let timer = null//先定义timer
let time = true//定义开关time,先设置为开
return function () {
//如果time是true,就执行下面的代码
if (time) {
time = false//把time设置为false
timer = setTimeout(//定时器启动
function () {
time = true//打开开关
fun()//节流后执行的函数
}, 1000)
}
}
}
Throttling(btn, 'click', false)
其实封装了两个,一个点击事件+防抖的函数。先设置事件监听(addEventListener)的封装,在给触发事件源后的函数设置了防抖的封装。
let btn = document.querySelector('button')//获取button
//把函数赋值给fun,这是节流后要执行的函数
let fun = function () { console.log('标准浏览器') }
//controls是元素,events是事件,buer是布尔值决定是否支持冒泡
function Throttling(controls, events, buer) {//节流的封装与传参
//事件添加的封装,fn是节流函数
controls.addEventListener(events, fn(fun), buer)
}
function fn(fun) {//节流函数,传的参是防抖后需要执行的函数
let timer = null//先定义timer
let time = true//定义开关time,先设置为开
return function () {
//如果timer不是false,那就先清空定时器
if (time !== false) {
clearTimeout(timer)
}
timer = setTimeout(//定时器启动
function () {
fun()//节流后执行的函数
}, 500)
time = true//打开开关
}
}
Throttling(btn, 'click', false)
写的不好,也请大家多多批评。