2010-01-20 27 views
14

Xin chào tất cả. Tôi có một biểu mẫu được gửi từ xa khi các yếu tố khác nhau thay đổi. Trên một lĩnh vực tìm kiếm đặc biệt tôi đang sử dụng một keyup để phát hiện khi các văn bản trong lĩnh vực này thay đổi. Vấn đề với điều này là khi một người nào đó gõ "gà" thì biểu mẫu được gửi bảy lần, chỉ với lần đếm cuối cùng.(jquery/js) - nhận văn bản từ trường trên khóa, nhưng với độ trễ để nhập thêm

Điều gì sẽ là tốt hơn là một cái gì đó giống như

  • KeyUp này phát hiện - bắt đầu chờ đợi (trong một giây)

  • khác KeyUp phát hiện - khởi động lại chờ đợi thời gian

  • kết thúc chờ đợi - nhận giá trị và gửi biểu mẫu

trước khi tôi đi và mã phiên bản riêng của tôi về điều này (tôi thực sự là một anh chàng phụ trợ với chỉ một chút js, tôi sử dụng jquery cho tất cả mọi thứ), là đã có một giải pháp hiện tại này? Có vẻ như nó sẽ là một yêu cầu chung. Một plugin jquery có thể? nếu không, cách đơn giản nhất và tốt nhất để viết mã này là gì?

cảm ơn, max

CẬP NHẬT - mã hiện gia tăng đối với Dan (dưới đây)

Dan - điều này có thể có liên quan. Một trong những plugin jquery mà tôi đang sử dụng trên trang (tablesorter) yêu cầu tệp này - "tablesorter/jquery-latest.js", nếu có, dẫn đến lỗi tương tự với mã của bạn như trước:

jQuery ("input # search"). dữ liệu ("timeout", null) không được xác định http://192.168.0.234/javascripts/main.js?1264084467 Dòng 11

Có thể có một số loại xung đột giữa các định nghĩa jquery khác nhau? (hoặc một cái gì đó)

$(document).ready(function() { 
    //initiate the shadowbox player 
// Shadowbox.init({ 
// players: ['html', 'iframe'] 
// }); 
}); 

jQuery(function(){ 
    jQuery('input#search') 
    .data('timeout', null) 
    .keyup(function(){ 
     jQuery(this).data('timeout', setTimeout(function(){ 
      var mytext = jQuery('input#search').val(); 
      submitQuizForm(); 
      jQuery('input#search').next().html(mytext); 
     }, 2000) 
    ) 
    .keydown(function(){ 
     clearTimeout(jQuery(this).data('timeout')); 
    }); 
    }); 
}); 

function submitQuizForm(){ 
    form = jQuery("#searchQuizzes"); 
    jQuery.ajax({ 
    async:true, 
    data:jQuery.param(form.serializeArray()), 
    dataType:'script', 
    type:'get', 
    url:'/millionaire/millionaire_quizzes', 
    success: function(msg){ 
    // $("#chooseQuizMainTable").trigger("update"); 
    } 
    }); 
    return true; 
} 

Trả lời

24

Xin lỗi tôi đã không thử nghiệm điều này và nó hơi lệch đầu tôi, nhưng điều gì đó dọc theo những dòng này hy vọng sẽ làm được điều này. Thay đổi năm 2000 đến tuy nhiên nhiều mili giây bạn cần vào giữa các bài máy chủ

<input type="text" id="mytextbox" style="border: 1px solid" /> 
<span></span> 

<script language="javascript" type="text/javascript"> 
    jQuery(function(){ 
     jQuery('#mytextbox') 
     .data('timeout', null) 
     .keyup(function(){ 
      clearTimeout(jQuery(this).data('timeout')); 
      jQuery(this).data('timeout', setTimeout(submitQuizForm, 2000)); 
     }); 
    }); 
</script> 
+0

bên trong hàm setTimeout bạn có thể có thể thay đổi jQuery ('# myElement') để jQuery (this) –

+0

Cảm ơn dan - nó rơi xuống tại .data đầu tiên ('timeout', null), nói rằng nó không phải là một hàm. Tôi có phải làm gì khác trước khi tôi có thể gọi .data không? Tôi đang gọi nó trên một trường văn bản trong trường hợp này. –

+0

Max, bạn có chắc chắn rằng bạn đã đưa thư viện jQuery vào và thay đổi # myelement thành bộ chọn phần tử của riêng bạn không? Tôi đã chỉ cho nó một thử nghiệm nhanh chóng và nó làm việc tại chỗ trên :) Dan –

4

Như một bản cập nhật, tôi đã kết thúc với điều này mà dường như làm việc tốt:

function afterDelayedKeyup(selector, action, delay){ 
    jQuery(selector).keyup(function(){ 
    if(typeof(window['inputTimeout']) != "undefined"){ 
     clearTimeout(inputTimeout); 
    } 
    inputTimeout = setTimeout(action, delay); 
    }); 
} 

