首先,我们以window.onresize事件为例,来看一下未做防抖的情况。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
<script>
window.onload = function () {
function log() {
console.log('hello');
}
window.onresize = log;
}
</script>
</html>
如图:
在效果图中,我们可以看到,在频繁改变window窗口大小的时候,log函数被多次触发执行,但如果我们最终目的只是想获得窗口多次改变后的最终结果,不需要去关注窗口变化的过程,那么这个连续函数的执行过程就变得多余了,而且还会对浏览器资源造成不必要的浪费,针对这个问题我们就需要用到防抖函数了。
防抖,一段时间内连续的函数调用,只允许其执行一次。
//防抖,事件在某个时间间隔内再触发,会重新计时
function debounce(fn, await) {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this, arguments);
}, await)
}
}
我们使用防抖函数看看效果吧!
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
<script>
window.onload = function () {
//防抖,事件在某个时间间隔内再触发,会重新计时
function debounce(fn, await) {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this, arguments);
}, await)
}
}
function log() {
console.log('hello');
}
window.onresize = debounce(log,300);
}
</script>
</html>
效果:
使用了防抖函数,对比于之前是不是好了很多,在一次窗口变化的过程,函数执行了一次。
接下来,我们以window.onscroll事件为例,来看一下未节流的情况
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body {
width: 100%;
height: 10000px;
}
</style>
</head>
<body>
</body>
<script>
window.onload = function () {
function log() {
console.log('hello');
}
window.onscroll = log;
}
</script>
</html>
如图:
在效果图中,我们可以看到,我们在进行滚动操作的时候,多次触发滚动事件进行输出,这也是非常损耗浏览器资源的,这也并不是我们想要的结果,我们只是想在触发滚动事件的时候,在一定时间间隔内触发滚动加载,并且在时间间隔内只触发执行一次
节流,一段时间内的函数调用,保证事件一定会被执行一次。
//节流,事件在某个时间间隔内连续触发,只触发一次
function throttle(fn, await) {
let canRun = true;
return function () {
if(!canRun)return;
canRun = false;
let timer = setTimeout(() => {
fn.call(this, arguments);
canRun = true;
clearTimeout(timer);
}, await);
}
}
我们使用节流函数看看效果
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body {
width: 100%;
height: 10000px;
}
</style>
</head>
<body>
</body>
<script>
window.onload = function () {
//节流,事件在某个时间间隔内连续触发,只触发一次
function throttle(fn, await) {
let canRun = true;
return function () {
if (!canRun) return;
canRun = false;
let timer = setTimeout(() => {
fn.call(this, arguments);
canRun = true;
clearTimeout(timer);
}, await);
}
}
function log() {
console.log('hello');
}
window.onscroll = throttle(log, 300);
}
</script>
</html>
效果: