2012-04-01 44 views
10

我使用rottentomatoes电影API与twitter的typeahead插件一起使用bootstrap 2.0。我已经能够整合这个API,但是我遇到的问题是,在API被调用之后的每个keyup事件之后。这一切都很好,但是我宁愿在一小段暂停之后打电话,让用户先输入几个字符。我可以推迟jquery的关键事件吗?

这是我的一个keyup事件后调用API当前代码:

var autocomplete = $('#searchinput').typeahead() 
    .on('keyup', function(ev){ 

     ev.stopPropagation(); 
     ev.preventDefault(); 

     //filter out up/down, tab, enter, and escape keys 
     if($.inArray(ev.keyCode,[40,38,9,13,27]) === -1){ 

      var self = $(this); 

      //set typeahead source to empty 
      self.data('typeahead').source = []; 

      //active used so we aren't triggering duplicate keyup events 
      if(!self.data('active') && self.val().length > 0){ 

       self.data('active', true); 

       //Do data request. Insert your own API logic here. 
       $.getJSON("http://api.rottentomatoes.com/api/public/v1.0/movies.json?callback=?&apikey=MY_API_KEY&page_limit=5",{ 
        q: encodeURI($(this).val()) 
       }, function(data) { 

        //set this to true when your callback executes 
        self.data('active',true); 

        //Filter out your own parameters. Populate them into an array, since this is what typeahead's source requires 
        var arr = [], 
         i=0; 

        var movies = data.movies; 

        $.each(movies, function(index, movie) { 
         arr[i] = movie.title 
         i++; 
        }); 

        //set your results into the typehead's source 
        self.data('typeahead').source = arr; 

        //trigger keyup on the typeahead to make it search 
        self.trigger('keyup'); 

        //All done, set to false to prepare for the next remote query. 
        self.data('active', false); 

       }); 

      } 
     } 
    }); 

是否可以设置一个小的延迟,避免每次KEYUP后调用API?

回答

9

它可以这样很容易做到:

var autocomplete = $('#searchinput').typeahead().on('keyup', delayRequest); 

function dataRequest() { 
    // api request here 
} 

function delayRequest(ev) { 
    if(delayRequest.timeout) { 
     clearTimeout(delayRequest.timeout); 
    } 

    var target = this; 

    delayRequest.timeout = setTimeout(function() { 
     dataRequest.call(target, ev); 
    }, 200); // 200ms delay 
} 
+0

这工作的很好,但它似乎陷入了一个循环,每200毫秒打一次数据请求调用? – Paul 2012-04-01 18:23:14

+0

在你的代码中,你在keyup后触发了keyup:'self.trigger('keyup')'。对于正确的键盘事件处理,你应该删除'ev.stopPropagation();'和'self.trigger('keyup')' – 2012-04-01 19:20:12

+0

这么做了......谢谢! – Paul 2012-04-02 12:07:47

-1

如果您只想让用户在ajax $ .getJSON请求之前输入几个字符,您可以修改if语句,以便用户输入最少数量的字符,而不是延迟例3中,您请求数据之前:

if(!self.data('active') && self.val().length >=3){ 
4

一般来说,这可以用setTimeoutclearTimeout方法实现:

var timer; 

$('#textbox').keyup(function() { 
    if (timer) { 
     clearTimeout(timer); 
    } 
    timer = setTimeout('alert("Something cool happens here....");', 500); 
}); 

setTimeout将执行提供的JavaScript指定后以毫秒为单位的时间间隔。 clearTimeout将取消此执行。

我也准备了jsFiddle demo显示代码片段的行动。

参考文献:

2

对于人的typeahead.js v0.11工作,并使用Bloodhound获取远程的建议,您可以使用rateLimitWait选项限制请求:

var search = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    remote: { 
    url: '/search?q=%QUERY', 
    rateLimitWait: 500 
    } 
});