วิธีการหน่วงเวลาตัวจัดการ. keyup () จนกว่าผู้ใช้จะหยุดพิมพ์


642

ฉันมีช่องค้นหา ตอนนี้มันค้นหาทุกปุ่มกด ดังนั้นหากมีคนพิมพ์“ Windows” มันจะทำการค้นหาด้วย AJAX สำหรับทุกการกดปุ่ม:“ W”,“ Wi”,“ Win”,“ Wind”,“ Windo”,“ Windo”,“ Window”,“ Windows”

ฉันต้องการความล่าช้าดังนั้นจึงค้นหาได้เฉพาะเมื่อผู้ใช้หยุดพิมพ์เป็นเวลา 200 มิลลิวินาที

ไม่มีตัวเลือกสำหรับสิ่งนี้ในkeyupฟังก์ชั่นและฉันได้ลองsetTimeoutแล้ว แต่มันไม่ทำงาน

ฉันจะทำสิ่งนั้นได้อย่างไร



2
หากฉันทำได้ฉันจะปิดสิ่งนี้ซ้ำซ้อน
a432511

7
ฉันไม่เห็นอันตรายจากการซ้ำซ้อนตราบใดที่คำตอบที่ได้รับและยอมรับนั้นถูกต้อง การเพิ่มลงในฐานข้อมูลของคำถามจะต้องเป็นสิ่งที่ดีและสิ่งที่จะต้องทำ
Mattis

14
อันตรายคือผู้คนในอนาคตจะไม่สามารถได้รับประโยชน์จากคำตอบที่ยอดเยี่ยมที่ทุกคนแบ่งปันหากมีคำถามเดียวกัน 100 ข้อดังนั้นการปิดทวีคูณและการเปลี่ยนเส้นทางทุกคนไปยังคำถามเดิมนั้นดีกว่าสำหรับการหาแนวทางปฏิบัติที่ดีที่สุด ดูstackoverflow.com/help/duplicatesสำหรับข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุที่ปิดรายการซ้ำ
rncrtr

14
นี่เป็นวิธีที่ได้รับความนิยมมากกว่าภาพที่คาดคะเนซ้ำ เป็นคำที่ดีกว่ามีคำตอบที่ดีกว่ามีอันดับสูงขึ้นใน google ฯลฯ .. หลายคนได้รับประโยชน์จากคำตอบนี้ เมื่อมองย้อนกลับไปมันจะเป็นเรื่องน่าละอายหากถูกปิด มีบางเรื่องที่ไม่ดีที่ซ้ำกัน แต่ไม่ได้อยู่ในหมวดหมู่นั้น
ผู้ใช้

คำตอบ:


1124

ฉันใช้ฟังก์ชั่นเล็ก ๆ นี้เพื่อจุดประสงค์เดียวกันโดยการรันฟังก์ชั่นหลังจากผู้ใช้หยุดพิมพ์ตามระยะเวลาที่กำหนดหรือในเหตุการณ์ที่เกิดขึ้นในอัตราที่สูงเช่นresize:

function delay(callback, ms) {
  var timer = 0;
  return function() {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      callback.apply(context, args);
    }, ms || 0);
  };
}


// Example usage:

$('#input').keyup(delay(function (e) {
  console.log('Time elapsed!', this.value);
}, 500));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="input">Try it:
<input id="input" type="text" placeholder="Type something here..."/>
</label>

มันทำงานอย่างไร:

delayฟังก์ชั่นจะกลับมาฟังก์ชั่นภายในห่อที่จับจับเวลาของแต่ละบุคคลในแต่ละการดำเนินการจับเวลาจะเริ่มต้นใหม่กับการหน่วงเวลาที่ให้ไว้ถ้าหลายประหารชีวิตเกิดขึ้นก่อนที่เวลาผ่านไปนี้จับเวลาจะเพียงแค่ตั้งค่าและเริ่มต้นอีกครั้ง

เมื่อตัวจับเวลาสิ้นสุดลงฟังก์ชันการเรียกกลับจะดำเนินการผ่านบริบทและข้อโต้แย้งเดิม (ในตัวอย่างนี้วัตถุเหตุการณ์ของ jQuery และองค์ประกอบ DOM เป็นthis)

อัพเดท 2019-05-16

