Javascript 如何防止在快速单击时两次调用en事件处理程序?

Javascript 如何防止在快速单击时两次调用en事件处理程序?,javascript,jquery,event-handling,Javascript,Jquery,Event Handling,有一个按钮,当用户单击按钮时,一些数据会保存到后端。问题是,当用户非常快地点击按钮时,事件处理程序会被执行多次 这是密码 var x = 1; $('#button').click(function() { // Do something // Save some data on network x++; console.log(x); }); 我希望当用户只单击一次按钮时,该处理程序就会被执行。即使在双击或三次单击的情况下,也应该只执行一次。我只是想避免快速点击,这个处理程序

有一个按钮,当用户单击按钮时,一些数据会保存到后端。问题是,当用户非常快地点击按钮时,事件处理程序会被执行多次

这是密码

var x = 1;
$('#button').click(function() {
  // Do something
  // Save some data on network
  x++;
  console.log(x);
});
我希望当用户只单击一次按钮时,该处理程序就会被执行。即使在双击或三次单击的情况下,也应该只执行一次。我只是想避免快速点击,这个处理程序当然可以再次执行

我脑子里有多种解决方案,比如

  • 定义一个全局变量,如
    IS\u BUTTON\u HANDLER\u WORKING=false
    ,当您输入处理程序时,将其设置为true,最后再次将其设置为false。并检查它是否为真,只需从函数返回即可

  • 开始时分离处理程序,最后重新连接

  • 假设您的应用程序中有25个按钮。实现这一点的最佳方法应该是什么

    看看这个

    解决方案
    使用此方法,我们确信只有在上一次执行完成后,下一个处理程序才会被执行。

    您可以使用jQueryone()方法,如图所示。

    有多种处理方法:

    单击后,您可以
    禁用
    /
    隐藏
    按钮:

    $('#button').attr("disabled", true);
    
    您还可以在每次单击时设置超时,以确保不会再次执行:

    var x, y = 1;
    
    $('#button').click(function() {
      if (x) clearTimeout(x);
      x = setTimeout(function() {
         // do the work here
         y++;
         console.log(y);
         // ----------------
      }, 1000);
    });
    
    因此,每次单击按钮时,它实际上只会在
    1000毫秒后执行代码,如果快速连续单击按钮,超时将被清除并重新开始

    请注意,以上内容未经测试

    就我个人而言,我认为禁用的解决方案是最好的,因为它向用户表明他已单击并且正在发生某些事情,您甚至可以在按钮旁边显示加载程序。

    根据编辑

    你应该使用

    您可以
    取消绑定
    单击事件功能

    var x = 1;
    function myButtonClick() {
    
        $('#button').unbind('click');
    
        // Do something
        // Save some data on network
        x++;
        console.log(x);
        $('#button').bind('click', myButtonClick);
    }
    
    $('#button').bind('click', myButtonClick);
    

    我正在使用下面的简单解决方案,它对我很有效:

    var x = 1;
    e.handled=false;
    $('#button').click(function(e) {
      if(e.handled==false){
          e.handled=true;
          // Do something
          // Save some data on network
          x++;
          console.log(x);      
      }
    });
    
    你在找什么

    或者,如果你需要一个特定的时间间隔,两次有效点击之间的间隔

    var last, diff;
    $( "button" ).click(function( event ) {
      if (last){
        diff = event.timeStamp - last;
        if (diff >= SOMEVAL){
          x++;
          console.log(x);    
        }
      }
      last = event.timeStamp;          
    });
    
    请尝试以下代码

    var x = 1;
    var fewSeconds=10; /*10 seconds*/
    
    $('#button').click(function() {
    $('#button').attr("disabled", "disabled");
      x++;
      console.log(x);
        var btn = $(this);
        btn.prop('disabled', true);
        setTimeout(function(){
            btn.prop('disabled', false);
        }, fewSeconds*1000);
    
    });
    
    大卫·沃尔什有一个伟大的梦想

    var btn=document.querySelector('twofons');
    btn.addEventListener(“单击”,方法1);
    btn.addEventListener(“单击”,方法2);
    函数方法2(){
    控制台日志(“方法2”);
    }
    setTimeout(函数(){
    btn.removeEventListener('单击',方法1);
    },5000);
    函数method1(){
    控制台日志(“方法1”);
    }
    
    Pramod Kharade在间隔后删除VeentListener
    点击我!
    
    假设您已将事件侦听器连接到按钮,一种方法是仅从按钮中删除事件侦听器,然后在需要时再次连接它。
    在事件侦听器函数本身中添加以下代码:

    function handleButtonClick(e){
      e.target.removeEventListener("click", handleBackButton);
    }
    

    根据您的设置,这可能会起作用。

    在按钮上启动忙指示灯,然后在结束返回之前停止

    Function DoSomething(){
    startBusyIndicator();
    // perform Action //
    
    stopBusyIndicator();
    return;
    }
    

    尝试使用
    one('click',fn)
    而不是
    click
    我认为
    one
    不是正确的答案,因为处理程序不会再次执行。您可能希望在一段时间后再次提交带有更新数据的表单。我喜欢这种禁用按钮的方法,因为它不需要我知道其他信息
    任何全局变量
    setinterval
    ->都会使代码有点复杂。如果以编程方式单击该按钮,则不会禁用该按钮。是的,我在发布该消息后阅读了很多文章。由于这是正确的方法,因此我正在更改对此的公认答案。谢谢你把它带来这里!!如果您希望事件立即触发并仅在特定时间后允许另一个调用,则似乎需要
    限制
    ,而不是
    取消缓冲
    。不,此类问题只需要取消缓冲或限制处理程序。您提到的BusyIndicator是一个非常复杂的解决方案,甚至不可能使它对某些协议保持稳定。
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If `immediate` is passed, trigger the function on the
    // leading edge, instead of the trailing.
    function debounce(func, wait, immediate) {
        var timeout;
        return function() {
            var context = this, args = arguments;
            var later = function() {
                timeout = null;
                if (!immediate) func.apply(context, args);
            };
            var callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(context, args);
        };
    };
    
    function handleButtonClick(e){
      e.target.removeEventListener("click", handleBackButton);
    }
    
    Function DoSomething(){
    startBusyIndicator();
    // perform Action //
    
    stopBusyIndicator();
    return;
    }