Jalankan fungsi javascript saat pengguna selesai mengetik, bukan pada tombol?

463

Saya ingin memicu permintaan ajax ketika pengguna selesai mengetik dalam kotak teks. Saya tidak ingin menjalankan fungsi pada setiap kali pengguna mengetik surat karena itu akan menghasilkan BANYAK permintaan ajax, namun saya tidak ingin mereka harus menekan tombol enter juga.

Apakah ada cara agar saya bisa mendeteksi ketika pengguna selesai mengetik dan kemudian melakukan permintaan ajax?

Menggunakan jQuery di sini! Dave

David Zorychta
sumber
21
Saya pikir Anda harus mendefinisikan "selesai mengetik" untuk kami.
Surreal Dreams
8
Sementara jawaban @Surreal Dreams memenuhi sebagian besar kebutuhan Anda, jika pengguna mulai mengetik lagi SETELAH batas waktu yang ditentukan, beberapa permintaan akan dikirim ke server. Lihat jawaban saya di bawah ini yang menyimpan setiap permintaan XHR dalam sebuah variabel dan membatalkannya sebelum melepaskan yang baru. Ini sebenarnya yang dilakukan Google dalam pencarian instan mereka .
Marko
1
mungkin duplikat penundaan jquery keyup?
CMS
1
Bagaimana dengan blur? Saya kira pengguna telah selesai mengetik ketika elemen input kehilangan fokus.
Don P
3
Pencarian google sederhana bisa memberi Anda jawaban sederhana: schier.co/blog/2014/12/08/…
Cannicide

Jawaban:

689

Jadi, saya akan menebak selesai mengetik berarti Anda hanya berhenti sebentar, katakan 5 detik. Maka dengan itu dalam pikiran, mari kita mulai waktu ketika pengguna melepaskan kunci dan menghapusnya ketika mereka menekan satu. Saya memutuskan input yang dimaksud adalah #myInput.

Membuat beberapa asumsi ...