Sau đó tôi gọi này từ trang trong câu hỏi của khối document.ready với

afterDelayedKeyup('input#search',"submitQuizForm()",500) 

Điều gì sẽ được tốt đẹp sẽ làm cho một sự kiện jquery mới trong đó sử dụng logic này, ví dụ như .delayedKeyup để đi cùng với .keyup, vì vậy tôi chỉ có thể nói điều gì đó như điều này cho một khối document.ready của một trang riêng lẻ.

jQuery('input#search').delayedKeyup(function(){ 
    submitQuizForm(); 
    }); 

Nhưng, tôi không biết cách tùy chỉnh jquery theo cách này. Đó là một nhiệm vụ bài tập về nhà tốt đẹp mặc dù.

+0

Hey Max, tốt ý tưởng về việc xóa thời gian chờ bằng cách sử dụng typeof mà không cần phải tạo rõ ràng biến toàn cầu :) – will824

3

Công việc tuyệt vời, Max, điều đó rất hữu ích đối với tôi!Tôi đã thực hiện một sự cải thiện nhẹ với chức năng của bạn bằng cách làm cho nó tổng quát hơn:

function afterDelayedEvent(eventtype, selector, action, delay) { 
    $(selector).bind(eventtype, function() { 
     if (typeof(window['inputTimeout']) != "undefined") { 
      clearTimeout(inputTimeout); 
     } 
     inputTimeout = setTimeout(action, delay); 
    }); 
} 

Bằng cách này bạn có thể sử dụng nó cho bất kỳ loại sự kiện, mặc dù KeyUp có lẽ là hữu ích nhất ở đây.

+0

Đẹp một Nicolas, cảm ơn :) –

7

Dưới đây là phần mở rộng của bạn ưa thích jquery:

(function($){ 

$.widget("ui.onDelayedKeyup", { 

    _init : function() { 
     var self = this; 
     $(this.element).keyup(function() { 
      if(typeof(window['inputTimeout']) != "undefined"){ 
       window.clearTimeout(inputTimeout); 
      } 
      var handler = self.options.handler; 
      window['inputTimeout'] = window.setTimeout(function() { 
       handler.call(self.element) }, self.options.delay); 
     }); 
    }, 
    options: { 
     handler: $.noop(), 
     delay: 500 
    } 

}); 
})(jQuery); 

Sử dụng nó như vậy:

$("input.filterField").onDelayedKeyup({ 
     handler: function() { 
      if ($.trim($(this).val()).length > 0) { 
       //reload my data store using the filter string. 
      } 
     } 
    }); 

Liệu một sự chậm trễ nửa giây theo mặc định.

+0

Làm việc tuyệt vời, cảm ơn Steven :) –

+0

Tôi muốn cắt giảm sử dụng để (dường như không thể có được định dạng đúng không?): 'var trimmedVal = $ .trim ($ (this) .val()); nếu (trimmedVal.length> 0) { // tải lại kho dữ liệu của tôi bằng chuỗi bộ lọc. } ' –

+0

Đúng, được chỉnh sửa. Cảm ơn. –

0

Tôi biết điều này là cũ, nhưng đó là một trong những kết quả đầu tiên khi tôi đang tìm kiếm cách làm một cái gì đó như thế này vì vậy tôi mặc dù tôi sẽ chia sẻ giải pháp của tôi. Tôi đã sử dụng kết hợp các câu trả lời được cung cấp để có được những gì tôi cần.

Tôi muốn một sự kiện tùy chỉnh hoạt động giống như các sự kiện jQuery hiện có và cần phải làm việc với keypress + xóa, lùi lại và nhập.

Dưới đây là jQuery plugin của tôi:

$.fn.typePause = function (dataObject, eventFunc) 
    { 
     if(typeof dataObject === 'function') 
     { 
      eventFunc = dataObject; 
      dataObject = {}; 
     } 
     if(typeof dataObject.milliseconds === 'undefined') 
      dataObject.milliseconds = 500; 
     $(this).data('timeout', null) 
      .keypress(dataObject, function(e) 
      { 
       clearTimeout($(this).data('timeout')); 
       $(this).data('timeout', setTimeout($.proxy(eventFunc, this, e), dataObject.milliseconds)); 
      }) 
      .keyup(dataObject, function(e) 
      { 
       var code = (e.keyCode ? e.keyCode : e.which); 
       if(code == 8 || code == 46 || code == 13) 
        $(this).triggerHandler('keypress',dataObject); 
      }); 
    } 

tôi đã sử dụng $.proxy() để bảo vệ bối cảnh trong sự kiện này, mặc dù có thể là một cách tốt hơn để làm điều này, hiệu suất-khôn ngoan.

Để sử dụng plugin này, chỉ cần làm:

$('#myElement').typePause(function(e){ /* do stuff */ }); 

hoặc

$('#myElement').typePause({milliseconds: 500, [other data to pass to event]},function(e){ /* do stuff */ });  
Các vấn đề liên quan