ฉันได้ติดตั้งฟังก์ชั่นใหม่โดยใช้คุณสมบัติ ES5 และ ES6 สำหรับสภาพแวดล้อมที่ทันสมัย:

function delay(fn, ms) {
  let timer = 0
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(fn.bind(this, ...args), ms || 0)
  }
}

การดำเนินงานที่ถูกปกคลุมด้วยชุดของการทดสอบ

สำหรับสิ่งที่ซับซ้อนยิ่งขึ้นลองดูที่ปลั๊กอินjQuery Typewatch


64
อีกหนึ่งทางเลือก: github.com/bgrins/bindWithDelay/blob/master/bindWithDelay.js มันใช้งานได้ดีเหมือนกับที่คุณอธิบายฉันเพิ่งพบว่าตัวเองใช้รูปแบบนั้นมากดังนั้นจึงติดตั้งเป็นปลั๊กอิน jQuery เพื่อทำให้ไวยากรณ์ง่ายขึ้น นี่คือหน้าตัวอย่าง: briangrinstead.com/files/bindWithDelay
Brian Grinstead

2
ฉันเริ่ม hardcoded จำนวนตัวอักษรที่พิมพ์วิธีนี้จะราบรื่นเหมือนกากน้ำตาล (โดยไม่ต้อง sulfer)
Har

2
เมื่อฉันใช้สิ่งนี้ด้วย $. โพสต์ () มันจะส่งทุกอย่างที่พิมพ์ในเวลาเดียวกัน แต่มันจะส่งมันหลายครั้งตามที่ฉันมีคีย์อัพ มีวิธีการส่งเฉพาะเมื่อหมดเวลาหรือไม่
ntgCleaner

7
แต่วิธีนี้ใช้ไม่ได้หากฉันเรียกใช้ฟังก์ชันที่แตกต่างกันสองฟังก์ชันขึ้นไปที่ต้องการความล่าช้าเฉพาะบุคคล ฉันทำโซลูชันนี้แทนstackoverflow.com/a/30503848/1834212
Miguel

4
ฉันแนะนำปลั๊กอิน 'bindWithDelay' ที่ลิงก์ในความคิดเห็นด้านบน แต่ฉันแนะนำคำตอบของ @ Hazerider สำหรับคำถามนี้ (ด้านล่าง - stackoverflow.com/a/19259625/368896 ) ซึ่งดีกว่าคำตอบนี้และควรเรียนรู้ที่จะเข้าใจความคิดที่เรียบง่ายและผูกพันเพื่อให้ตัวจับเวลาที่แตกต่างกันสำหรับองค์ประกอบที่แตกต่างกัน หลักการเดียวกันนี้ใช้ในรหัสปลั๊กอินด้านบน แต่เข้าใจง่ายขึ้น
Dan Nissenbaum

60

หากคุณต้องการค้นหาหลังจากพิมพ์เสร็จแล้วให้ใช้ตัวแปรโกลบอลเพื่อระงับการหมดเวลาที่ส่งคืนจากการsetTimoutโทรของคุณและยกเลิกด้วยclearTimeoutถ้าถ้ามันยังไม่เกิดขึ้นเพื่อที่จะไม่เริ่มต้นการหมดเวลายกเว้นในkeyupเหตุการณ์สุดท้าย

var globalTimeout = null;  
$('#id').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
}   
function SearchFunc(){  
  globalTimeout = null;  
  //ajax code
}

หรือด้วยฟังก์ชั่นที่ไม่ระบุชื่อ:

var globalTimeout = null;  
$('#id').keyup(function() {
  if (globalTimeout != null) {
    clearTimeout(globalTimeout);
  }
  globalTimeout = setTimeout(function() {
    globalTimeout = null;  

    //ajax code

  }, 200);  
}   

39

อีกการปรับปรุงเล็กน้อยในคำตอบของ CMS เพื่อให้สามารถแยกความล่าช้าได้ง่ายคุณสามารถใช้สิ่งต่อไปนี้:

function makeDelay(ms) {
    var timer = 0;
    return function(callback){
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
};

หากคุณต้องการนำความล่าช้าเดิมกลับมาใช้ใหม่ให้ทำ

var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});

หากคุณต้องการความล่าช้าแยกจากกันคุณสามารถทำได้

$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});