//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
}
Mimpi nyata
sumber
4
Terima kasih :) Saya mulai mengetik komentar saya pada pertanyaan dan menyadari saya punya ide yang baik.
Surreal Dreams
26
Jawaban ini tidak berfungsi dengan benar, ia akan selalu menyala setelah 5 detik kecuali jika pengguna mengetik sangat lambat. Lihat solusi kerja di bawah ini.
berlangsung
3
Jika Anda mengalami masalah di sini, karena timer langsung menyala, coba tambahkan tanda kutip di sekitar panggilan fungsi: setTimeout ('functionToBeCalled', doneTypingInterval);
Largo
3
Saya melihat beberapa komentar di mana fungsi callback, doneTypingdalam contoh, berjalan segera. Itu biasanya akibat tidak sengaja termasuk ()setelah nama fungsi. Perhatikan bahwa seharusnya setTimeout(doneTyping,tidak membacasetTimeout(doneTyping(),
Anthony DiSanti
2
@Jessica untuk bekerja dengan pasta, Anda harus menambahkan acara 'tempel' seperti ini: pada ('pasta keyup',
Sergey
397

Jawaban yang dipilih di atas tidak berfungsi.

Karena typingTimer kadang-kadang diatur beberapa kali (keyup ditekan dua kali sebelum keydown dipicu untuk pengetik cepat dll.) Maka itu tidak jelas dengan benar.

Solusi di bawah menyelesaikan masalah ini dan akan memanggil X detik setelah selesai sesuai permintaan OP. Itu juga tidak lagi membutuhkan fungsi keydown redundan. Saya juga telah menambahkan tanda centang sehingga panggilan fungsi Anda tidak akan terjadi jika input Anda kosong.

//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
}

Dan kode yang sama dalam solusi vanilla JavaScript:

//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
}

Solusi ini memang menggunakan ES6 tetapi tidak perlu di sini. Cukup ganti letdengan vardan fungsi panah dengan fungsi biasa.

pergi
sumber
5
Yah, mungkin berguna untuk tetap memanggil fungsi meskipun inputnya kosong. Bagaimana jika Anda ingin menghapus beberapa hasil pencarian (misalnya) ketika input kosong lagi?
rvighne
7
Saya pikir kita juga harus mempertimbangkan kondisi di mana pengguna hanya menempelkan string di dalam bidang.
Vishal Nair
10
gunakan $('#myInput').on('input', function() {jika Anda ingin ini berfungsi dengan salin dan tempel. Saya tidak melihat titik cek jika input kosong. Misalkan dia ingin menghapus apa yang diketiknya ini akan gagal melakukan panggilan ajax.
billynoah
3
Kenapa if ($('#myInput').val)bukan if ($('#myInput').val())? Haruskah .valsuatu fungsi?
wlnirvana
4
Mengapa tidak menggunakan $ (ini) .val ()?
JoelFan
76

Ini hanya satu baris dengan fungsi debounce underscore.js :

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

Ini pada dasarnya mengatakan doSomething 500 milidetik setelah saya berhenti mengetik.

Untuk info lebih lanjut: http://underscorejs.org/#debounce

bit2pixel
sumber
5
Tampaknya tersedia untuk jQuery, juga: code.google.com/p/jquery-debounce dan github.com/diaspora/jquery-debounce
koppor
63
Itu mengherankan saya bagaimana orang-orang mengatakan "ONE LINE OF CODE" sebagai sangat penting. Bagus. SATU LINE kode yang membutuhkan file JS 1.1k untuk dimuat. Saya tidak downvoting ini karena merupakan solusi. Tapi satu baris yang berani mengganggu saya dan juga menyebabkan kode gembung.
Wolfie
1
@ Wolfie, saya setuju dengan Anda tentang kode mengasapi tetapi Underscore dan Lodash adalah dua utilitas tergantung pada NPM jadi ini mungkin solusi satu baris untuk banyak orang.
Paul
3
@ Paul Saya setuju bahwa jika Anda memuat perpustakaan untuk keperluan lain, tidak masalah dan sebenarnya bermanfaat untuk menggunakan kode umum. Tetapi untuk memuat lebih dari K kode untuk tujuan satu baris tidak efisien. Apalagi dengan platform seluler yang semakin tidak terbatas data. Dan banyak daerah Euro juga membayar internet berdasarkan data. Jadi ada baiknya memperhatikan kembung ketika masuk akal untuk melakukannya.
Wolfie
mengapa saya mendapat:Uncaught ReferenceError: _ is not defined
Wilf
44

Ya, Anda dapat mengatur batas waktu katakan 2 detik pada setiap dan setiap acara kunci yang akan memunculkan permintaan ajax. Anda juga dapat menyimpan metode XHR dan membatalkannya pada acara tekan tombol berikutnya sehingga Anda lebih menghemat bandwidth. Ini adalah sesuatu yang saya tulis untuk skrip pelengkapan otomatis saya.

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
});

Semoga ini membantu,

Marko

Marko
sumber
Saya tidak akan merekomendasikan ini. Kode memicu permintaan API setiap kali tombol ditekan. Maka itu membatalkan permintaan jika tombol lain ditekan. Meskipun solusi ini mencegah callback AJAX untuk dipicu saat tipe pengguna, itu masih akan memalu server dengan permintaan.
lxg
Ixg, tidak ini tidak akan. Fungsi clearTimeout yang ia gunakan menghapus peristiwa Timeout sebelumnya, karenanya memohon panggilan API.
John Smith
@ JohnSmith, saya tidak setuju mungkin lebih baik untuk menghapus timer, kemudian periksa apakah xhr kosong atau apa pun kondisi Anda dan akhirnya jalankan timer dengan panggilan ajax
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);
    }
});

contoh lengkap di sini: http://jsfiddle.net/ZYXp4/8/

