2011-07-20 407 views
4

我有一个#search元素,当发生keyup事件时应该触发一个函数。如果keyup未在设定的时间内发生(例如500毫秒),则该功能只应触发。这将防止搜索结果更新每个被按下的字母。问题是,与Backbone.js的,我有我的事件中的哈希和一个适用的样子:jquery/backbone.js - 延迟函数调用

'keyup #search' : 'setSearch'

keyup事件发生时调用setSearch()功能。我现在还不清楚如何处理它。我已经尝试了各种各样的东西,但是没有任何东西可以维持定时器超过函数结尾。

我有一些像这样:

setSearch: function(event) { 
      var timer = window.setTimeout(function() { 
       // run function here 
       alert('fired'); 
      }, 500); 
    }, 

而非alert('fired'),我有我自己的功能运行。我可以看到为什么这个代码不起作用(每发生一个keyup事件都会设置一个定时器,但我仍然没有清楚的想法,我还有什么可以尝试的。

回答

3

您需要一个实例变量视图,存储定时器ID,那么你就可以阻止它,并根据需要重新启动:

setSearch: function(event) { 
    var self = this; 
    if(self.timer) 
     clearTimeout(self.timer); 
    self.timer = setTimeout(function() { 
     alert('fired'); 
     self.timer = null; 
    }, 500); 
} 

所以,如果计时器已经在运行,你叫clearTimeout停止它,开始一个新的计时器,并存储计时器ID在self.timer(AKA this.timer)您还需要重置定时器的回调函数中存储的定时器ID或您的定时器发射一次后您的setSearch将不会做任何事情,并且所有的self业务只是捕获this用于定时器的回调函数。

0

由于您希望您的事件处理程序事件能够维护事件是否具有recentlyFired,因此您可能希望将您的处理程序封装到闭包中并保持该状态。发生事件时应将状态更改为true,并在延迟500ms后重置为false。

setSearch: function() { 
    var firedRecently = false; 
    return function(event) { 
     if (firedRecently) { 
      // it has fired recently. Do you want to do something here? 
     } else { 
      // not fired recently 
      firedRecently = true; 
      // run your function here 
      alert('fired'); 
      var resetStatus = window.setTimeout(function() { 
       firedRecently = false; 
      }, 500); 
     } 
    } 
}(); 
19

实际上是什么,你正在寻找

setSearch: _.throttle(function() { 
       //Do Stuff 
       }, 500), 

一言以蔽之从underscore.js提供给您的功能(骨干的要求),这将返回匿名函数的一种新形式每500ms只能调用一次。您可能需要根据需要调整时间。

更多信息: http://documentcloud.github.com/underscore/#throttle

+10

user1243645的评论:“我遇到了我的项目类似的要求我只是想补充一点,响应斯凯勒·安德森的一篇关于'_。油门“,我实际上已经发现['_.debounce()'](http://documentcloud.github.com/underscore/#debounce)可以更好地满足我的需求。” –

+0

对于这个问题,去抖动要比油门好得多。 – tonyhb

1

防止搜索结果的更新每keyup正是那种认为下划线的_.debounce(function, wait)功能是为了应付局面。该underscore documentation for _.debounce()状态:

创建并返回传递function的新版本去抖,这将推迟执行,直到后,因为它被调用最后一次wait毫秒已经过去了。用于实现只应在输入停止后才会发生的行为。

你重构的代码看起来那样简单:

setSearch: function(event) { 
    _.debounce(doSomething, 300); 
}, 
+0

“,它将推迟执行,直到自上次调用后等待毫秒后才开始执行” - 对于“搜索字段”不起作用,因为您不希望它在第一个键盘上执行搜索,在搜索之前,你想等3个键盘等等 - 特别是对于大集合。但是,如果发生火灾,请再次等待火灾,是的,这很好。 – VeenarM

+0

去弹回效果最佳 – vini