1
น่าสนใจว่าโซลูชันที่มีผู้อัปโหลดมากกว่า 600 คนในวันที่ฉันเขียนความคิดเห็นนี้ไม่ดีเท่าคำตอบนี้โดยมีเพียง upvotes เพียง 2 คน (รวมถึงของฉัน) ดีกว่าอย่างชัดเจนเพราะรองรับวิดเจ็ตหลายตัวที่สามารถแชร์หรือไม่แชร์คือความล่าช้า คำตอบที่ยอดเยี่ยม
Dan Nissenbaum

... แม้ว่าปลั๊กอิน jQuery ในความคิดเห็นด้านล่างคำตอบยังจัดการตัวจับเวลาแยกต่างหากสำหรับองค์ประกอบที่แยกต่างหากและเพิ่มอาร์กิวเมนต์เค้น & เหตุการณ์เช่นกัน: github.com/bgrins/bindWithDelay/blob/master/bindWithDelay.js วิธีการทั่วไปของปลั๊กอินนั้นเหมือนกับโค้ดของคุณดังนั้นโค้ดของคุณจึงควรศึกษาอย่างละเอียดเพื่อทำความเข้าใจกับความเรียบง่ายก่อนที่จะพยายามทำความเข้าใจกับปลั๊กอินที่ซับซ้อนกว่านี้ ฉันขอแนะนำให้ใช้ปลั๊กอินนั้น - แต่ถ้าคุณไม่ต้องการเค้นหรือผ่านข้อมูลเหตุการณ์รหัสของคุณยอดเยี่ยมมาก! สองตัวเลือกที่ดี ขอบคุณ!
Dan Nissenbaum

1
อืมมันทำให้ฉันล่าช้า แต่someApiCallก็ยังทริกเกอร์หลายครั้ง - ตอนนี้มีค่าสุดท้ายของฟิลด์อินพุต
Roelant


14

จากคำตอบของ CMS ฉันทำสิ่งนี้:

ใส่รหัสด้านล่างหลังจากรวม jQuery:

/*
 * delayKeyup
 * http://code.azerti.net/javascript/jquery/delaykeyup.htm
 * Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
 * Written by Gaten
 * Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
 */
(function ($) {
    $.fn.delayKeyup = function(callback, ms){
        var timer = 0;
        $(this).keyup(function(){                   
            clearTimeout (timer);
            timer = setTimeout(callback, ms);
        });
        return $(this);
    };
})(jQuery);

และใช้อย่างนี้:

$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);

ข้อควรระวัง: ตัวแปร $ (นี่) ในฟังก์ชั่นที่ส่งผ่านเนื่องจากพารามิเตอร์ไม่ตรงกับอินพุต


12

หน่วงเวลาการใช้มัลติฟังก์ชั่นโดยใช้ป้ายกำกับ

นี่คือทางออกที่ฉันทำงานด้วย มันจะชะลอการดำเนินการใด ๆ เกี่ยวกับฟังก์ชั่นที่คุณต้องการ อาจเป็นข้อความค้นหาแบบเลื่อนลงอาจเป็นการคลิกอย่างรวดเร็วที่ปุ่มก่อนหน้าหรือถัดไป สิ่งนี้ใช้ออบเจกต์โกลบอลที่เก็บแต่ละครั้งที่เรียกใช้งานและเปรียบเทียบกับคำขอปัจจุบันมากที่สุด

ดังนั้นผลลัพธ์คือคลิก / การกระทำล่าสุดเท่านั้นที่จะถูกเรียกเนื่องจากการร้องขอเหล่านั้นถูกเก็บไว้ในคิวหลังจากเรียก X มิลลิวินาทีหากไม่มีการร้องขออื่นที่มีป้ายชื่อเดียวกันอยู่ในคิว!

function delay_method(label,callback,time){
    if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}  
    delayed_methods[label]=Date.now();
    var t=delayed_methods[label];
    setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{  delayed_methods[label]=""; callback();}}, time||500);
  }

คุณสามารถตั้งค่าเวลาหน่วงของคุณเอง (เป็นทางเลือกค่าเริ่มต้นเป็น 500ms) และส่งข้อโต้แย้งการทำงานของคุณใน "แฟชั่นปิด"

ตัวอย่างเช่นถ้าคุณต้องการเรียกฟังก์ชั่นการร้อง:

function send_ajax(id){console.log(id);}