azzy81
sumber
Ini bekerja untuk saya, namun perlu diingat bahwa ketika pengguna tab-out dari kotak teks Anda tidak akan mendapatkan peristiwa keyup karena telah kehilangan fokus pada saat itu. Mengaturnya ke keydown bukannya menyelesaikan masalah.
horatius83
12

Kedua jawaban teratas tidak berfungsi untuk saya. Jadi, inilah solusi saya:

var timeout = null;

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

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

Saya menyukai jawaban Surreal Dream tetapi saya menemukan bahwa fungsi "doneTyping" saya akan menyala untuk setiap penekanan tombol, yaitu jika Anda mengetik "Halo" dengan sangat cepat; alih-alih menembak hanya sekali ketika Anda berhenti mengetik, fungsi akan menyala 5 kali.

Masalahnya adalah bahwa fungsi setTimeout javascript tampaknya tidak menimpa atau membunuh semua timeout lama yang telah ditetapkan, tetapi jika Anda melakukannya sendiri berfungsi! Jadi saya baru saja menambahkan panggilan clearTimeout tepat sebelum setTimeout jika typingTimer diatur. Lihat di bawah:

//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
}

NB Saya ingin menambahkan ini sebagai komentar untuk jawaban Surreal Dream tapi saya pengguna baru dan tidak memiliki reputasi yang cukup. Maaf!

Liam Flanagan
sumber
10

Memodifikasi jawaban yang diterima untuk menangani kasus tambahan seperti tempel:

//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
}
Jecom
sumber
6

Saya tidak berpikir acara keyDown diperlukan dalam kasus ini (tolong katakan padaku mengapa jika saya salah). Dalam skrip saya (non-jquery) solusi yang serupa terlihat seperti itu:

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)
    }

}

Ini balasan pertama saya di Stack Overflow, jadi saya harap ini membantu seseorang, suatu hari nanti :)

Rafal Pastuszak
sumber
6

Nyatakan delayfungsi berikut :

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

dan kemudian menggunakannya:

let $filter = $('#item-filter');
$filter.on('keydown', function () {
    delay(function () {            
        console.log('this will hit, once user has not typed for 1 second');            
    }, 1000);
});    
Fabian Bigler
sumber
Solusi Anda fantastis, kawan!
Pengembang
1
@ Pengembang Terima kasih banyak. Saya juga menambahkan jawaban lain untuk menyelesaikan skenario yang sedikit lebih rumit (beberapa kontrol per halaman).
Fabian Bigler
solusi bagus Saya menggunakan ini tetapi bukannya keydown saya menggunakan acara 'input'
Budyn
Dengan acara keyup, itu berhasil untuk saya. Terima kasih.
Sinan Eldem
6

Jawaban yang terlambat tetapi saya menambahkannya karena ini tahun 2019 dan ini sepenuhnya dapat dicapai dengan menggunakan ES6 yang cantik, tidak ada perpustakaan pihak ketiga, dan saya menemukan sebagian besar jawaban berperingkat sangat besar dan terbebani dengan terlalu banyak variabel.

Solusi elegan diambil dari posting blog yang luar biasa ini.

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))
GrayedFox
sumber
1
Ini benar-benar harus menjadi jawaban teratas untuk tahun ini
Dark Hippo
4

Yah, sebenarnya tidak, karena komputer tidak dapat menebak kapan pengguna selesai mengetik. Anda tentu saja dapat mengaktifkan timer pada tombol atas, dan mengatur ulang pada setiap tombol berikutnya ke atas. Jika penghitung waktu kedaluwarsa, pengguna belum mengetik untuk jangka waktu - Anda bisa menyebutnya "selesai mengetik".

Jika Anda mengharapkan pengguna membuat jeda saat mengetik, tidak ada cara untuk mengetahui kapan mereka selesai.

(Kecuali tentu saja Anda dapat mengetahui dari data ketika mereka selesai)

sleske
sumber
3

Saya merasa solusinya sedikit lebih sederhana dengan inputacara ini:

