比如说现在有个功能是单击实现选中,双击实现修改内容
单击成功的标志是改变背景颜色,双击成功的标志是显示输入框
现在如果想修改内容的话,此时双击会同时改变背景颜色,这就不符合要求了,改变背景颜色是不需要的。
这是因为双击同时会触发单击的事件
双击触发了两次单击事件和一次双击事件
如何解决呢 在单击事件里, --用定时器
首先先来回顾一下防抖和节流
防抖在input输入框的逻辑是这样的(功能大概是这样,解决方案其实有两种 这是其中一种)
需要判断新来的event在不在上一个定时器区间内,如何判断呢,如果定时器执行完了就把timer置为null,判断timer的值就可以。事件触发进入函数,判断如果timer为null就代表不在区间内,开启一个定时器作为周期开始;如果不为null就代表已经有定时器存在了,需要清除上一个定时器,然后再开启一个定时器以此类推
节流的逻辑是这样的 无论触发了多少次事件,在一次周期中,只会在定时器定时时间结束时执行一次目标代码
和上面的一样,也是需要判断timer的值来确定事件在不在周期内部,同样timer的值由是不是第一次执行和是不是上一个周期已经结束了决定。如果在周期内部的话就什么都不做,如果不在就开启一个定时器
接下来解决最开始的问题
现在的需求是如果500ms内没有第二次点击就执行目标代码,如果有第二次点击就直接return
和上面防抖节流一样,也是需要判断timer的值来确定事件在不在周期内部,同样timer的值由是不是第一次执行和是不是上一个周期已经结束了决定。和防抖节流不一样的是,如果第二次点击在周期内的话,定时器和timer都要清空--timer清空代表一个周期结束了,定时器清空代表不会执行定时器回调了
export function singleClick(fn, delay = 500) {let timer = nullreturn function () {// 如果timer有值代表前面已经点击了一次 那就返回 if (timer) {console.log("没有执行")clearTimeout(timer)// 初始化 要不然永远会走这个if语句timer = nullreturn}timer = setTimeout(() => {fn.apply(this, arguments)timer = null}, delay)}}