หากต้องการป้องกันคำขอ send_ajax หลายคำขอคุณจะล่าช้าโดยใช้:

delay_method( "check date", function(){ send_ajax(2); } ,600);

ทุกคำขอที่ใช้ป้ายกำกับ "วันที่ตรวจสอบ" จะถูกทริกเกอร์เฉพาะในกรณีที่ไม่มีการร้องขออื่น ๆ ภายในระยะเวลา 600 มิลลิวินาที อาร์กิวเมนต์นี้เป็นทางเลือก

ป้ายกำกับความเป็นอิสระ (เรียกใช้ฟังก์ชันเป้าหมายเดียวกัน) แต่เรียกใช้ทั้งสอง:

delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});

ผลลัพธ์ในการเรียกใช้ฟังก์ชันเดียวกัน แต่หน่วงเวลาอย่างอิสระเนื่องจากฉลากของพวกเขาแตกต่างกัน


ฉันกำลังใช้รหัสของคุณในโครงการที่ฉันกำลังทำงานและมีปัญหากับมัน มันไม่ได้ล่าช้าอะไรจริง ๆ คิดว่าคุณอาจต้องการเห็น / ให้ความช่วยเหลือ stackoverflow.com/questions/51393779/…
KDJ

10

วิธีการง่ายสุดออกแบบมาเพื่อเรียกใช้ฟังก์ชันหลังจากผู้ใช้พิมพ์ในช่องข้อความเสร็จแล้ว ...

<script type="text/javascript">
$(document).ready(function(e) {
    var timeout;
    var delay = 2000;   // 2 seconds

    $('.text-input').keyup(function(e) {
        console.log("User started typing!");
        if(timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
            myFunction();
        }, delay);
    });

    function myFunction() {
        console.log("Executing function for user!");
    }
});
</script>

<textarea name="text-input" class="text-input"></textarea>

1
ขอบคุณ! คำตอบที่ได้รับความนิยมดังกล่าวไม่ทำงาน ... แต่คำแนะนำของคุณทำงานได้อย่างสมบูรณ์
user2662680

1
2020 ยังคงใช้งานได้
Romel Indemne

9

หากมีคนชอบที่จะชะลอการทำงานของฟังก์ชั่นเดียวกันและไม่มีตัวแปรภายนอกเขาสามารถใช้สคริปต์ต่อไป:

function MyFunction() {

    //Delaying the function execute
    if (this.timer) {
        window.clearTimeout(this.timer);
    }
    this.timer = window.setTimeout(function() {

        //Execute the function code here...

    }, 500);
}

1
ที่ดี! ทางออกง่าย ๆ ที่ใช้งานได้ดี!
Fellipe Sanches

1
ฉันชอบอันนี้ ไม่สามารถใช้ซ้ำได้ แต่เข้าใจง่าย
Vincent

7

ฟังก์ชั่นนี้ขยายฟังก์ชั่นจากคำตอบของ Gaten เล็กน้อยเพื่อให้ได้องค์ประกอบคืน:

$.fn.delayKeyup = function(callback, ms){
    var timer = 0;
    var el = $(this);
    $(this).keyup(function(){                   
    clearTimeout (timer);
    timer = setTimeout(function(){
        callback(el)
        }, ms);
    });
    return $(this);
};

$('#input').delayKeyup(function(el){
    //alert(el.val());
    // Here I need the input element (value for ajax call) for further process
},1000);

http://jsfiddle.net/Us9bu/2/


6

ฉันประหลาดใจที่ไม่มีใครพูดถึงปัญหาของอินพุตหลายรายการใน CMS ที่ดีมาก

โดยทั่วไปคุณจะต้องกำหนดตัวแปรล่าช้าเป็นรายบุคคลสำหรับแต่ละอินพุต มิฉะนั้นถ้า sb ใส่ข้อความไปที่อินพุตแรกและข้ามไปยังอินพุตอื่นอย่างรวดเร็วและเริ่มพิมพ์ให้โทรกลับไปหาอันแรกที่ไม่ถูกเรียก!

ดูรหัสด้านล่างฉันมาพร้อมกับคำตอบอื่น ๆ :

(function($) {
    /**
     * KeyUp with delay event setup
     * 
     * @link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
     * @param function callback
     * @param int ms
     */
    $.fn.delayKeyup = function(callback, ms){
            $(this).keyup(function( event ){
                var srcEl = event.currentTarget;
                if( srcEl.delayTimer )
                    clearTimeout (srcEl.delayTimer );
                srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
            });

        return $(this);
    };
})(jQuery);

