赞
踩
防抖:单位时间内,频繁触发事件,只执行最后一次。
举个栗子:在王者荣耀游戏内频繁按回城键,每一次按下回城键都会打断上一次回城,并且重新开始回城。
使用场景:
实现防抖的两种方式:
lodash
中的_.debounce()
方法下面我们分别使用这两种方法优化以下需求的实现:
鼠标每移动一次,盒子内的数值加一。(防抖间隔设置为500毫秒)
lodash
中的_.debounce()
实现防抖<!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>防抖</title> <script src="./node_modules/lodash/lodash.js"></script> <style> .box { width: 300px; height: 300px; background-color: pink; text-align: center; line-height: 300px; font-size: 40px; font-weight: 900; color: aliceblue; } </style> </head> <body> <div class="box"></div> <script> const box = document.querySelector('.box') // console.log(box); function mouseMove() { box.innerHTML = num++ } let num = 0 box.addEventListener('mousemove', _.debounce(mouseMove, 500)) </script> </body> </html>
该方法的详细使用可参考文档: JavaScript 实用工具库——lodash中文文档
核心:利用 setTimeout 定时器实现
声明定时器变量
每次鼠标移动(事件触发)的时候都要先判断是否有定时器,如果有先清除以前的定时器
如果没有定时器,则开启定时器,存入到定时器变量里面
定时器里面写函数调用
let num = 0
const box = document.querySelector('.box')
function mouseMove() {
box.innerHTML = num++
}
function debounce(fn, t) {
let timer
return function () { // 返回匿名函数
if (timer) clearTimeout(timer)
timer = setTimeout(function () {
fn() // 加小括号调用函数
}, t)
}
}
box.addEventListener('mousemove', debounce(mouseMove, 500))
能够实现和lodash
中的_.debounce()
一样的效果。
utils/debounce.js
// 防抖 export const debounce = function (fn, wait = 500) { // console.log(...arguments); // fn wait // 这个timer只会在页面初始化的时候定义一次,后面每一次输入都直接触发return的函数 let timer; // console.log(this); // undefined return function () { // console.log(arguments); // e str // console.log(this); // VueComponent 因为返回匿名返回后相当于在组件直接调这个函数 if (timer) clearTimeout(timer); timer = setTimeout(() => { // console.log(this); // VueComponent // apply改变此函数this指向并向此函数传递参数 fn.apply(this, arguments); }, wait); }; };
.vue
<template> <div> <input v-model="inputValue" @input="(e) => watchInput(e, 'Nihao')"> </div> </template> <script> import { debounce } from '../utils/debounce.js' export default { data() { return { inputValue: '', } }, methods: { watchInput: debounce((e, str) => { // console.log(this); // undefined 如果不用箭头函数就是VC console.log(e.target.value); console.log(str); }, 2000), }, } </script>
效果展示:
节流:单位时间内,频繁触发事件,只执行第一次。
举个栗子:王者荣耀技能有一定cd,点击释放技能后,cd期间无法继续释放技能。
使用场景:
高频事件:鼠标移动mousemove
、页面尺寸缩放resize
、滚动条滚动scroll
等等。
实现防抖的两种方式:
lodash
中的_.throttle()
方法下面我们分别使用这两种方法优化以下需求的实现:
鼠标在盒子上移动,不管移动多少次,每隔2000毫秒才+1。
lodash
中的_.throttle()
实现节流const box = document.querySelector('.box')
function mouseMove() {
box.innerHTML = num++
}
let num = 0
box.addEventListener('mousemove', _.throttle(mouseMove, 2000))
节流的核心就是利用定时器来实现:
注意:1.定时器里面调用执行的函数 2.定时器里面要把定时器清空。
let num = 0 const box = document.querySelector('.box') function mouseMove() { box.innerHTML = num++ } function throttle(fn, t) { let timer = null return function () { // 返回匿名函数 if (!timer) { timer = setTimeout(function () { fn() // 加小括号调用函数 timer = null // 清空定时器 }, t) } else { return } } } box.addEventListener('mousemove', throttle(mouseMove, 2000))
能够实现和lodash
中的_.throttle()
一样的效果。
值得注意的是:
定时器里面清空定时器只能将定时器置空,不能使用clearTimeout(定时器变量名)
,因为定时器还在运作,无法使用clearTimeout(定时器变量名)
。
和防抖同理
// 节流
export const throttle = function (fn, wait = 500) {
let timer = null
return function () {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null
}, wait)
} else {
return
}
}
}
性能优化 | 说明 | 使用场景 |
---|---|---|
防抖 | 单位时间内,频繁触发事件,只执行最后一次 | 搜索框搜索输入、手机号、邮箱验证输入检测 |
节流 | 单位时间内,频繁触发事件,只执行第一次 | 高频事件:鼠标移动mousemove、页面尺寸缩放resize、滚动条滚动scroll等等 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。