Kullanıcı anahtar yukarı yerine yazmayı bitirdiğinde javascript işlevi çalıştırılsın mı?


464

Kullanıcı bir metin kutusuna yazmayı bitirdiğinde bir ajax isteği tetiklemek istiyorum. Kullanıcı bir harf yazdığı her zaman işlevini çalıştırmak istemiyorum çünkü bu çok ajax istekleri LOT sonuçlanır, ancak ben de enter düğmesine vurmak zorunda istemiyorum.

Kullanıcı yazmayı bitirdikten sonra ajax isteği yapmak algılamak için bir yolu var mı?

Burada jQuery kullanıyor! Dave


21
Bence bizim için "yazmayı bitir" i tanımlamanız gerekecek.
Gerçeküstü Düşler

8
@Surreal Dreams'in yanıtı gereksinimlerinizin çoğunu karşılarken, kullanıcı belirtilen zaman aşımından SONRA tekrar yazmaya başlarsa, sunucuya birden fazla istek gönderilir. Aşağıdaki her XHR isteğini bir değişkende saklayan ve yenisini başlatmadan önce iptal eden cevabımı görün. Aslında Google, Anında aramalarında bunu yapar .
Marko


1
Bulanıklık ne olacak? Sanırım giriş elemanı odak kaybettiğinde kullanıcı yazmayı kesinlikle bitirdi.
Don P

3
Basit bir Google araması size basit cevabı alabilirdi: schier.co/blog/2014/12/08/…
Cannicide

Yanıtlar:


689

Yani, yazmayı bitirmeyi tahmin edeceğim, bir süreliğine durduğunuz anlamına gelir, 5 saniye. Bunu göz önünde bulundurarak, kullanıcı bir tuşu bıraktığında bir zamanlayıcı başlatabilir ve bir tuşa bastığında onu temizleyelim. Söz konusu girdinin #myInput olacağına karar verdim.

Birkaç varsayımda bulunmak ...

//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 5000;  //time in ms, 5 second for example
var $input = $('#myInput');

//on keyup, start the countdown
$input.on('keyup', function () {
  clearTimeout(typingTimer);
  typingTimer = setTimeout(doneTyping, doneTypingInterval);
});

//on keydown, clear the countdown 
$input.on('keydown', function () {
  clearTimeout(typingTimer);
});

//user is "finished typing," do something
function doneTyping () {
  //do something
}

4
Teşekkürler :) Soru hakkındaki yorumumu yazmaya başladım ve iyi bir fikrim olduğunu fark ettim.
Gerçeküstü Düşler

26
Bu cevap düzgün çalışmıyor, kullanıcı çok yavaş yazmazsa her zaman 5 saniye sonra tetiklenir. Aşağıdaki çalışma çözümüne bakın.
going

3
Burada sorunla karşılaşırsanız, zamanlayıcı hemen tetiklendiğinden, işlev çağrısının etrafına tırnak eklemeyi deneyin: setTimeout ('functionToBeCalled', doneTypingInterval);
Largo

