2012-04-12 35 views
9

Tôi có người dùng thực hiện cuộc gọi ajax khi đang nhập. Vấn đề là nó làm cho các cuộc gọi cho mỗi chữ được gõ, vì vậy tôi thiết lập thời gian chờ như thế này:Đợi chức năng cho đến khi người dùng ngừng nhập

$(input).live('keyup', function(e){ 

setTimeout(function(){ 

var xx = $(input).val(); 
doSearch(xx); 

}, 400); 

}); 

Nó chờ 400ms nhưng sau đó thực hiện cho mỗi khóa. Làm thế nào tôi có thể thay đổi điều này để thực hiện cuộc gọi ajax chỉ 'một lần' khoảng 400ms sau khi lá thư được gõ cuối cùng?

(tôi đã sử dụng 'chậm trễ' trong quá khứ nhưng điều đó không làm việc ở tất cả với kịch bản của tôi ...)

+0

Đã có giải pháp được cung cấp trong câu hỏi khác: https://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up/16324620 # 16324620 –

Trả lời

18
timer = 0; 
function mySearch(){ 
    var xx = $(input).val(); 
    doSearch(xx); 
} 
$(input).live('keyup', function(e){ 
    if (timer) { 
     clearTimeout(timer); 
    } 
    timer = setTimeout(mySearch, 400); 
}); 

nó tốt hơn để di chuyển chức năng của bạn đến một hàm có tên và gọi nó là nhiều lần, bởi vì nếu không bạn đang tạo một hàm lambda trên mỗi KeyUp đó là không cần thiết và tương đối đắt tiền

+0

Điều đó làm việc như một sự quyến rũ :) – Youss

+0

@Youss và điều gì sẽ xảy ra nếu bạn nhấn và nhả một phím, và sau đó giữ một phím khác xuống? – Alnitak

+0

@Alnitak, bạn nói đúng, và có những vấn đề khác với điều này, ví dụ khi bạn gõ quá chậm (hơn 400 mili giây giữa 2 phím), nhưng trong trường hợp bình thường nó làm cho mọi thứ mượt mà hơn – Gavriel

4

Bạn cần phải thiết lập lại bộ đếm thời gian mỗi lần một khóa mới được nhấn, ví dụ

(function() { 
    var timer = null; 

    $(input).live('keyup', function(e) { 
     timer = setTimeout(..., 400); 
    }); 

    $(input).live('keydown', function(e) { 
     clearTimeout(timer); 
    }); 
)(); 

Biểu thức hàm được sử dụng để đảm bảo rằng phạm vi của biến số timer bị giới hạn ở hai hàm cần có.

+0

Có lẽ nên sử dụng '.on ('keyup', ...)' Vì jquery 1.7 '.live' đã không được chấp nhận. – ZombieCode

+0

@Ekaterina có, có lẽ nên, nhưng đây là tập hợp tối thiểu các thay đổi đối với mã OP. – Alnitak

0

tôi sẽ nghĩ rằng bạn có thể sử dụng delay() một lần nữa trong ngữ cảnh này miễn là bạn ổn bằng cách thêm tạm thời 'thứ gì đó' vào danh sách kết hợp. Liệu nó có giúp hiệu quả với anh không?

$(input).live('keyup', function(e) { 
    if (!$(input).hasClass("outRunningAJob")) { 
     var xx = $(input).val(); 
     $(input).addClass("outRunningAJob"); 
     doSearch(xx); 
     $(input).delay(400).queue(function() { 
      $(this).removeClass("outRunningAJob"); 
      $(this).dequeue(); 
     }); 
    } 
}); 
+0

Có vẻ như một cách giải quyết ... Câu trả lời được cung cấp bởi @ Flöcsy là thẳng hơn về phía trước. ps những gì là outRunningAJob :) – Youss

+0

Cá nhân tôi chưa trở nên thoải mái với các chức năng 'timeout' và vì vậy tôi nghĩ có lẽ bạn đang ở một nơi tương tự kể từ khi bạn đang hỏi về nó. Nó là một cách giải quyết? Đó là cách tôi sẽ tiếp cận vấn đề. Nếu bạn đang quen thuộc hơn với việc sử dụng 'delay' thì đây có thể là một giải pháp tốt hơn (trong một sự tôn trọng bảo trì). 'outRunningAJob' chỉ là tùy ý nhưng tự tạo tài liệu. Vui mừng bạn thích nó :-) – veeTrain

0

Tôi tìm thấy sau dễ dàng hơn để thực hiện:

$(input).on('keyup', function() { 
    delay(function() { 
     if (input).val() !== '' && $(input).val() !== $(input).attr('searchString')) { 
      // make the AJAX call at this time 
      // Store the value sent so we can compare when JSON returns 
      $(input).attr('searchString', $(input).val()); 

      namepicker2_Search_Prep(input); 
     } 
    }, 500); 
}); 

Bằng cách lưu trữ các chuỗi hiện tại bạn có thể thấy rằng người dùng đã ngừng gõ. Sau đó, bạn có thể gọi hàm của bạn một cách an toàn để thực hiện những gì cần phải xử lý.

Các vấn đề liên quan