2012-04-01 28 views
10

Tôi đang sử dụng API phim rottentomatoes kết hợp với plugin typeahead của twitter bằng cách sử dụng bootstrap 2.0. Tôi đã có thể tích hợp API nhưng vấn đề tôi gặp phải là sau mỗi sự kiện keyup API được gọi. Điều này là tất cả tốt và dandy nhưng tôi thà thực hiện cuộc gọi sau một tạm dừng nhỏ cho phép người dùng gõ một số ký tự đầu tiên.Tôi có thể trì hoãn sự kiện keyup cho jquery không?

Đây là mã hiện tại của tôi mà các cuộc gọi API sau một sự kiện KeyUp:

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

       }); 

      } 
     } 
    }); 

Có thể thiết lập một sự chậm trễ nhỏ và tránh gọi API sau mỗi lần KeyUp?

Trả lời

9

nó có thể dễ dàng thực hiện như thế này:

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

Điều này hoạt động tốt nhưng có vẻ như bị kẹt trong một vòng lặp, thực hiện cuộc gọi đến datarequest mỗi 200 ms? – Paul

+0

Trong mã của bạn, bạn đang kích hoạt khóa sau khi khóa: 'self.trigger ('keyup')'. Đối với việc xử lý sự kiện keyup thích hợp, bạn nên xóa 'ev.stopPropagation();' và 'self.trigger ('keyup')' –

+0

Điều đó đã làm được điều đó ... cảm ơn! – Paul

-1

Thay vì trễ, nếu bạn chỉ muốn cho phép người dùng nhập một vài ký tự trước yêu cầu ajax $ .getJSON, bạn có thể sửa đổi câu lệnh if để người dùng phải nhập số ký tự tối thiểu, cho ví dụ 3, trước khi bạn yêu cầu dữ liệu:

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

Nói chung, điều này có thể đạt được với setTimeoutclearTimeout phương pháp:

var timer; 

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

setTimeout sẽ thực hiện javascript cung cấp sau khi quy định khoảng thời gian tính bằng mili giây. clearTimeout sẽ hủy thực thi này.

Tôi cũng đã chuẩn bị jsFiddle demo hiển thị đoạn mã đang hoạt động.

Tài liệu tham khảo:

2

Đối với những người làm việc với v0.11 của typeahead.js và sử dụng Bloodhound để lấy lời đề nghị từ xa, bạn có thể sử dụng tùy chọn rateLimitWait để tăng tốc yêu cầu:

var search = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    remote: { 
    url: '/search?q=%QUERY', 
    rateLimitWait: 500 
    } 
}); 
Các vấn đề liên quan