代码之家  ›  专栏  ›  技术社区  ›  Nate Pet

如何防止使用jQuery双击?

  •  67
  • Nate Pet  · 技术社区  · 12 年前

    我有一个这样的按钮:

    <input type="submit" id="submit" value="Save" />
    

    在jQuery中,我使用了以下内容,但它仍然允许双击:

    <script type="text/javascript">
    
    $(document).ready(function () {
    
        $("#submit").one('click', function (event) {  
    

    你知道如何防止双击吗?

    19 回复  |  直到 10 年前
        1
  •  89
  •   bancer    8 年前

    jQuery的 one() 将为每个绑定的元素触发一次附加的事件处理程序,然后删除该事件处理程序。

    如果由于某种原因不能满足要求,也可以在单击按钮后完全禁用该按钮。

    $(document).ready(function () {
         $("#submit").one('click', function (event) {  
               event.preventDefault();
               //do something
               $(this).prop('disabled', true);
         });
    });
    

    需要注意的是,使用ID submit 可能会导致问题,因为它会覆盖 form.submit 函数,并引用该元素。

        2
  •  34
  •   Kichrum    10 年前

    还有一个解决方案:

    $('a').on('click', function(e){
        var $link = $(e.target);
        e.preventDefault();
        if(!$link.data('lockedAt') || +new Date() - $link.data('lockedAt') > 300) {
            doSomething();
        }
        $link.data('lockedAt', +new Date());
    });
    

    在这里,我们将上次点击的时间保存为数据属性,然后检查上次点击是否超过0.3秒。如果它是假的(不到0.3秒前),只更新上次点击时间,如果是真的,做点什么。

    jsbin

        3
  •  28
  •   roberth    9 年前

    我发现大多数解决方案都不适用于点击Labels或DIV之类的元素(例如,当使用Kendo控件时)。所以我做了一个简单的解决方案:

    function isDoubleClicked(element) {
        //if already clicked return TRUE to indicate this click is not allowed
        if (element.data("isclicked")) return true;
    
        //mark as clicked for 1 second
        element.data("isclicked", true);
        setTimeout(function () {
            element.removeData("isclicked");
        }, 1000);
    
        //return FALSE to indicate this click was allowed
        return false;
    }
    

    在您必须决定是否开始活动的地方使用它:

    $('#button').on("click", function () {
        if (isDoubleClicked($(this))) return;
    
        ..continue...
    });
    
        4
  •  12
  •   Pangui    10 年前

    我的解决方案: https://gist.github.com/pangui/86b5e0610b53ddf28f94 它可以防止双击,但在1秒后可以接受更多的点击。希望能有所帮助。

    这是代码:

    jQuery.fn.preventDoubleClick = function() {
      $(this).on('click', function(e){
        var $el = $(this);
        if($el.data('clicked')){
          // Previously clicked, stop actions
          e.preventDefault();
          e.stopPropagation();
        }else{
          // Mark to ignore next click
          $el.data('clicked', true);
          // Unmark after 1 second
          window.setTimeout(function(){
            $el.removeData('clicked');
          }, 1000)
        }
      });
      return this;
    }; 
    
        5
  •  11
  •   Ilia Ross    10 年前

    在我的案例中,jQuery one有一些副作用(在IE8中),我最终使用了以下内容:

    $(document).ready(function(){
      $("*").dblclick(function(e){
        e.preventDefault();
      });
    });
    

    它工作得很好,看起来更简单。在那里找到它: http://www.jquerybyexample.net/2013/01/disable-mouse-double-click-using-javascript-or-jquery.html

        6
  •  7
  •   Kabindas    7 年前

    “轻松豌豆”

    $(function() {
         $('.targetClass').dblclick(false);
    });
    
        7
  •  6
  •   Paul Chu    6 年前

    只要把这个方法放在你的表单中,它就会处理双击或多次点击。一旦请求发送,它将不允许再次发送请求。

    <script type="text/javascript">
        $(document).ready(function(){
                $("form").submit(function() {
                    $(this).submit(function() {
                        return false;
                    });
                    return true;
                }); 
        }); 
    </script>
    

    它肯定会对你有所帮助。

        8
  •  2
  •   user3856437    7 年前

    我也有类似的问题。您可以使用setTimeout()来避免双击。

    //some codes here above after the click then disable it
    

    //如果有属性被禁用,也请在此处检查

    //如果btn标记中有一个属性被禁用,那么 //返回。将其转换为js。

    $('#btn1').prop("disabled", true);
    
    setTimeout(function(){
        $('#btn1').prop("disabled", false);
    }, 300);
    
        9
  •  2
  •   Peter Csala Matheus Robert Lichtnow    4 年前

    当加载具有相同表单的新页面时,您可以执行以下操作以禁用提交按钮:

    $("#btnConfirm").bind("click", function (e) {
      $("#btnConfirm ").css("pointer-events", "none");
    });
    

    提交按钮可能如下所示:

    <input
        type="submit"
        name="ACMS_POST_Form_Confirm"
        value="confirm"
        id="btnConfirm"
    />
    
        10
  •  1
  •   Paulo Henrique Queiroz Nelson    8 年前
    /*
    Double click behaves as one single click
    
    
    "It is inadvisable to bind handlers to both the click and dblclick events for the same element. The sequence of events triggered varies from browser to browser, with some receiving two click events before the dblclick and others only one. Double-click sensitivity (maximum time between clicks that is detected as a double click) can vary by operating system and browser, and is often user-configurable."
    
    That way we have to check what is the event that is being executed at any sequence. 
    
       */
           var totalClicks = 1;
    
     $('#elementId').on('click dblclick', function (e) {
    
     if (e.type == "dblclick") {
        console.log("e.type1: " + e.type);
        return;
     } else if (e.type == "click") {
    
        if (totalClicks > 1) {
            console.log("e.type2: " + e.type);
            totalClicks = 1;
            return;
        } else {
            console.log("e.type3: " + e.type);
            ++totalClicks;
        }
    
        //execute the code you want to execute
    }
    
    });
    
        11
  •  1
  •   Peter van Mourik    7 年前

    @Kichrum提供的解决方案几乎对我有效。我不得不添加e.stopImmediatePropagation()来防止默认操作。这是我的代码:

    $('a, button').on('click', function (e) {
        var $link = $(e.target);
        if (!$link.data('lockedAt')) {
            $link.data('lockedAt', +new Date());
        } else if (+new Date() - $link.data('lockedAt') > 500) {
            $link.data('lockedAt', +new Date());
        } else {
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
        }
    });
    
        12
  •  1
  •   Tadas Stasiulionis    7 年前

    我发现的是一个在现代浏览器上运行的旧解决方案。适用于双击时不切换类。

    $('*').click(function(event) {
        if(!event.detail || event.detail==1){//activate on first click only to avoid hiding again on double clicks
            // Toggle classes and do functions here
            $(this).slideToggle();
        }
    });
    
        13
  •  1
  •   ma5k    6 年前

    这是我的第一个帖子&我很缺乏经验,所以请对我宽容一点,但我觉得我有一个有效的贡献,可能会对某人有所帮助。。。

    有时,重复点击之间需要一个很大的时间窗口(例如,一个mailto链接,需要几秒钟才能打开电子邮件应用程序,但你不希望它被重新触发),但你也不想在其他地方让用户慢下来。我的解决方案是根据事件类型为链接使用类名,同时在其他地方保留双击功能。。。

    var controlspeed = 0;
    
    $(document).on('click','a',function (event) {
        eventtype = this.className;
        controlspeed ++;
        if (eventtype == "eg-class01") {
            speedlimit = 3000;
        } else if (eventtype == "eg-class02") { 
            speedlimit = 500; 
        } else { 
            speedlimit = 0; 
        } 
        setTimeout(function() {
            controlspeed = 0;
        },speedlimit);
        if (controlspeed > 1) {
            event.preventDefault();
            return;
        } else {
    
            (usual onclick code goes here)
    
        }
    });
    
        14
  •  0
  •   Andrea    10 年前

    我也遇到过类似的问题,但禁用按钮并没有完全奏效。当点击按钮时,还会发生一些其他操作,有时,按钮没有很快被禁用,当用户双击时,会触发2个事件。
    我采用了Pangui的超时思想,并将这两种技术结合起来,禁用按钮并包含一个超时,以防万一。我创建了一个简单的jQuery插件:

    var SINGLECLICK_CLICKED = 'singleClickClicked';
    $.fn.singleClick = function () {
        var fncHandler; 
        var eventData;
        var fncSingleClick = function (ev) {
            var $this = $(this);
            if (($this.data(SINGLECLICK_CLICKED)) || ($this.prop('disabled'))) {
                ev.preventDefault();
                ev.stopPropagation();
            }
            else {
                $this.data(SINGLECLICK_CLICKED, true);
                window.setTimeout(function () {
                    $this.removeData(SINGLECLICK_CLICKED);
                }, 1500);
                if ($.isFunction(fncHandler)) {
                    fncHandler.apply(this, arguments);
                }
            }
        }
    
        switch (arguments.length) {
            case 0:
                return this.click();
            case 1:
                fncHandler = arguments[0];
                this.click(fncSingleClick);
                break;
            case 2: 
                eventData = arguments[0];
                fncHandler = arguments[1];
                this.click(eventData, fncSingleClick);
                break;
        }
        return this;
    }
    

    然后这样使用:

    $("#button1").singleClick(function () {
       $(this).prop('disabled', true);
       //...
       $(this).prop('disabled', false);
    })
    
        15
  •  0
  •   regiov    6 年前

    如果您真正想要的是避免多个表单提交,而不仅仅是防止双击,那么如果有客户端验证(例如根据需要标记的文本字段),那么在按钮的单击事件上使用jQuery one()可能会有问题。这是因为单击会触发客户端验证,如果验证失败,则不能再次使用该按钮。为了避免这种情况,one()仍然可以直接用于表单的提交事件。这是我发现的最干净的基于jQuery的解决方案:

    <script type="text/javascript">
    $("#my-signup-form").one("submit", function() {
        // Just disable the button.
        // There will be only one form submission.
        $("#my-signup-btn").prop("disabled", true);
    });
    </script>
    
        16
  •  0
  •   Tejas Hegde    4 年前

    我能够通过以下方式高效地完成这项任务

    1. 一旦调用按钮单击处理程序,禁用按钮

    2. 进行必要的操作。

    3. 使用SetTimeout在几秒钟后将禁用的属性设置回false

       $('#btn1).click(function(e){
       $('#btn1').prop("disabled", true);
      
       setTimeout(()=>{
       $('#btn1').prop("disabled", false);
       },2000)
      

    这应该能解决问题。

        17
  •  0
  •   Dominik Zyla    2 年前

    您可以将其用于整个应用程序

    $('a').not('.excluded-class, .excluded-class').click(function () {
         $(this).css('pointer-events','none');
    });
    $('button').not(".excluded-class").click(function () {
         $(this).prop('disabled', true);
    });
    

    排除类,如果您使用SweetAlerts或someting进行确认操作

        18
  •  0
  •   Tyler2P Suraj Mandal    2 年前

    设置一个flag对我很有效。我的flag被称为“submitOnce”。

    var submitOnce = 0;
    
    $(document).ready(function(){
      $("form").submit(function(e) {
        if (submitOnce > 0) {
          e.preventDefault();
        }
        //alert(submitOnce);
        submitOnce +=1;                
      });
    });
    
        19
  •  0
  •   Jose Rivera    2 年前

    我修改了罗伯特的回答。我使用的不是数据,而是类属性。

    function isDoubleClicked(element) {
        //if already clicked return TRUE to indicate this click is not allowed
        if (element.hasClass("is-clicked")) return true;
    
        //mark as clicked for 1 second
        element.addClass("is-clicked");
        setTimeout(function () {
            element.removeClass('is-clicked');
        }, 1000);
    
        //return FALSE to indicate this click was allowed
        return false;
    }
    

    所以,用法是一样的

    $('#button').on("click", function () {
        if (isDoubleClicked($(this))) 
            return;
    
        ..continue...
    });