防抖
在规定时间内,多次触发一个事件,只会执行最后一个事件中的函数。
应用场景:输入框内搜索,输入关键词就会触发搜索事件函数,一直输入一直触发。用防抖,防止连续发送请求,在规定的时间内(如2000ms内),只会触发一次搜索事件,以规定时间内的最后一次触发为准。
按钮多次点击提交,频繁触发提交事件。利用防抖,防止多次提交,在规定时间内,只处理最后一次的提交事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 防抖函数,两个参数分别是处理函数和延迟时间
// 在多少时间内只执行处理函数,在规定时间多次触发滚动事件,只会执行最后一次的滚动事件
function debounce(fn, delay) {
let timer = null; //定义一个定时器
// 返回一个函数
return function() {
// 滚动事件一触发,就会输出
console.log("hello");
// 执行函数之前,先判断是否有定时器在执行
if (timer !== null)
clearTimeout(timer); //如果有旧的定时器,就清除这个定时器
// 重新开启一个新的定时器(在delay时间末尾,执行一次fn函数)
timer = setTimeout(fn, delay);
}
}
// 处理函数
function handle() {
console.log(parseInt(Math.random() * 10));
}
// 监听滚动事件
// 页面发生滚动事件,就会触发防抖函数debounce
// debounce(handle, 200):在200毫秒内,只执行一次handle函数
window.addEventListener('scroll', debounce(handle, 200));
</script>
</head>
<body>
<div style="height: 2000px; width: 200px; background-color: brown;">
</div>
</body>
</html>
如下图:
只执行最后一次事件中的处理函数
vue3版本
<script setup>
import { ref } from 'vue'
defineProps({
msg: String
})
const count = ref(0)
const handle = () => {
count.value++
}
const handler = (fn, delay) => {
let timer = null
console.log(timer, 22222);
return function () {
if (timer != null) {
clearTimeout(timer)
}
timer = setTimeout(fn, delay)
}
}
const clicker = handler(handle, 1000)
</script>
<template>
<div>
<h1>{{ msg }}</h1>
<button type="button" @click="clicker">count is: {{ count }}</button>
</div>
</template>
<style scoped lang="scss">
</style>
节流
在规定时间内,只执行第一次的触发事件中的函数,只处理一次函数,在这时间内,此函数 都不会再执行了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 节流函数
function throttle(func, delay) {
// 记录当前时间(就是第一次(上一次)滚动事件触发的时间)
var prev = Date.now();
return function() {
// 普通函数的this指向window
var context = this;
// arguments是一个类数组对象,用于接受函数的参数
// 这个只要发生滚动事件就会输出
// console.log(arguments);
var args = "hello";
console.log(args);
// 再次记录当前的时间(第二次(下一次)滚动事件的触发时间)
var now = Date.now();
//两次滚动事件触发的时间间隔是否大于规定的时间
if (now - prev >= delay) {
// 如果间隔大于规定的时间delay,就会调用func(也就是handle函数)
// apply:改变函数的this指向,第一个参数是this指向,第二参数是传递的参数,要用数组存放,
// call和bind是 一个一个的存放,不用数组
func.apply(context, [args]);
prev = Date.now();
}
}
}
// 这个处理函数在规定时间内只能执行一次
function handle() {
console.log(parseInt(Math.random() * 10));
// console.log(arguments);
}
// 监听滚动事件
// 滚动事件,触发throttle函数,规定时间是1000ms
window.addEventListener('scroll', throttle(handle, 1000));
</script>
</head>
<body>
<div style="height: 2000px; width: 200px; background-color: brown;">
</div>
</body>
</html>
如下图
在第一次事件触发时就执行了处理函数,在规定时间内只执行一次
防抖和节流的区别
防抖是在一定时间内多次触发同一事件,但是只会执行最后一次的事件中的函数。比如输入框搜索,按钮提交都是以最后一次为准,就需要防抖(关注最后的结果)。
节流是在一定时间内多次触发同一事件,但是只会执行第一次的事件,等时间到了,才会再次触发此事件。比如发送请求,需要要上一次请求完成之后才会执行下一个请求,就需要节流(关注的是过程)。
arguments对象。
arguments 是一个对应于传递给函数的参数的类数组对象,是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。
arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。
typeof参数返回 ‘object’