3
doneTypingÖrnekte geri çağırma işlevinin hemen çalıştığı birkaç yorum görüyorum . Bu genellikle ()işlev adından sonra yanlışlıkla dahil olmanın bir sonucudur . Okumak gerektiğini Not setTimeout(doneTyping,değilsetTimeout(doneTyping(),
Anthony DiSanti

2
Böyle olay eklemek 'yapıştırmak' zorunda yapıştırmak ile işe @Jessica: ( 'yapıştırmak keyUp' üzerine,
Sergey

397

Yukarıda seçilen cevap işe yaramıyor.

TypingTimer sık ​​sık birkaç kez ayarlandığından (hızlı daktilolar vb. İçin tuşlar tetiklenmeden önce iki kez basıldığında) düzgün bir şekilde temizlenmez.

Aşağıdaki çözüm bu sorunu çözer ve bitirildikten sonra OP'nin istediği gibi X saniye arar. Ayrıca artık tuş kilidi işlevini de gerektirmez. Ayrıca, girişiniz boşsa işlev çağrınızın gerçekleşmemesi için bir kontrol ekledim.

//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 5000;  //time in ms (5 seconds)

//on keyup, start the countdown
$('#myInput').keyup(function(){
    clearTimeout(typingTimer);
    if ($('#myInput').val()) {
        typingTimer = setTimeout(doneTyping, doneTypingInterval);
    }
});

//user is "finished typing," do something
function doneTyping () {
    //do something
}

Ve aynı kod vanilya JavaScript çözümünde:

//setup before functions
let typingTimer;                //timer identifier
let doneTypingInterval = 5000;  //time in ms (5 seconds)
let myInput = document.getElementById('myInput');

//on keyup, start the countdown
myInput.addEventListener('keyup', () => {
    clearTimeout(typingTimer);
    if (myInput.value) {
        typingTimer = setTimeout(doneTyping, doneTypingInterval);
    }
});

//user is "finished typing," do something
function doneTyping () {
    //do something
}

Bu çözüm ES6 kullanır, ancak burada gerekli değildir. Sadece yerini letile varve düzenli fonksiyonu ile ok fonksiyonu.


5
Giriş boş olsa bile işlevi çağırmak yararlı olabilir. Giriş tekrar boş olduğunda bazı arama sonuçlarını (örneğin) silmek isterseniz ne olur?
rvighne

7
Ben de kullanıcı sadece macunlar alanın içinde dize gelir koşulunu düşünmeliyiz.
Vishal Nair

10
$('#myInput').on('input', function() {bunun kopyala ve yapıştır ile çalışmasını istiyorsanız kullanın . Girişin boş olup olmadığını kontrol etme noktasını görmüyorum. Diyelim ki bunu yazdığı şeyi silmek istiyorsa, ajax çağrısı yapamaz.
billynoah

3
Neden if ($('#myInput').val)yerine if ($('#myInput').val())? .valBir işlev olmalı mı ?
wlnirvana

4
Neden $ (this) .val () kullanmıyorsunuz?
JoelFan

76

Bu sadece bir satır ile underscore.js filtreleme fonksiyonu:

$('#my-input-box').keyup(_.debounce(doSomething , 500));

Bu temelde yazmayı bıraktıktan sonra doSomething 500 milisaniye diyor .

Daha fazla bilgi için: http://underscorejs.org/#debounce


5
JQuery için de mevcut gibi görünüyor: code.google.com/p/jquery-debounce ve github.com/diaspora/jquery-debounce
koppor

63
İnsanların "BİR KOD HATTI" nı eleştirel olarak önemli gördükleri beni şaşırtıyor. Harika. Yüklemek için 1.1k JS dosyası gerektiren bir kod satırı. Bunu küçümsemiyorum çünkü bir çözüm. Ama bir satır cesur şey beni rahatsız ediyor ve şişkinlik koduna yol açıyor.
Wolfie

1
@Wolfie çok kodun kabartmak konusunda sana katılıyorum ama Underscore ve Lodash üst iki bağlıydı-upon kamu altındadır NPM bu birçok kişi için tek satırlık çözüm olabilir bu yüzden.
Paul

3
@Paul Kütüphaneleri başka amaçlarla yüklüyorsanız, ortak kod kullanmanın iyi ve gerçekten faydalı olduğunu kabul ediyorum. Ancak, bir satırın amacı için bir K kodunun üzerine yüklenmek verimli değildir. Özellikle mobil platformlar giderek daha az sınırsız veri haline geliyor. Birçok Euro bölgesi de veriler için internet için para ödüyor. Bu yüzden makul olduğunda şişkinliğe dikkat etmek iyidir.
Wolfie

neden aldım:Uncaught ReferenceError: _ is not defined
Wilf

44

Evet, ajax isteğini tetikleyecek her bir key up olayında 2 saniyelik bir zaman aşımı süresi ayarlayabilirsiniz. Ayrıca XHR yöntemini saklayabilir ve bant genişliği daha da fazla kaydetmek için sonraki tuş basımı olaylarında iptal edebilirsiniz. İşte benim otomatik tamamlama komut dosyası için yazdığım bir şey.

var timer;
var x;

$(".some-input").keyup(function () {
    if (x) { x.abort() } // If there is an existing XHR, abort it.
    clearTimeout(timer); // Clear the timer so we don't end up with dupes.
    timer = setTimeout(function() { // assign timer a new timeout 
        x = $.getJSON(...); // run ajax request and store in x variable (so we can cancel)
    }, 2000); // 2000ms delay, tweak for faster/slower
});

Bu yardımcı olur umarım,

Marko


Bunu tavsiye etmezdim. Kod tetikleyiciler bir API isteği her zaman bir tuşa basıldığında. Ardından başka bir tuşa basıldığında isteği iptal eder. Bu çözüm, kullanıcı yazarken AJAX geri aramasının tetiklenmesini engellese de, sunucuyu isteklerle çekmeye devam edecektir.
lxg

Ixg, hayır bu olmayacak. Kullandığı clearTimeout işlevi, API çağrısını çağırmak için önceki Zaman Aşımı olaylarını siler.
John Smith

@JohnSmith, muhtemelen zamanlayıcıyı temizlemenin daha iyi olduğunu kabul etmiyorum, sonra xhr'un boş olup olmadığını veya durumunuz ne olursa olsun kontrol edin ve nihayetinde ajax çağrısı ile zamanlayıcıyı çalıştırın
Fleuv

20
var timer;
var timeout = 1000;

$('#in').keyup(function(){
    clearTimeout(timer);
    if ($('#in').val) {
        timer = setTimeout(function(){
            //do stuff here e.g ajax call etc....
             var v = $("#in").val();
             $("#out").html(v);
        }, timeout);
    }
});

tam örnek burada: http://jsfiddle.net/ZYXp4/8/


Bu benim için çalıştı, ancak kullanıcı metin kutusundan çıktığı zaman, o noktaya odak kaybettiği için bir keyup olayı alamayacağınızı unutmayın. Bunun yerine tuşa basılması sorunu çözüyor gibi görünüyor.
horatius83

12

Her iki ilk 2 cevap benim için çalışmıyor. İşte benim çözümüm:

var timeout = null;

$('#myInput').keyup(function() {
    clearTimeout(timeout);

    timeout = setTimeout(function() {
        //do stuff here
    }, 500);
});

11

Gerçeküstü Rüya'nın cevabını seviyorum ama "doneTyping" fonksiyonumun her tuşa basıldığında çalışacağını gördüm; yazmayı bıraktığınızda yalnızca bir kez ateş etmek yerine, işlev 5 kez tetiklenir.

Sorun, javascript setTimeout işlevinin ayarlanmış olan eski zaman aşımlarının üzerine yazmak veya öldürmek gibi görünmemesi, ancak bunu kendiniz yaparsanız çalışır! Eğer typingTimer ayarlanmışsa, setTimeout'tan hemen önce bir clearTimeout çağrısı ekledim. Aşağıya bakınız:

//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 5000;  //time in ms, 5 second for example

//on keyup, start the countdown
$('#myInput').on("keyup", function(){
    if (typingTimer) clearTimeout(typingTimer);                 // Clear if already set     
    typingTimer = setTimeout(doneTyping, doneTypingInterval);
});

//on keydown, clear the countdown 
$('#myInput').on("keydown", function(){
    clearTimeout(typingTimer);
});

//user is "finished typing," do something
function doneTyping () {
    //do something
}

Not: Bunu sadece Surreal Dream'in cevabına bir yorum olarak eklemek isterdim ama yeni bir kullanıcıyım ve yeterli itibarım yok. Afedersiniz!


10

Kabul edilen cevabı, macun gibi ek durumları ele alacak şekilde değiştirmek:

//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 2000;  //time in ms, 2 second for example
var $input = $('#myInput');

// updated events 
$input.on('input propertychange paste', function () {
    clearTimeout(typingTimer);
    typingTimer = setTimeout(doneTyping, doneTypingInterval);      
});

//user is "finished typing," do something
function doneTyping () {
  //do something
}

6

Bu durumda keyDown olayının gerekli olduğunu düşünmüyorum (lütfen neden yanlış olduğumu söyleyin). Benim (jquery olmayan) komut dosyasında benzer bir çözüm şöyle görünür:

var _timer, _timeOut = 2000; 



function _onKeyUp(e) {
    clearTimeout(_timer);
    if (e.keyCode == 13) {      // close on ENTER key
        _onCloseClick();
    } else {                    // send xhr requests
        _timer = window.setTimeout(function() {
            _onInputChange();
        }, _timeOut)
    }

}

Stack Overflow'daki ilk cevabım, bu yüzden umarım bu birisine yardımcı olur :)


6

Aşağıdaki delayişlevi bildirin :

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

ve sonra kullanın:

let $filter = $('#item-filter');
$filter.on('keydown', function () {
    delay(function () {            
        console.log('this will hit, once user has not typed for 1 second');            
    }, 1000);
});    

Çözümün harika, kardeşim!
Geliştirici

1
@Developer Çok teşekkürler. Ayrıca biraz daha karmaşık bir senaryo (sayfa başına birden fazla kontrol) çözmek için başka bir cevap ekledim.
Fabian Bigler

güzel çözüm. Bunu kullanıyorum ama 'giriş' olayını kullanarak im yerine keydown im
Budyn

Keyup etkinliği ile benim için harika çalıştı. Teşekkürler.
Sinan Eldem

6

Geç cevap ama ekliyorum çünkü 2019 ve bu tamamen güzel ES6, üçüncü taraf kütüphaneleri kullanılarak elde edilebilir ve yüksek puanlı cevapların çoğunun hantal ve çok fazla değişkenle tartıldığını görüyorum.

Bu mükemmel blog gönderisinden alınan zarif çözüm .

function debounce(callback, wait) {
  let timeout;
  return (...args) => {
      const context = this;
      clearTimeout(timeout);
      timeout = setTimeout(() => callback.apply(context, args), wait);
  };
}

window.addEventListener('keyup', debounce( () => {
    // code you would like to run 1000ms after the keyup event has stopped firing
    // further keyup events reset the timer, as expected
}, 1000))

1
Bu gerçekten yıl verilen en iyi cevap olmalı
Dark Hippo

4

Kullanıcı yazmayı ne zaman bitirdiğini tahmin edemediğinden, kesinlikle hayır. Tabii ki anahtar açıkken bir zamanlayıcıyı ateşleyebilir ve sonraki her anahtar açıldığında sıfırlayabilirsiniz. Zamanlayıcının süresi dolarsa, kullanıcı zamanlayıcı süresi için yazmamışsa - "yazmayı bitirmiş" diyebilirsiniz.

Kullanıcıların yazarken duraklama yapmasını bekliyorsanız, ne zaman yapıldıklarını bilmenin bir yolu yoktur.

(Tabii ki veriler bittikten sonra söyleyemezseniz)


3

Çözümün inputolayla biraz daha basit olduğunu hissediyorum :

var typingTimer;
var doneTypingInterval = 500;

$("#myInput").on("input", function () {
    window.clearTimeout(typingTimer);
    typingTimer = window.setTimeout(doneTyping, doneTypingInterval);
});

function doneTyping () {
    // code here
}

3

@going'un cevabına katılıyorum. Benim için işe yarayan bir diğer benzer çözüm, aşağıdaki çözümdür. Tek fark keyup yerine .on ("input" ...) kullanıyorum. Bu yalnızca girişteki değişiklikleri yakalar. Ctrl, Shift vb. diğer tuşlar yok sayılır.

var typingTimer;                //timer identifier
var doneTypingInterval = 5000;  //time in ms (5 seconds)

//on input change, start the countdown

$('#myInput').on("input", function() {    
    clearTimeout(typingTimer);
    typingTimer = setTimeout(function(){
        // doSomething...
    }, doneTypingInterval);
});

3

Ben sadece kullanıcı yazmayı bitirmek için beklemek için basit bir kod anladım:

adim 1. zaman aşımı değerini null olarak ayarlayın ve kullanıcı yazarken geçerli zaman aşımını silin.

adım 2. keyup olayı tetiklenmeden önce değişken tanımlamasının temiz zaman aşımını tetikleyin.

adım 3. zaman aşımını yukarıda açıklanan değişkene tanımlayın;

<input type="text" id="input" placeholder="please type" style="padding-left:20px;"/>
<div class="data"></div>

javascript kodu

var textInput = document.getElementById('input');
var textdata = document.querySelector('.data');
// Init a timeout variable to be used below
var timefired = null;

// Listen for keystroke events
// Init a timeout variable to be used below
var timefired = null;// Listen for keystroke events
textInput.onkeyup = function (event) {
clearTimeout(timefired);
timefired = setTimeout(function () {
    textdata.innerHTML = 'Input Value:'+ textInput.value;
  }, 600);
};

1
soru zaten cevaplandı ... ve buna oldukça benziyor
Mixone

3

Aramayı girişimde uyguluyordum ve ajax tabanlı olması gerekiyordu. Bu, her tuş değişikliğinde, aranan sonuçların güncellenmesi ve görüntülenmesi gerektiği anlamına gelir. Bu, sunucuya gönderilen çok sayıda ajax çağrısı ile sonuçlanır, bu iyi bir şey değildir.

Biraz çalıştıktan sonra, kullanıcı yazmayı bıraktığında sunucuya ping atmak için bir yaklaşım yaptım.

Bu çözüm benim için çalıştı:

$(document).ready(function() {
    $('#yourtextfield').keyup(function() {
        s = $('#yourtextfield').val();
        setTimeout(function() { 
            if($('#yourtextfield').val() == s){ // Check the value searched is the latest one or not. This will help in making the ajax call work when client stops writing.
                $.ajax({
                    type: "POST",
                    url: "yoururl",
                    data: 'search=' + s,
                    cache: false,
                    beforeSend: function() {
                       // loading image
                    },
                    success: function(data) {
                        // Your response will come here
                    }
                })
            }
        }, 1000); // 1 sec delay to check.
    }); // End of  keyup function
}); // End of document.ready

Bunu uygularken herhangi bir zamanlayıcı kullanmaya gerek olmadığını fark edeceksiniz.


2

Bu yazdığım basit bir JS kodu:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br" lang="pt-br">
<head><title>Submit after typing finished</title>
<script language="javascript" type="text/javascript">
function DelayedSubmission() {
    var date = new Date();
    initial_time = date.getTime();
    if (typeof setInverval_Variable == 'undefined') {
            setInverval_Variable = setInterval(DelayedSubmission_Check, 50);
    } 
}
function DelayedSubmission_Check() {
    var date = new Date();
    check_time = date.getTime();
    var limit_ms=check_time-initial_time;
    if (limit_ms > 800) { //Change value in milliseconds
        alert("insert your function"); //Insert your function
        clearInterval(setInverval_Variable);
        delete setInverval_Variable;
    }
}

</script>
</head>
<body>

<input type="search" onkeyup="DelayedSubmission()" id="field_id" style="WIDTH: 100px; HEIGHT: 25px;" />

</body>
</html>

1

Metin kutusunun odağı ne zaman kaybettiğini tespit etmek için onblur olayını kullanabilirsiniz: https://developer.mozilla.org/en/DOM/element.onblur

Bu, kullanıcının bir sürü şey yazdığı ve daha sonra metin kutusu hala odaklanmış olarak oturduğu duruma dikkat ederseniz, "yazmayı durdurur" ile aynı değildir.

Bunun için onclick olayına bir setTimeout bağlama ve hiçbir tuş vuruşları olmadan x süre sonra kullanıcı yazmayı bıraktığını varsayarak öneririm.


1

Neden sadece onfocusout'u kullanmıyorsunuz?

https://www.w3schools.com/jsreF/event_onfocusout.asp

Bu bir formsa, gönder düğmesini tıklatmak için her giriş alanının her zaman odağını terk ederler, böylece onfocusout olay işleyicisini çağırırken hiçbir girişin kaçırmayacağını bilirsiniz.


1
onfocusout'un soru sorulduğunda (neredeyse 7 yıl önce) zayıf bir desteği vardı ve ayrıca onfocusout ile olan etkisi biraz farklı olurdu. Zaman aşımı / geri dönme çözümü ile kullanıcı yazmayı durdurur ve kullanıcının odak değiştirmesi gerekmediğinde "tetiklenir", kullanıcının öğeye odaklanmasını beklemek zorunda kalacaksınız. Kullanım örneği, kullanıcı potansiyel kullanıcı adını girmeyi bıraktığında form alanının sağında adın kullanılabilir olduğunu belirten bir onay işareti veya "X" göründüğü kayıt formlarından biridir.
David Zorychta

arama çubuğu odakta ise, dışarı çıkmaya gerek yok, bir süre sonra doğrudan sonuç gösterilmeyecek şekilde doğrudan gösterilecek
P Satish Patro

1

Kullanıcının alandan uzaklaşması gerekiyorsa, Javascript'te Onchange yerine "onBlur" kullanabiliriz

  <TextField id="outlined-basic"  variant="outlined" defaultValue={CardValue} onBlur={cardTitleFn} />

Bu gerekli değilse zamanlayıcı ayarı iyi bir seçenek olacaktır.


0

Metin kutusuna odaklanmayı algıladıktan sonra, tuşa basma zaman aşımı kontrolü yapın ve her tetiklendiğinde sıfırlayın.

Zaman aşımı tamamlandığında, ajax isteğinizi yapın.


0

Belirli bir uzunluk (posta kodu alanı gibi) arıyorsanız:

$("input").live("keyup", function( event ){
if(this.value.length == this.getAttribute('maxlength')) {
        //make ajax request here after.
    }
  });

Ajax isteğini göndermeden önce sınırlı doğrulama yapmak kötü bir fikir değildir.
chim

0

İhtiyaçlarımın biraz garip olup olmadığından emin değilim, ama buna benzer bir şeye ihtiyacım vardı ve bunu kullanarak bitirdim:

$('input.update').bind('sync', function() {
    clearTimeout($(this).data('timer'));            
    $.post($(this).attr('data-url'), {value: $(this).val()}, function(x) {
        if(x.success != true) {
            triggerError(x.message);    
        }
    }, 'json');
}).keyup(function() {
    clearTimeout($(this).data('timer'));
    var val = $.trim($(this).val());
    if(val) {
        var $this = $(this);
        var timer = setTimeout(function() {
            $this.trigger('sync');
        }, 2000);
        $(this).data('timer', timer);
    }
}).blur(function() {
    clearTimeout($(this).data('timer'));     
    $(this).trigger('sync');
});

Hangi benim uygulamamda böyle elemanlara sahip olmamı sağlar:

<input type="text" data-url="/controller/action/" class="update">

Kullanıcı "yazmayı tamamladığında" (2 saniye boyunca hiçbir işlem yapılmazsa) veya başka bir alana (öğenin dışına bulanıklaştığında) güncellenen


0

Kullanıcı yazmayı bitirene kadar beklemeniz gerekiyorsa bunu basit kullanın:

$(document).on('change','#PageSize', function () {
    //Do something after new value in #PageSize       
});

Ajax çağrısı ile tam örnek - bu çağrı cihazı için çalışıyor - liste başına öğe sayısı:

$(document).ready(function () {
    $(document).on('change','#PageSize', function (e) {
        e.preventDefault();
        var page = 1;
        var pagesize = $("#PageSize").val();
        var q = $("#q").val();
        $.ajax({
            url: '@Url.Action("IndexAjax", "Materials", new { Area = "TenantManage" })',
            data: { q: q, pagesize: pagesize, page: page },
            type: 'post',
            datatype: "json",
            success: function (data) {
                $('#tablecontainer').html(data);
               // toastr.success('Pager has been changed', "Success!");
            },
            error: function (jqXHR, exception) {
                ShowErrorMessage(jqXHR, exception);
            }
        });  
    });
});    

0

Sayfa başına birden çok zamanlayıcı

Diğer tüm cevaplar sadece bir kontrol için çalışır ( diğer cevabım dahil). Sayfa başına birden fazla kontrolünüz varsa (örneğin, bir alışveriş sepetinde) yalnızca kullanıcının bir şey yazdığı son kontrol çağrılır . Benim durumumda bu kesinlikle istenen davranış değildir - her kontrolün kendi zamanlayıcısı olmalıdır.

Bunu çözmek için, işleve bir kimlik iletmeniz ve aşağıdaki kodda olduğu gibi bir timeoutHandles sözlüğünü tutmanız yeterlidir:

İşlev Beyanı:

var delayUserInput = (function () {
    var timeoutHandles = {};    
    return function (id, callback, ms) {        
        if (timeoutHandles[id]) {
            clearTimeout(timeoutHandles[id]);
        }

        timeoutHandles[id] = setTimeout(callback, ms);             
    };
})();

İşlev Kullanımı:

  delayUserInput('yourID', function () {
     //do some stuff
  }, 1000);

0

Basit ve kolay anlaşılır.

var mySearchTimeout;
$('#ctl00_mainContent_CaseSearch').keyup(function () {
   clearTimeout(mySearchTimeout);
   var filter = $(this).val();
   mySearchTimeout = setTimeout(function () { myAjaxCall(filter); }, 700);
   return true;
});

0

ES6 sözdizimi ile birlikte parametreleri işlevinize iletmek için.

$(document).ready(() => {
    let timer = null;
     $('.classSelector').keydown(() => {
     clearTimeout(timer); 
     timer = setTimeout(() => foo('params'), 500);
  });
});

const foo = (params) => {
  console.log(`In foo ${params}`);
}

-2

Vay, 3 yorum bile oldukça doğru!

  1. Boş giriş, işlev çağrısını atlamak için bir neden değildir, örneğin yeniden yönlendirmeden önce atık parametresini url'den kaldırırım

  2. .on ('input', function() { ... });tetiklemek için kullanılması gerektiğini keyup, pastevechange olaylar

  3. kesinlikle .val()ya.value kullanılmalıdır

  4. Bunun $(this)yerine inside olayı işlevini kullanabilirsiniz#idBirden çok girişle çalışmak

  5. (benim kararım) ben yerine anonim işlevini kullanın doneTypingiçinde setTimeoutkolayca erişmek için $(this)n.4 gelen, ancak öncelikle gibi kaydetmeniz gerekirvar $currentInput = $(this);

EDIT Bazı insanların hazır kodu kopyalama-yapıştırma imkanı olmadan yönleri anlamadığını görüyorum. İşte burdasın

var typingTimer;
//                  2
$("#myinput").on('input', function () {
    //             4     3
    var input = $(this).val();
    clearTimeout(typingTimer);
    //                           5
    typingTimer = setTimeout(function() {
        // do something with input
        alert(input);
    }, 5000);      
});

Bu soruyu nasıl cevaplıyor?
Thomas Orlita

@ThomasOrlita bu cevap en çok oy alan 3 yanıtı destekliyor. Kabul edilene bir göz atın: 1. desteklemiyor paste, kullanmıyor this, vb. (Bence önemli ama tonlarca yorumda kaybolmak istemiyorum)
vladkras

1
Bu soruya cevap vermiyor. Başka bir cevap hakkında yorum yapmak isterseniz, bir yorum sistemi var (şu anda kullanıyorum!)
GrayedFox
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.