โซลูชันนี้จะอ้างอิง setTimeout ภายในตัวแปร delayTimer ของอินพุต นอกจากนี้ยังผ่านการอ้างอิงขององค์ประกอบการโทรกลับตามที่แนะนำ fazzyx

ทดสอบใน IE6, 8 (comp - 7), 8 และ Opera 12.11


ลองใช้วิธีนี้แล้ว แต่ไม่สามารถทำงานได้อย่างถูกต้องในการกดคีย์ครั้งแรก
Lars Thorén

6

สิ่งนี้ใช้ได้กับฉันเมื่อฉันล่าช้าการดำเนินการตรรกะการค้นหาและตรวจสอบว่าค่าเหมือนกันกับที่ป้อนในฟิลด์ข้อความ ถ้าค่าเหมือนกันฉันจะดำเนินการและดำเนินการกับข้อมูลที่เกี่ยวข้องกับค่าการค้นหา

$('#searchText').on('keyup',function () {
    var searchValue = $(this).val();
    setTimeout(function(){
        if(searchValue == $('#searchText').val() && searchValue != null && searchValue != "") {
           // logic to fetch data based on searchValue
        }
        else if(searchValue == ''){
           // logic to load all the data
        }
    },300);
});

ไม่ทำงานอย่างที่คาดไว้จำนวนการดึงข้อมูลเหมือนเดิมเพิ่งล่าช้า 300 มิลลิวินาที - คุณต้องใช้ฟังก์ชั่น clearTimeout () ในทุกการกดแป้นก่อนที่จะดำเนินการ setTimeout ()
Picard

คุณไม่จำเป็นต้องใช้ clearTimeout ในกรณีนี้ เงื่อนไข searchValue == $ ('# searchText'). val () ภายใน setTimeout จะตรวจสอบให้แน่ใจว่าค่านั้นเหมือนกับค่าเดิมเมื่อ 300ms ที่ผ่านมาหรือไม่ แจ้งให้เราทราบหากนี่เหมาะสม ขอบคุณ
ซาก้ากาลา

4

ฟังก์ชั่นการหน่วงเวลาเพื่อเรียกใช้ทุกปุ่มกด ต้องใช้ jQuery 1.7.1 ขึ้นไป

jQuery.fn.keyupDelay = function( cb, delay ){
  if(delay == null){
    delay = 400;
  }
  var timer = 0;
  return $(this).on('keyup',function(){
    clearTimeout(timer);
    timer = setTimeout( cb , delay );
  });
}

การใช้งาน: $('#searchBox').keyupDelay( cb );


3

นี่เป็นวิธีการแก้ปัญหาตามแนวของ CMS แต่แก้ปัญหาสำคัญบางประการสำหรับฉัน:

  • รองรับอินพุตหลายอินพุต, ความล่าช้าสามารถทำงานพร้อมกันได้
  • ละเว้นเหตุการณ์สำคัญที่ไม่ได้เปลี่ยนค่า (เช่น Ctrl, Alt + Tab)
  • แก้ไขเงื่อนไขการแย่งชิง (เมื่อดำเนินการติดต่อกลับและเปลี่ยนค่าไปแล้ว)
var delay = (function() {
    var timer = {}
      , values = {}
    return function(el) {
        var id = el.form.id + '.' + el.name
        return {
            enqueue: function(ms, cb) {
                if (values[id] == el.value) return
                if (!el.value) return
                var original = values[id] = el.value
                clearTimeout(timer[id])
                timer[id] = setTimeout(function() {
                    if (original != el.value) return // solves race condition
                    cb.apply(el)
                }, ms)
            }
        }
    }
}())

การใช้งาน:

signup.key.addEventListener('keyup', function() {
    delay(this).enqueue(300, function() {
        console.log(this.value)
    })
})

รหัสเขียนในสไตล์ที่ฉันชอบคุณอาจต้องเพิ่มเซมิโคลอนจำนวนมาก

