2010-03-09 27 views
29

Làm cách nào để trì hoãn các hành động giữa nhấn phím trong jQuery. Ví dụ;trì hoãn các hành động giữa nhấn phím trong jQuery

Tôi có một cái gì đó như thế này

if($(this).val().length > 1){ 
    $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){ 
    if(data.length > 0) { 
     $('#suggestions').show(); 
     $('#autoSuggestionsList').html(data); 
    }else{ 
     $('#suggestions').hide(); 
    } 
}); 
} 

tôi muốn ngăn chặn đăng dữ liệu nếu người dùng liên tục gõ. Vì vậy, làm thế nào tôi có thể cung cấp cho 0,5 giây chậm trễ?

+0

Tôi giả định rằng đây là một chức năng mà được thông qua vào 'bấm phím() '? – Jeremy

Trả lời

59

Bạn có thể sử dụng khả năng dữ liệu của jQuery để làm điều này, một cái gì đó như thế này:

$('#mySearch').keyup(function() { 
    clearTimeout($.data(this, 'timer')); 
    var wait = setTimeout(search, 500); 
    $(this).data('timer', wait); 
}); 

function search() { 
    $.post("stuff.php", {nStr: "" + $('#mySearch').val() + ""}, function(data){ 
    if(data.length > 0) { 
     $('#suggestions').show(); 
     $('#autoSuggestionsList').html(data); 
    }else{ 
     $('#suggestions').hide(); 
    } 
    }); 
} 

Ưu điểm chính ở đây là không có biến toàn cầu ở khắp mọi nơi, và bạn có thể bọc này trong một chức năng ẩn danh trong setTimeout nếu bạn muốn, chỉ cần cố gắng làm ví dụ càng rõ ràng càng tốt.

10

Tất cả bạn cần làm là quấn chức năng của bạn trong một thời gian chờ mà được thiết lập lại khi người dùng nhấn một phím:

var ref; 
var myfunc = function(){ 
    ref = null; 
    //your code goes here 
}; 
var wrapper = function(){ 
    window.clearTimeout(ref); 
    ref = window.setTimeout(myfunc, 500); 
} 

Sau đó chỉ cần gọi "wrapper" trong sự kiện quan trọng của bạn.

+0

+1 ít jQuery cho một giải pháp đơn giản. – A1rPun

1

tôi muốn quấn nó trong một chức năng như vậy:

var needsDelay = false; 

    function getSuggestions(var search) 
    { 
    if(!needsDelay) 
    { 
     needsDelay = true; 
     setTimeout("needsDelay = false", 500); 

     if($(this).val().length > 1){ 
      $.post("stuff.php", {nStr: "" + search + ""}, function(data){ 
       if(data.length > 0) { 
        $('#suggestions').show(); 
        $('#autoSuggestionsList').html(data); 
       }else{ 
        $('#suggestions').hide(); 
       } 
      }); 
     } 
    } 


    } 

Bằng cách đó dù có bao nhiêu lần bạn ping này, bạn sẽ không bao giờ tìm kiếm hơn mỗi 500 mili giây.

+5

không bao giờ chuyển chuỗi thành setTimeout! eval là ác (trong * hầu hết * trường hợp) :) sử dụng một hàm anoymous như: 'setTimeout (function() {needsDelay = false;}, 500);' thay thế. –

+0

Tôi biết rằng eval là ác, nhưng tôi vẫn còn lười biếng và đặt eval báo cáo trong mã của tôi. Tôi cần phải thêm nó vào danh sách nazi của tôi. Không còn eval nữa. – thaBadDawg

3

Có một plugin hay để xử lý việc này. câu trả lời jQuery Throttle/Debounce

+0

không có phụ thuộc vào jQuery cho mọi thứ? Phải thừa nhận- tên "Debounce" gọi tiếng cười hoài nghi! Dù sao, tìm tốt. – matrixugly

+0

lodash cũng có các phương pháp [throttle] (https://lodash.com/docs#throttle) và [debounce] (https://lodash.com/docs#debounce) –

2

của Nick là hoàn hảo nhưng nếu xử lý sự kiện đầu tiên ngay lập tức là rất quan trọng sau đó tôi nghĩ rằng chúng tôi có thể làm:

$(selector).keyup(function(e){ //or another event 

    if($(this).val().length > 1){ 
     if !($.data(this, 'bouncing-locked')) { 

      $.data(this, 'bouncing-locked', true) 

      $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){ 
       if(data.length > 0) { 
        $('#suggestions').show(); 
        $('#autoSuggestionsList').html(data); 
       }else{ 
        $('#suggestions').hide(); 
       } 
      }); 

      self = this 
      setTimeout(function() { 
       $.data(self, 'bouncing-locked', false); 

       //in case the last event matters, be sure not to miss it 
       $(this).trigger("keyup"); // call again the source event 
      }, 500) 
     } 
    } 
}); 
Các vấn đề liên quan