你尚未登录,仅允许查看本站部分内容。请登录使用邀请码注册
renfufei

防止短时间内误操作导致的重复点击 1个回复 专栏 @ Javascript

renfufei 发布于 2 月前

功能: 防止抖动;防止短时间内重复点击等

实现原理

采用 dom 的 data 属性来缓存一个时间戳或者状态值, 在某个设定的时间后进行清除。 在此期间, 认为是误操作的重复点击,对事件直接忽略。

实现代码

    // clickBind(jQuery对象, handler, 禁止重复点击的秒数)
    // 防止抖动;防止短时间内重复点击等
    function clickBind($dom, handler, seconds){
        if(!$dom || !$dom.click || !handler){return;}
        // 将数据存到 data-属性上
        var data_key_inHandling = "in_click_handling";
        var class_key_inHandling = "wait-cursor";
        // .wait-cursor{ cursor: wait !important; }
        // 禁止重复点击的时间-秒
        seconds = seconds || 1;
        // 绑定事件, 其实可以包装一下,绑定各种事件
        $dom.click(handlerProxy);
        //
        function handlerProxy(){
            //
            var $this = $(this);
            // 判断是否处于抖动期
            if(isInHandling($this)){
                return false;
            }
            // 设置正在处理中
            setInHandling($this);
            // 自动移除禁止状态
            timeoutRemoveInHandling($this, seconds);
            // 执行
            return handler.apply(this, arguments);
        };
        // 判断是否正在处理之中
        function isInHandling($this){
            var inHandling = $this.data(data_key_inHandling);
            if(inHandling){
                return true;
            }
            return false;
        };
        // 设置处于处理过程中
        function setInHandling($this){
            var timestamp = new Date().getTime();
            $this.data(data_key_inHandling, ""+timestamp);
            $this.addClass(class_key_inHandling);
            // 其实可以设置禁止点击-disable
        };
        //
        function timeoutRemoveInHandling($this, seconds){
            window.setTimeout(function(){
                $this.removeClass(class_key_inHandling);
                $this.removeData(data_key_inHandling);
                // 其实可以设置禁止点击-disable
            }, seconds * 1000);
        };

    };

为了较好的展示,可以设置一个 CSS样式:

.wait-cursor{ cursor: wait !important; }

使用示例

 // 使用示例
 clickBind($("#btn1"), function(){
  // 处理逻辑 。。。
  console.dir("clicked at:" + new Date());
 });

当然,也可以自定义防抖动的时间。

其他

当然,也有其他的实现方式. 比如:

  • 服务器 session 之中的 token
  • 利用 sessionStorage 来暂存某类型事件的上次触发时间等。
  • 遮罩层

但应该考虑失败时如何进行处理!

欢迎拍砖!

2 月前,renfufei 补充:
  • alcat2008

    用 throttle 或者 debounce 不是更简单吗?

    #1
登录后回复,如无账号,请使用邀请码注册