var typingTimer;
var doneTypingInterval = 500;

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

function doneTyping () {
    // code here
}
Adrien Brunelat
sumber
3

setuju dengan jawaban @ going. Solusi serupa lainnya yang berhasil bagi saya adalah solusi di bawah ini. Satu-satunya perbedaan adalah bahwa saya menggunakan .on ("input" ...) alih-alih keyup. Ini hanya menangkap perubahan pada input. tombol lain seperti Ctrl, Shift dll diabaikan

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);
});
Grace.io
sumber
3

Saya baru saja menemukan kode sederhana untuk menunggu pengguna selesai mengetik:

langkah 1.set time out ke null lalu hapus timeout saat ini saat pengguna mengetik.

langkah 2.trigger timeout yang jelas ke variabel define sebelum peristiwa keyup dipicu.

langkah 3. tentukan batas waktu untuk variabel yang dinyatakan di atas;

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

kode javascript

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);
};
Nevil Saul Blemuss
sumber
1
pertanyaannya sudah dijawab ... dan sangat mirip dengan ini
Mixone
3

Saya sedang menerapkan pencarian di daftar saya dan membutuhkannya untuk berbasis ajax. Itu berarti bahwa pada setiap perubahan kunci, hasil yang dicari harus diperbarui dan ditampilkan. Ini menghasilkan begitu banyak panggilan ajax yang dikirim ke server, yang bukan hal yang baik.

Setelah beberapa bekerja, saya membuat pendekatan untuk melakukan ping ke server ketika pengguna berhenti mengetik.

Solusi ini bekerja untuk saya:

$(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

Anda akan melihat bahwa tidak perlu menggunakan timer saat menerapkan ini.

Ata ul Mustafa
sumber
2

Ini adalah kode JS sederhana yang saya tulis:

<!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>
Alfredo Lingoist Jr.
sumber
1

Anda dapat menggunakan acara onblur untuk mendeteksi ketika kotak teks kehilangan fokus: https://developer.mozilla.org/en/DOM/element.onblur

Itu tidak sama dengan "berhenti mengetik", jika Anda peduli tentang kasus di mana pengguna mengetik banyak barang dan kemudian duduk di sana dengan kotak teks masih fokus.

Untuk itu saya akan menyarankan untuk mengikat setTimeout ke acara onclick, dan dengan asumsi bahwa setelah x jumlah waktu tanpa penekanan tombol, pengguna telah berhenti mengetik.

Mike Ruhlin
sumber
1

Mengapa tidak menggunakan fokus saja?

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

Jika itu bentuk, mereka akan selalu meninggalkan fokus setiap bidang input untuk mengklik tombol kirim sehingga Anda tahu tidak ada input yang akan ketinggalan untuk mendapatkan penangan event onfocusout yang dipanggil.

coffeeeee
sumber
1
onfocusout memiliki dukungan yang buruk ketika pertanyaan diajukan (hampir 7 tahun yang lalu sekarang), dan juga efek dengan onfocusout akan sedikit berbeda. Anda harus menunggu pengguna untuk meninggalkan fokus pada elemen sedangkan dengan solusi timeout / debounce itu "menyala" segera setelah pengguna berhenti mengetik dan pengguna tidak diharuskan untuk beralih fokus. Contoh use case akan menjadi salah satu formulir pendaftaran di mana ketika pengguna berhenti memasukkan nama pengguna potensial tanda centang atau "X" muncul di sebelah kanan bidang formulir yang menunjukkan bahwa nama tersedia.
David Zorychta
jika bilah pencarian fokus, tidak ada yang perlu keluar, setelah beberapa saat hasil akan langsung ditampilkan karena tidak ada lagi mengetik yang diketik
P Satish Patro
1

Jika ada keharusan bagi pengguna untuk menjauh dari bidang, kita dapat menggunakan "onBlur" alih-alih Onchange dalam Javascript

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

Jika itu tidak diperlukan, pengaturan timer akan menjadi pilihan yang baik.

Jayabharathi Palanisamy
sumber
0

Setelah Anda mendeteksi fokus pada kotak teks, pada tombol lakukan pemeriksaan batas waktu, dan reset setiap kali itu dipicu.

Ketika batas waktu selesai, lakukan permintaan ajax Anda.

ocodo
sumber
0

Jika Anda mencari panjang tertentu (seperti bidang kode pos):

$("input").live("keyup", function( event ){
if(this.value.length == this.getAttribute('maxlength')) {
        //make ajax request here after.
    }
  });
Jason
sumber
Bukan ide buruk untuk melakukan validasi terbatas sebelum mengirim permintaan ajax.
chim
0

Tidak yakin apakah kebutuhan saya agak aneh, tetapi saya membutuhkan sesuatu yang mirip dengan ini dan inilah yang akhirnya saya gunakan:

$('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');
});

