Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery中的节流事件调用_Javascript_Jquery_Events_Zurb Foundation - Fatal编程技术网

Javascript jQuery中的节流事件调用

Javascript jQuery中的节流事件调用,javascript,jquery,events,zurb-foundation,Javascript,Jquery,Events,Zurb Foundation,我有一个keyup事件绑定到一个函数,该函数大约需要四分之一秒才能完成 $("#search").keyup(function() { //code that takes a little bit to complete }); 当用户键入一个完整的单词,或以其他方式快速按键时,该函数将连续调用数次,并且需要一段时间才能全部完成 $("#search").keyup(function() { //code that takes a little bit to complete });

我有一个
keyup
事件绑定到一个函数,该函数大约需要四分之一秒才能完成

$("#search").keyup(function() {
  //code that takes a little bit to complete
});
当用户键入一个完整的单词,或以其他方式快速按键时,该函数将连续调用数次,并且需要一段时间才能全部完成

$("#search").keyup(function() {
  //code that takes a little bit to complete
});
是否有一种方法可以限制事件调用,以便如果有几个事件连续快速调用,它只会触发最近调用的事件调用?

请查看


这里有一个不需要插件的潜在解决方案。使用布尔值决定是执行keyup回调,还是跳过它

var doingKeyup = false;

$('input').keyup(function(){
    if(!doingKeyup){
        doingKeyup=true;
        // slow process happens here
        doingKeyup=false;
    }
});

对于快速解决方案(请注意,coffeescript),这样的方法似乎最简单(没有外部库):


我在回顾对的更改时遇到了这个问题。他们已经为去盎司和节流做好了准备。看起来可能与他在回答中提到的jquery debounce@josh3736相同

从他们的网站:

// Debounced button click handler
$('.button').on('click', Foundation.utils.debounce(function(e){
  // Handle Click
}, 300, true));

// Throttled resize function
$(document).on('resize', Foundation.utils.throttle(function(e){
  // Do responsive stuff
}, 300));

这里有一个使用JQuery的干净方法

    /* delayed onchange while typing jquery for text boxes widget
    usage:
        $("#SearchCriteria").delayedChange(function () {
            DoMyAjaxSearch();
        });

    */
    (function ($) {
        $.fn.delayedChange = function (options) {
            var timer;
            var o;

            if (jQuery.isFunction(options)) {
                o = { onChange: options };
            }
            else
                o = options;

            o = $.extend({}, $.fn.delayedChange.defaultOptions, o);

            return this.each(function () {
                var element = $(this);
                element.keyup(function () {
                    clearTimeout(timer);
                    timer = setTimeout(function () {
                        var newVal = element.val();
                        newVal = $.trim(newVal);
                        if (element.delayedChange.oldVal != newVal) {
                            element.delayedChange.oldVal = newVal;
                            o.onChange.call(this);
                        }

                    }, o.delay);
                });
            });


        };

        $.fn.delayedChange.defaultOptions = {
            delay: 1000,
            onChange: function () { }
        }

        $.fn.delayedChange.oldVal = "";


    })(jQuery);

你也可以使用优秀的图书馆

Josh's是目前最受欢迎的评论,其中讨论了你是否真的应该限制通话,或者你是否想要一个脱口器。有点微妙,但下划线有两个:和


如果您还没有使用下划线,请检查它。它可以使您的JavaScript更加干净,并且足够轻量级,可以让大多数讨厌库的人停下来。

两个小型通用节流方法实现。(我更喜欢通过这些简单的函数来实现,而不是添加另一个jquery插件)

  • 在上次呼叫后等待一段时间

    当我们不想在用户不断键入查询时调用例如搜索函数时,这个函数很有用


  • 下面是一个可以同时测试两者的示例:

    这是一个节流阀,而不是去盎司。在搜索字段的情况下,您希望在用户完成键入(去盎司)后运行搜索,而不是在用户键入一个字符(节流)后运行搜索。Debounce插件实际上只是一个例子,我并不是在假设他的搜索字段是如何工作的。@josh3736公平地说,这个问题的标题确实需要一个“节流阀”。不过,我以前没有听说过“debounce”。这种方法还有一个问题——如果在前一个处理程序运行时输入了最后一个字符或一系列字符,则不会触发最终文本字符串。只有在另一个事件循环中发生
    //缓慢进程
    时,否则这是正确的方式,因为JS是单线程的,所以这没有用处。当我使用多个选择器时,如
    .sel1、.sel2 sel3
    @HungryCoder:当然,每个匹配的元素将共享同一个计时器,因此,在您完全停止发送事件之前,回调不会启动。Debounce不是在节流。这是一个问题else@vsync:挑剔的术语。OP说“节流”,但实际上是指“去盎司”,这并不能回答问题。OP可能认为它已经得到了回答,但这甚至还没有达到所描述的一半,也无法接近自动完成结果的预期行为。去盎司是错误的函数。OP实际上是在要求油门。请看:这是一个非常有用的高级JS主题,更多的人应该会看到它。关于油门或去抖器是否真的是你想要的存在争议。参考这一点:回答比下面更好的类似问题两个例子都是去盎司方法,而不是节流;)
        /* delayed onchange while typing jquery for text boxes widget
        usage:
            $("#SearchCriteria").delayedChange(function () {
                DoMyAjaxSearch();
            });
    
        */
        (function ($) {
            $.fn.delayedChange = function (options) {
                var timer;
                var o;
    
                if (jQuery.isFunction(options)) {
                    o = { onChange: options };
                }
                else
                    o = options;
    
                o = $.extend({}, $.fn.delayedChange.defaultOptions, o);
    
                return this.each(function () {
                    var element = $(this);
                    element.keyup(function () {
                        clearTimeout(timer);
                        timer = setTimeout(function () {
                            var newVal = element.val();
                            newVal = $.trim(newVal);
                            if (element.delayedChange.oldVal != newVal) {
                                element.delayedChange.oldVal = newVal;
                                o.onChange.call(this);
                            }
    
                        }, o.delay);
                    });
                });
    
    
            };
    
            $.fn.delayedChange.defaultOptions = {
                delay: 1000,
                onChange: function () { }
            }
    
            $.fn.delayedChange.oldVal = "";
    
    
        })(jQuery);
    
    function throttle(time, func) {
      if (!time || typeof time !== "number" || time < 0) {
          return func;
      }
    
      var throttleTimer = 0;
    
      return function() {
        var args = arguments;
        clearTimeout(throttleTimer);
        throttleTimer = setTimeout(function() {
          func.apply(null, args);
        }, time);
      }
    }
    
    function throttleInterval(time, func) {
      if (!time || typeof time !== "number" || time < 0) {
          return func;
      }
    
      var throttleTimer = null;
      var lastState = null;
      var eventCounter = 0;
      var args = [];
    
      return function() {
        args = arguments;
        eventCounter++;
        if (!throttleTimer) {
          throttleTimer = setInterval(function() {
            if (eventCounter == lastState) {
              clearInterval(throttleTimer);
              throttleTimer = null;
              return;
            }
    
            lastState = eventCounter;
            func.apply(null, args);
          }, time);
        }
      }
    }
    
    $("#inputBox").on("input", throttle(2000, function(evt) {
      myFunctionToThrottle(evt);
    }));