สิ่งที่ควรทราบ:

  • id ที่ไม่ซ้ำกันถูกสร้างขึ้นตาม id ของแบบฟอร์มและชื่ออินพุตดังนั้นจึงต้องมีการกำหนดและไม่ซ้ำกันหรือคุณสามารถปรับให้เข้ากับสถานการณ์ของคุณ
  • ความล่าช้าส่งคืนวัตถุที่ขยายได้ง่ายตามความต้องการของคุณ
  • องค์ประกอบดั้งเดิมที่ใช้สำหรับการหน่วงเวลาจะถูกผูกไว้กับการเรียกกลับดังนั้นthisทำงานตามที่คาดไว้ (เช่นในตัวอย่าง)
  • ค่าว่างจะถูกละเว้นในการตรวจสอบที่สอง
  • ระวังenqueueก็คาดว่ามิลลิวินาทีแรกที่ผมชอบว่า setTimeoutแต่คุณอาจต้องการที่จะเปลี่ยนพารามิเตอร์ที่จะมีการแข่งขัน

โซลูชันที่ฉันใช้เพิ่มระดับความซับซ้อนอีกระดับช่วยให้คุณสามารถยกเลิกการประมวลผลได้ แต่นี่เป็นฐานที่ดีในการสร้าง


3

การรวมคำตอบ CMS เข้ากับคำตอบของมิเกลทำให้ได้โซลูชันที่มีประสิทธิภาพซึ่งช่วยให้เกิดความล่าช้าพร้อมกัน

var delay = (function(){
    var timers = {};
    return function (callback, ms, label) {
        label = label || 'defaultTimer';
        clearTimeout(timers[label] || 0);
        timers[label] = setTimeout(callback, ms);
    };
})();

เมื่อคุณต้องการชะลอการกระทำที่แตกต่างกันอย่างอิสระให้ใช้อาร์กิวเมนต์ที่สาม

$('input.group1').keyup(function() {
    delay(function(){
        alert('Time elapsed!');
    }, 1000, 'firstAction');
});

$('input.group2').keyup(function() {
    delay(function(){
        alert('Time elapsed!');
    }, 1000, '2ndAction');
});

3

สร้างคำตอบของ CMS ที่นี่ต่อไปนี้เป็นวิธีการหน่วงเวลาใหม่ซึ่งจะรักษา 'this' ไว้ในการใช้งาน:

var delay = (function(){
  var timer = 0;
  return function(callback, ms, that){
    clearTimeout (timer);
    timer = setTimeout(callback.bind(that), ms);
  };
})();

การใช้งาน:

$('input').keyup(function() {
    delay(function(){
      alert('Time elapsed!');
    }, 1000, this);
});

2

ใช้

mytimeout = setTimeout( expression, timeout );

โดยที่ expression เป็นสคริปต์ที่จะใช้งานและการหมดเวลาคือเวลาที่จะรอเป็นมิลลิวินาทีก่อนที่จะทำงาน - สิ่งนี้ไม่ได้เป็นการแฮกสคริปต์ แต่เพียงชะลอการดำเนินการของส่วนนั้นจนกว่าการหมดเวลาจะเสร็จสิ้น

clearTimeout(mytimeout);

จะรีเซ็ต / ล้างการหมดเวลาดังนั้นจึงไม่เรียกใช้สคริปต์ในนิพจน์ (เช่นการยกเลิก) ตราบใดที่ยังไม่ได้ดำเนินการ


2

จากคำตอบของ CMS มันจะไม่สนใจเหตุการณ์สำคัญที่ไม่เปลี่ยนแปลงค่า

var delay = (function(){
    var timer = 0;
    return function(callback, ms){
      clearTimeout (timer);
      timer = setTimeout(callback, ms);
    };
})(); 

var duplicateFilter=(function(){
  var lastContent;
  return function(content,callback){
    content=$.trim(content);
    if(content!=lastContent){
      callback(content);
    }
    lastContent=content;
  };
})();

$("#some-input").on("keyup",function(ev){

  var self=this;
  delay(function(){
    duplicateFilter($(self).val(),function(c){
        //do sth...
        console.log(c);
    });
  }, 1000 );


})


1
var globalTimeout = null;  
$('#search').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
});
function SearchFunc(){  
  globalTimeout = null;  
  console.log('Search: '+$('#search').val());
  //ajax code
};

1

นี่คือข้อเสนอแนะที่ฉันได้เขียนซึ่งดูแลอินพุตหลายรายการในแบบฟอร์มของคุณ

