手动实现双击事件监听(灵活可配置)

3,170 阅读2分钟

前日一群友问:双击会连带触发单击事件,想让二者独立开来,分别做不同的监听,怎么破?我随口道:对单击事件做个封装呗?问怎么封装,思考了几分钟,还真难倒了我,我是个倔强的人,再想了一会,也没找到合适的解法,就这样几星期过去了,项目又赶进度,这事不了了之,今日想起,倍感羞愧,再想想就出来了,也记录下想到的种种思路,以及种种的被推翻,聊以慰藉。

为何不用原生实现?

前文已提到: dblclick会连带触发单击事件,二者混合一起,虽然不能简单地说好坏,但有些场景的确是需要将二者独立开来的。

分析与思考


来一张分析草图

接着上面的草图继续思考:

  • 这个单元时间跟延时调用挺像
  • 单元存在状态用一个变量保存,应该是布尔值
  • 单元存在状态变化在两个时间点:单元自然结尾、单元提前结束
  • 单元结束意味着 单击或双击的判定
  • 判定后,需要重置相应的参数与状态

第一种写法
var unitAlive = false;
var timer = null;
function handleClick(single,double){
    if(typeof single !== 'function' || typeof double !== 'function'){
        throw "参数必须为函数"
    }
    return function(){
        if(unitAlive === false){
            //单元未启动阶段
            //启动单元
            timer = setTimeout(function(){
                unitAlive = false;
                single()
            },160)
            //更新单元存续变量
            unitAlive = true;
        }else{
            //单元存续阶段,出现了二次点击
            //提前结束单元
            clearTimeout(timer);
            unitAlive = false;
            double()
        }
    }
}
//use
document.querySelector('#btn').addEventListener('click',handleClick(function(){
    //单击
    console.log('single')
},function(){
    //双击
    console.log('double')
}))

我们将单元与存续状态分为两个变量存储,因此定义了两个global变量,思考下是否能将二者合起来呢?当然可以,往下看呢:


第二种写法

将单元本身地特质决定存续状态:数组天生具备此特征,length为0则证明单元队列为空,不存在。队列为1则存在

var unitLine = [];
function handleClick(single,double){
    if(typeof single !== 'function' || typeof double !== 'function'){
        throw "参数必须为函数"
    }
    return function(){
        if(unitLine.length === 0){
            //单元未启动阶段
            //启动单元
            line.push(setTimeout(()=>{
                //清空单元队列
                unitLine = [];
                single();
            },170))
        }else if(unitLine.length === 1){
            //队列种有一个
            
            clearTimeout(unitLine[0]);//提前结束单元
            unitLine = [];//清空队列
            double()
        }
    }
    
}

总结

通过上述自定义地方式,实现了双击与单击的独立,当然还可以将时间间隔(单元时间长度设置为参数传入),更加灵巧。毕竟是手工实现,严格测试可能会有纰漏,正常的使用应该是没问题的,毕竟水平有限,不足之处还望读者朋友不吝赐教哦!