Yang memungkinkan saya untuk memiliki elemen seperti ini di aplikasi saya:

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

Yang diperbarui ketika pengguna "selesai mengetik" (tidak ada tindakan selama 2 detik) atau pergi ke bidang lain (kabur dari elemen)

Paolo Bergantino
sumber
0

Jika Anda perlu menunggu sampai pengguna selesai mengetik, gunakan ini:

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

Contoh lengkap dengan panggilan ajax - ini berfungsi untuk pager saya - jumlah item per daftar:

$(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);
            }
        });  
    });
});    
Miroslav Siska
sumber
0

Banyak penghitung waktu per halaman

Semua jawaban lain hanya berfungsi untuk satu kontrol ( termasuk jawaban saya yang lain ). Jika Anda memiliki beberapa kontrol per halaman (misalnya dalam keranjang belanja) hanya kontrol terakhir tempat pengguna mengetik sesuatu yang akan dipanggil . Dalam kasus saya ini tentu bukan perilaku yang diinginkan - setiap kontrol harus memiliki timer sendiri.

Untuk mengatasi ini, Anda hanya perlu memberikan ID ke fungsi dan mempertahankan kamus timeoutHandles seperti dalam kode berikut:

Deklarasi Fungsi:

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

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

Penggunaan fungsi:

  delayUserInput('yourID', function () {
     //do some stuff
  }, 1000);
Fabian Bigler
sumber
0

Sederhana dan mudah dimengerti.

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

Untuk melewatkan parameter ke fungsi Anda bersama dengan sintaks ES6.

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

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

Wow, bahkan 3 komentar cukup benar!

  1. Input kosong bukan alasan untuk melewatkan panggilan fungsi, misalnya saya menghapus parameter limbah dari url sebelum dialihkan

  2. .on ('input', function() { ... });harus digunakan untuk memicu keyup, pastedan changeacara

  3. pasti .val()atau .valueharus digunakan

  4. Anda dapat menggunakan $(this)fungsi acara di dalam alih-alih #idbekerja dengan beberapa input

  5. (keputusan saya) saya menggunakan fungsi anonim bukannya doneTypingdi setTimeoutmudah akses $(this)dari n.4, tetapi Anda harus menyimpannya terlebih dahulu sepertivar $currentInput = $(this);

EDIT Saya melihat bahwa beberapa orang tidak mengerti arah tanpa kemungkinan untuk menyalin-rekatkan kode siap. Di sini kamu

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);      
});
vladkras
sumber
Bagaimana ini menjawab pertanyaan?
Thomas Orlita
@ThomasOrlita jawaban ini melengkapi 3 jawaban yang paling banyak dinilai. Lihatlah yang diterima: 1. tidak mendukung paste, tidak digunakan this, dll. (Saya pikir ini penting tapi saya tidak ingin tersesat dalam banyak komentar)
vladkras
1
Ini tidak menjawab pertanyaan. Jika Anda ingin mengomentari jawaban lain, ada sistem komentar (saya menggunakannya sekarang!)
GrayedFox