masalah setTimeout / clearTimeout

103

Saya mencoba membuat halaman untuk pergi ke halaman awal setelah mis. 10 detik tidak aktif (pengguna tidak mengklik di mana pun). Saya menggunakan jQuery untuk sisanya tetapi set / clear dalam fungsi pengujian saya adalah javascript murni.

Dalam rasa frustrasi saya, saya berakhir dengan sesuatu seperti fungsi ini yang saya harap dapat saya panggil pada setiap klik di halaman. Pengatur waktu mulai dengan baik, tetapi tidak diatur ulang dengan sekali klik. Jika fungsi dipanggil 5 kali dalam 10 detik pertama, maka 5 peringatan akan muncul ... tidak ada clearTimeout ...

function endAndStartTimer() {
    window.clearTimeout(timer);
    var timer;
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
}

Adakah yang punya beberapa baris kode yang akan melakukan trik? - pada setiap klik berhenti, setel ulang dan mulai pengatur waktu. - Saat timer mencapai mis. 10sec melakukan sesuatu.

Tillebeck
sumber

Jawaban:

226

Anda perlu mendeklarasikan di timer luar fungsi. Jika tidak, Anda mendapatkan variabel baru di setiap pemanggilan fungsi.

var timer;
function endAndStartTimer() {
  window.clearTimeout(timer);
  //var millisecBeforeRedirect = 10000; 
  timer = window.setTimeout(function(){alert('Hello!');},10000); 
}
Runcing
sumber
ditambah 1 karena perlu, dalam hal ini, untuk menghapus variabel yang menutup timeOut sebelum memanggil waktu habis, dengan demikian, hindari untuk dipanggil dua kali
Diego Favero
46

Masalahnya adalah timervariabel tersebut bersifat lokal, dan nilainya hilang setelah setiap pemanggilan fungsi.

Anda perlu mempertahankannya, Anda dapat meletakkannya di luar fungsi, atau jika Anda tidak ingin mengekspos variabel sebagai global, Anda dapat menyimpannya di closure , misalnya:

var endAndStartTimer = (function () {
  var timer; // variable persisted here
  return function () {
    window.clearTimeout(timer);
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
  };
})();
CMS
sumber
15

Itu karena timer adalah variabel lokal untuk fungsi Anda.

Coba buat di luar fungsi.

arclight
sumber
6

Cara untuk menggunakan ini dalam bereaksi:

class Timeout extends Component {
  constructor(props){
    super(props)

    this.state = {
      timeout: null
    }

  }

  userTimeout(){
    const { timeout } = this.state;
    clearTimeout(timeout);
    this.setState({
      timeout: setTimeout(() => {this.callAPI()}, 250)
    })

  }
}

Bermanfaat jika Anda hanya ingin memanggil API setelah pengguna berhenti mengetik misalnya. Fungsi userTimeout dapat diikat melalui onKeyUp ke sebuah masukan.

zero_cool
sumber
1
Ini yang saya cari selama beberapa jam, terima kasih. Saya hanya ingin tahu apakah ada cara yang lebih baik agar hasil seperti ini terjadi?
Nikasv
1
@nikasv throttling, dan debouncing adalah dua alternatif: medium.com/@_jh3y/…
zero_cool
2

Tidak yakin apakah ini melanggar beberapa aturan pengkodean praktik yang baik tetapi saya biasanya keluar dengan yang ini:

if(typeof __t == 'undefined')
        __t = 0;
clearTimeout(__t);
__t = setTimeout(callback, 1000);

Ini mencegah kebutuhan untuk menyatakan timer keluar dari fungsi.

EDIT: ini juga tidak mendeklarasikan variabel baru di setiap pemanggilan, tetapi selalu mendaur ulang sama.

Semoga ini membantu.

clamiax
sumber
0

Ini bekerja dengan baik. Ini adalah manajer yang saya buat untuk menangani acara-acara. Memiliki acara untuk ditahan, dan saat Anda melepaskannya.

function onUserHold(element, func, hold, clearfunc) {
    //var holdTime = 0;
    var holdTimeout;

    element.addEventListener('mousedown', function(e) {
        holdTimeout = setTimeout(function() {
            func();
            clearTimeout(holdTimeout);
            holdTime = 0;
        }, hold);
        //alert('UU');
    });

    element.addEventListener('mouseup', clearTime);
    element.addEventListener('mouseout', clearTime);

    function clearTime() {
        clearTimeout(holdTimeout);
        holdTime = 0;
        if(clearfunc) {
            clearfunc();
        }
    }
}

Parameter elemen adalah yang Anda pegang. Parameter func aktif saat ditahan selama beberapa milidetik yang ditentukan oleh parameter tahan. Parameter clearfunc adalah opsional dan jika diberikan, itu akan diaktifkan jika pengguna melepaskan atau meninggalkan elemen. Anda juga dapat melakukan beberapa solusi untuk mendapatkan fitur yang Anda inginkan. Nikmati! :)

Kino Bacaltos
sumber
0

Contoh Praktis Menggunakan Jquery untuk Menu Dropdown! Saat mengarahkan mouse ke #IconLoggedinUxExternal, tampilkan div # ExternalMenuLogin dan setel waktu untuk menyembunyikan div # ExternalMenuLogin

Di atas mouse di div # ExternalMenuLogin itu membatalkan batas waktu. Saat mouse keluar pada div # ExternalMenuLogin itu mengatur batas waktu.

Intinya di sini adalah selalu memanggil clearTimeout sebelum menyetel batas waktu, dengan demikian, menghindari panggilan ganda

var ExternalMenuLoginTO;
$('#IconLoggedinUxExternal').on('mouseover mouseenter', function () {

    clearTimeout( ExternalMenuLoginTO )
    $("#ExternalMenuLogin").show()
});

$('#IconLoggedinUxExternal').on('mouseleave mouseout', function () {

    clearTimeout( ExternalMenuLoginTO )    
    ExternalMenuLoginTO = setTimeout(
        function () {

            $("#ExternalMenuLogin").hide()

        }
        ,1000
    );
    $("#ExternalMenuLogin").show()
});

$('#ExternalMenuLogin').on('mouseover mouseenter', function () {

    clearTimeout( ExternalMenuLoginTO )
});
$('#ExternalMenuLogin').on('mouseleave mouseout', function () {

    clearTimeout( ExternalMenuLoginTO )
    ExternalMenuLoginTO = setTimeout(
        function () {

            $("#ExternalMenuLogin").hide()

        }
        ,500
    );
});
Diego Favero
sumber