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

2022-01-15 00:00:00 event-handling jquery javascript

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

There is a button and when user clicks on button, some data is saved to back-end. Issue is when user clicks on button very quickly, event handler is getting executed multiple times.

这是代码

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

我希望当用户单击按钮一次时执行此处理程序.即使在双击或三次单击的情况下,也应该只执行一次.我只是想避免快速点击,这个处理程序当然可以再次执行

我有多种解决方案,比如

I have multiple solutions in my mind like

  1. 定义一个像 IS_BUTTON_HANDLER_WORKING = false 这样的全局变量,当你进入处理程序时,将其设置为 true,最后再次设置为 false.并检查是否为真,只需从函数返回.

  1. Define a global variable like IS_BUTTON_HANDLER_WORKING = false and when you enter the handler set it to true and in the end set it to false again. And check if it is true just return from the function.

在开始时分离处理程序并在最后重新附加.

Detach the handler in the beginning and reattach in the end.

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

Consider you have 25 buttons in your application. What should be the best approach to implement this.

看看这个小提琴

$('#button').click(function() {
   $(this).attr('disabled', true);
  // Do something
  // Save some data on network
  $(this).removeAttr('disabled');
});

使用它,我们可以确定只有在之前的执行完全完成后,我们的下一个处理程序才会被执行.

推荐答案

David Walsh 有一个很棒的 解决方案.

David Walsh has a great solution.

// 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);
    };
};

相关文章