1.谈一谈防抖与节流?有什么区别?如何实现?
定义
所谓防抖,就是指触发事件后,在 n 秒后函数才会执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
所谓节流,就是指连续触发事件,但是在 n 秒中只执行一次函数。
区别
函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。
使用场景
防抖:
1、搜索框搜索输入。只需用户最后一次输入完,再发送请求。
2、手机号、邮箱验证输入检测。
3、窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流:
1、滚动加载,加载更多或滚到底部监听。
2、谷歌搜索框,搜索联想功能。
3、高频点击提交,表单重复提交。
2.防抖的使用 例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>防抖与节流</title>
<style>
.box {
width: 200px;
height: 200px;
overflow: auto;
}
</style>
</head>
<body>
<div class="box" id="container">
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
<p>防抖演示</p>
</div>
</body>
<script type="text/javascript">
// 当连续触发scroll事件,handle函数只会在1秒时间内执行一次,在如果继续滚动执行,就会清除定时器,重新计时。相当于就是多次执行,只执行一次。
function debounce(fn, wait) {
var timeout = null;// 使用闭包,缓存变量
return function () {
if (timeout !== null) {
console.log('清除定时器啦')
clearTimeout(timeout); //清除这个定时器
}
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
console.log(Math.random());
}
var container = document.getElementById('container')
container.addEventListener('scroll', debounce(handle, 1000));
</script>
</html>
3.节流的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>防抖函数</title>
<style>
.box {
width: 200px;
height: 200px;
overflow: auto;
}
</style>
</head>
<body>
<div class="box" id="container">
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
<p>节流演示</p>
</div>
</body>
<script>
// 在前端开发中会遇到一些频繁的事件触发,比如: 1000/200= 5ms;
// window 的 resize(窗口大小)、scroll(滚动)
// mousedown、mousemove
// keyup、keydown
// ……
// 前端开发中,我们常常会去监听滚动事件或者用户输入框验证事件,如果事件处理没有频率限制,就会加重浏览器的负担,影响用户的体验感,
// 因此,我们可以采取防抖(debounce)和节流(throttle)来处理,减少调用事件的频率,达到较好的用户体验。
// throttle 节流 指定时间间隔内只会执行一次任务;
// 节流的原理很简单: 如果你持续触发事件,每隔一段时间,只执行一次事件。
// 关于节流的实现,有两种主流的实现方式,一种是使用时间戳,一种是设置定时器。
// 场景很多,常见的有:
// 屏幕尺寸变化时页面内容的变动,执行相应逻辑;
// 监听鼠标滚动时间,执行相应逻辑;
// 监听重复点击时的时间,执行相应逻辑
// 规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
// 在节流函数内部使用开始时间prev、当前时间now和剩余时间remain,当剩余时间小于等于0意味着执行处理函数,这样保证第一次就能立即执行函数并且每隔delay时间执行一次;
function throttle(func, delay) {
var timer = null; // 使用闭包,缓存变量
var prev = Date.now(); // 最开始进入滚动的时间
return function () {
var context = this; // this指向window
var args = arguments;
var now = Date.now();
var remain = delay - (now - prev); // 剩余时间
clearTimeout(timer);
// 如果剩余时间小于0,就立刻执行
if (remain <= 0) {
func.apply(context, args);
prev = Date.now();
} else {
timer = setTimeout(func, remain);
}
}
}
// 处理的函数
function handle() {
console.log(Math.random());
}
var container = document.getElementById("container");
container.addEventListener("scroll", throttle(handle, 3000))//20次 真实需求中 一秒调依次函数就足够了 怎么办?
</script>
</html>
拓展:
js防抖与节流以及应用场景
在前端开发中会遇到一些频繁的事件触发,例如input,keyup,keydown,scroll,resize,mousemove等,这非常影响性能,所以我们需要控制它们触发的频率,方法就是防抖与节流。
防抖
防抖的原理就是:要等你触发完事件 n 秒内不再触发事件,我才执行。
//debounce
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function () {
func.apply(context, args)
}, wait);
}
}
节流
节流的原理很简单:如果你持续触发事件,每隔一段时间,只执行一次事件。
有两种主流的实现方式,一种是使用时间戳,一种是设置定时器。
(1)时间戳实现
特点:第一次事件会立刻执行,停止触发后没有办法再执行事件。
function throttle(func, wait) {
var previous = 0;
return function () {
var now = Date.now();
var context = this;
var args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
(2)定时器实现
特点:会在 n 秒后第一次执行,事件停止触发后依然会再执行一次事件。
function throttle(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
if (!timeout) {
timeout = setTimeout(function () {
func.apply(context, args);
timeout = null;
}, wait)
}
}
}
应用场景:
防抖:
1.浏览器窗口 缩放,resize事件,常见于需要做页面适配的时候,需要 根据最终呈现的页面情况进行dom渲染。
2.表单的按钮提交事件,例如登录,发短信,避免用户点击太快,以至于发送了多次请求。
3.search搜索框输入,只需用户最后一次输入完在发送请求。
4.文本编辑器实时保存,当无任何更改操作1s后进行保存。
节流:
1.鼠标不断点击触发,mousedown(单位时间内只触发一次) mousemove事件。
2.商品预览图的放大镜效果。
3.谷歌搜索框(支持实时搜索),搜索联想功能。
4.scroll事件,每隔1s计算一次位置信息。
窗外
雨落纷纷
宿雾空