js防抖的一些疑问解答:为什么addEventListener调用防抖可以,onClick不行

tech2022-08-12  124

刚学习防抖/节流的时候就一直有一个疑问:为啥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>

 

最新回复(0)