刚学习防抖/节流的时候就一直有一个疑问:为啥addEventListener调用防抖函数可以,但是我再HTML里写onClick方法就不行呢?百思不得其解,后来还是屈服了,用了addEventListener,但是后来学到了vue.....这下不能这么干了(因为vue不建议直接操作dom)懵圈了,在仔细整理闭包后才知道原因:这种防抖函数(生成器)的原理是 防抖函数每执行一次返回一个受 time
变量控制的函数!
上代码:
/**
* 防抖函数
* @param {*} func 回调函数 必传
* @param {*} wait 等待时长 默认500ms 可不传
*/
export function debounce(func, wait = 500) {
let timeOut
return function () {
let content = this
let arg = arguments
if (timeOut) {
clearTimeout(timeOut)
}
timeOut = setTimeout(() => {
func.apply(content, arg)
}, wait)
}
}
原始调用:
<button id="box" onclick="fangDou(handle, 1000)">点我点我点我</button>
<script>
let box = document.getElementById("box");
function handle() {
console.log(111);
}
box.addEventListener("click", debounce(handle, 1000))
</script>
这样可以的原因是
addEventListener
后面的 debounce
加了个括号,所以它会在解析的时候执行,返回的这个函数作为点击事件的回调函数,没毛病;而 onclick
的回调函数直接就是 debounce
,每次点击都只会返回受控的函数,而这个受控的函数没有执行,所以没有反应。
解决的思路:
<button id="box" onclick="clickHandler()">点我点我点我</button>
<script>
let box = document.getElementById("box");
function handle() {
console.log(111);
}
clickHandler = debounce(handle, 500);
在vue中:
<template>
<div>
<div class="inputContent">
<t-input
:style="{'--fonWidth':fonWidth+'px'}"
v-model="searchKey"
class="inputSearch"
clearable
placeholder="搜索内容"
>
</t-input>
</div>
</div>
</template>
<script>
import { debounce } from '../common/util.js'
export default {
data () {
return {
searchKey: '',
vm: this,
}
},
watch: {
searchKey: function () {
this.toDoSth(this)
}
},
methods: {
// 调用防抖
toDoSth: debounce((vm) => {
vm.searchEvent()
}, 500),
searchEvent () {
if (this.searchKey.length) { // 查询
} else { // 清空
alert()
}
}
}
}
</script>