ฟังก์ชั่นนี้ได้รับวัตถุของช่องใส่ใส่รหัสของคุณ

function fieldKeyup(obj){
    //  what you want this to do

} // fieldKeyup

นี่คือฟังก์ชั่น delayCall ที่เกิดขึ้นจริงดูแลหลายฟิลด์อินพุต

function delayCall(obj,ms,fn){
    return $(obj).each(function(){
    if ( typeof this.timer == 'undefined' ) {
       // Define an array to keep track of all fields needed delays
       // This is in order to make this a multiple delay handling     
          function
        this.timer = new Array();
    }
    var obj = this;
    if (this.timer[obj.id]){
        clearTimeout(this.timer[obj.id]);
        delete(this.timer[obj.id]);
    }

    this.timer[obj.id] = setTimeout(function(){
        fn(obj);}, ms);
    });
}; // delayCall

การใช้งาน:

$("#username").on("keyup",function(){
    delayCall($(this),500,fieldKeyup);
});

1

จากES6เราสามารถใช้ไวยากรณ์ฟังก์ชันลูกศรได้เช่นกัน

ในตัวอย่างนี้รหัสล่าช้าkeyupเหตุการณ์ 400ms หลังจากผู้ใช้เสร็จสิ้นการพิมพ์ก่อนการโทรsearchFuncทำการร้องขอแบบสอบถาม

const searchbar = document.getElementById('searchBar');
const searchFunc = // any function

// wait ms (milliseconds) after user stops typing to execute func
const delayKeyUp = (() => {
    let timer = null;
    const delay = (func, ms) => {
        timer ? clearTimeout(timer): null
        timer = setTimeout(func, ms)
    }
    return delay
})();

searchbar.addEventListener('keyup', (e) => {
    const query = e.target.value;
    delayKeyUp(() => {searchFunc(query)}, 400);
})

1

jQuery :

var timeout = null;
$('#input').keyup(function() {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
      console.log($(this).val());
  }, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<input type="text" id="input" placeholder="Type here..."/>

จาวาสคริปต์เพียว:

let input = document.getElementById('input');
let timeout = null;

input.addEventListener('keyup', function (e) {
    clearTimeout(timeout);
    timeout = setTimeout(function () {
        console.log('Value:', input.value);
    }, 1000);
});
<input type="text" id="input" placeholder="Type here..."/>


0

ลองดูที่ปลั๊กอินเติมข้อความอัตโนมัติ ฉันรู้ว่ามันช่วยให้คุณระบุความล่าช้าหรือจำนวนอักขระขั้นต่ำ แม้ว่าคุณจะไม่ได้ใช้ปลั๊กอินการมองผ่านโค้ดจะให้แนวคิดบางอย่างเกี่ยวกับวิธีการใช้งานด้วยตนเอง


0

ฉันได้สร้างโค้ดสำหรับ จำกัด ajax ความถี่สูงที่ทำให้เกิดการร้องขอโดย Keyup / Keydown ลองดู:

https://github.com/raincious/jQueue

ทำแบบสอบถามของคุณเช่นนี้:

var q = new jQueue(function(type, name, callback) {
    return $.post("/api/account/user_existed/", {Method: type, Value: name}).done(callback);
}, 'Flush', 1500); // Make sure use Flush mode.

และผูกเหตุการณ์เช่นนี้:

$('#field-username').keyup(function() {
    q.run('Username', this.val(), function() { /* calling back */ });
});

0

เห็นนี่วันนี้สายไปหน่อย แต่อยากเอานี่ไว้ในกรณีที่คนอื่นต้องการ เพียงแยกฟังก์ชั่นเพื่อให้สามารถใช้งานซ้ำได้ โค้ดด้านล่างจะรอ 1/2 วินาทีหลังจากพิมพ์หยุด

    var timeOutVar
$(selector).on('keyup', function() {

                    clearTimeout(timeOutVar);
                    timeOutVar= setTimeout(function(){ console.log("Hello"); }, 500);
                });


0
// Get an global variable isApiCallingInProgress

//  check isApiCallingInProgress 
if (!isApiCallingInProgress) {
// set it to isApiCallingInProgress true
      isApiCallingInProgress = true;

      // set timeout
      setTimeout(() => {
         // Api call will go here

        // then set variable again as false
        isApiCallingInProgress = false;     
      }, 1000);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.