Bagaimana cara mendeteksi waktu idle dalam JavaScript secara elegan?

479

Apakah mungkin mendeteksi waktu " idle " dalam JavaScript?
Kasing penggunaan utama saya mungkin adalah untuk mengambil atau mengambil pramuat konten.

Waktu idle: Periode tanpa aktivitas pengguna atau tanpa penggunaan CPU

Cherian
sumber
7
Bagaimana Anda mendefinisikan IDLE TIME?
Itay Moav -Malimovka
4
periksa github.com/kidh0/jquery.idle
apneadiving
74
Hampir 50% dari jawaban di sini menggunakan jQuery untuk tugas sederhana seperti Javascript murni. Ini di luar bodoh, terutama karena OP ingin Javascript. Minta es krim Stroberi tetapi dapatkan gudang semi-terpisah sebagai gantinya.
TheCarver
4
itulah StackOverflow untuk Anda
robertmain
5
@TheCarver - Harus menginstal pustaka jQuery untuk sesuatu yang begitu sederhana memang konyol, dan memperpanjang waktu render dan meningkatkan penggunaan energi. Orang harus gulir ke bawah sedikit lebih jauh. Ada juga solusi copy-paste di Javascript vanilla juga.
Frank Conijn

Jawaban:

439

Berikut ini adalah skrip sederhana menggunakan JQuery yang menangani acara mousemove dan penekanan tombol. Jika waktu habis, halaman akan dimuat ulang.

<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
    //Increment the idle time counter every minute.
    var idleInterval = setInterval(timerIncrement, 60000); // 1 minute

    //Zero the idle timer on mouse movement.
    $(this).mousemove(function (e) {
        idleTime = 0;
    });
    $(this).keypress(function (e) {
        idleTime = 0;
    });
});

function timerIncrement() {
    idleTime = idleTime + 1;
    if (idleTime > 19) { // 20 minutes
        window.location.reload();
    }
}
</script>   
freddoo
sumber
16
Anda kehilangan tanda koma setelah $ (dokumen). Sudah (fungsi () badan. Juga, dalam panggilan untuk mengaturInterval, itu tidak akan bekerja dengan tanda kutip di sekitar nama fungsi dan Anda tidak perlu tanda kurung setelahnya. Hanya: setInterval (timerIncrement, 60000)
Jesse Roper
9
@Jesse: Saran Anda semuanya baik-baik saja, beginilah seharusnya kodenya. Tapi saya hanya ingin menunjukkan bahwa bahkan tanpa perubahan ini, kode ini berfungsi penuh. Titik koma di akhir pernyataan ekspresi adalah opsional dan Anda sebenarnya dapat meneruskan string setInterval, yang kemudian dievaluasi sebagai JavaScript.
Felix Kling
6
Anda bisa menggunakan idleTime++;sajaidleTime = idleTime + 1;
Mike Causer
7
Apakah ini tidak berat pada sistem pengguna? Katakanlah, pengguna dengan peramban yang cukup lama di komputer yang tidak terlalu berat, bekerja dalam aplikasi javascript selama setengah hari, dan sedang memproses fungsi-fungsi ini setiap kali pengguna menggerakkan tetikusnya ... Saya ingin tahu apakah ini akan menang ' t mempengaruhi pengalaman pengguna ...
Sander
5
@ PietBinnenbocht Juga, jika Anda mulai mengoptimalkan hal-hal seperti ini, Anda juga dapat mengubah setiap fungsi yang mengambil string seperti 'mousemove keydown click'menggunakan flag bit ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK), karena mereka waaaaay lebih cepat daripada operasi string. Tetapi apakah Anda benar - benar ingin melakukan ini?
Killah
362

Tanpa menggunakan jQuery, hanya JavaScript vanilla:

var inactivityTime = function () {
    var time;
    window.onload = resetTimer;
    // DOM Events
    document.onmousemove = resetTimer;
    document.onkeypress = resetTimer;

    function logout() {
        alert("You are now logged out.")
        //location.href = 'logout.html'
    }

    function resetTimer() {
        clearTimeout(time);
        time = setTimeout(logout, 3000)
        // 1000 milliseconds = 1 second
    }
};

Dan init fungsi di mana Anda membutuhkannya (misalnya: onPageLoad).

window.onload = function() {
  inactivityTime(); 
}

Anda dapat menambahkan lebih banyak acara DOM jika perlu. Paling sering digunakan adalah:

document.onload = resetTimer;
document.onmousemove = resetTimer;
document.onmousedown = resetTimer; // touchscreen presses
document.ontouchstart = resetTimer;
document.onclick = resetTimer;     // touchpad clicks
document.onkeypress = resetTimer;
document.addEventListener('scroll', resetTimer, true); // improved; see comments

Atau daftarkan acara yang diinginkan menggunakan array

window.addEventListener('load', resetTimer, true);
var events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
events.forEach(function(name) {
 document.addEventListener(name, resetTimer, true); 
});

Daftar Acara DOM : http://www.w3schools.com/jsref/dom_obj_event.asp

Ingat gunakan window, atau documentsesuai kebutuhan Anda. Di sini Anda dapat melihat perbedaan di antara mereka: Apa perbedaan antara jendela, layar, dan dokumen dalam Javascript?

Kode Diperbarui dengan @ frank-conijn dan @daxchen meningkatkan: window.onscrolltidak akan menyala jika bergulir di dalam elemen yang dapat digulir, karena acara gulir tidak menggelembung. window.addEventListener('scroll', resetTimer, true), argumen ketiga memberitahu pendengar untuk menangkap acara selama fase penangkapan alih-alih fase gelembung.

Equiman
sumber
58
Saya suka pendekatan javascript biasa jauh lebih baik.
Manatax
4
mengatur ulang timer adalah pendekatan yang lebih langsung / intuitif dan akurat daripada memiliki timeout melakukan hal itu, hanya untuk menjaga jumlah integer dari hal lain, ketika timer itu sendiri dapat menjadi penghitung (presisi tinggi).
Josh Sutterfield
2
@ mpsbhat hanya menambahkan console.log atau peringatan dan lihat apakah berfungsi. Atau daftarkan acara ini:document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
equiman
2
Ya ... Bekerja. jsfiddle.net/mpsbhat/6b6mja5t/1 . Terima kasih @equiman
mpsbhat
6
Akan jauh lebih baik untuk memiliki flag var notidle; atur flag itu = true hanya pada event. Kemudian dalam tes fungsi resetTimer jika flag notidle benar, jika reset timer mereka, atau panggil logout. Ini akan menghilangkan kompleksitas overhead karena mengatur ulang timer secara konstan.
MartinWebb
75

Memperbaiki jawaban Equiman:

function idleLogout() {
    var t;
    window.onload = resetTimer;
    window.onmousemove = resetTimer;
    window.onmousedown = resetTimer;  // catches touchscreen presses as well      
    window.ontouchstart = resetTimer; // catches touchscreen swipes as well 
    window.onclick = resetTimer;      // catches touchpad clicks as well
    window.onkeypress = resetTimer;   
    window.addEventListener('scroll', resetTimer, true); // improved; see comments

    function yourFunction() {
        // your function for too long inactivity goes here
        // e.g. window.location.href = 'logout.php';
    }

    function resetTimer() {
        clearTimeout(t);
        t = setTimeout(yourFunction, 10000);  // time is in milliseconds
    }
}
idleLogout();

.
Terlepas dari perbaikan mengenai deteksi aktivitas, dan perubahan dari documentmenjadi window, skrip ini sebenarnya memanggil fungsi, daripada membiarkannya diam.

Tidak menangkap nol penggunaan CPU secara langsung, tetapi itu tidak mungkin, karena menjalankan fungsi menyebabkan penggunaan CPU. Dan ketidakaktifan pengguna akhirnya mengarah ke nol penggunaan CPU, jadi secara tidak langsung itu menangkap penggunaan nol CPU.

Frank Conijn
sumber
3
Hanya ingin menunjukkan bahwa window.onscrolltidak akan menyala jika pengguliran ada di dalam elemen yang dapat digulir, karena acara gulir tidak menggelembung. Dengan menggunakan window.addEventListener('scroll', resetTimer, true), argumen ketiga memberi tahu pendengar untuk menangkap peristiwa selama capturefase alih-alih bubblefase (IE> 8), lihat jawaban ini
DaxChen
@ DaxChen - Tidak document.onscrollmemiliki masalah yang sama, tidak memecat jika gulir di dalam anak digulir?
Frank Conijn
2
Ya, intinya yang saya katakan adalah menggunakan addEventListeneralih-alih onscroll.
DaxChen
@DaxChen - OK, saya bertanya-tanya apakah Anda bermaksud demikian, untuk mengatasinya, tapi sekarang sudah jelas. Saya mengedit jawabannya. Terima kasih atas komentarnya.
Frank Conijn
Saya akan memperbarui jawaban saya dengan informasi penting ini, untuk rajin menyalin dan menempelkan kesalahan saya. Terima kasih @DaxChen dan Frank
equiman
33

Saya telah membuat lib kecil yang melakukan ini setahun yang lalu:

https://github.com/shawnmclean/Idle.js

Deskripsi:

Pustaka javascript kecil untuk melaporkan aktivitas pengguna di browser (menjauh, menganggur, tidak melihat halaman web, di tab yang berbeda, dll). yang independen dari perpustakaan javascript lainnya seperti jquery.

Pengguna Visual Studio bisa mendapatkannya dari NuGet dengan: PM> Install-Package Idle.js

Shawn Mclean
sumber
32

Berikut ini adalah implementasi jQuery dari ide tvanfosson:

$(document).ready(function(){

   idleTime = 0;

   //Increment the idle time counter every second.
   var idleInterval = setInterval(timerIncrement, 1000);

   function timerIncrement()
   {
     idleTime++;
     if (idleTime > 2)
     {
       doPreload();
     }
   }

   //Zero the idle timer on mouse movement.
   $(this).mousemove(function(e){
      idleTime = 0;
   });

   function doPreload()
   {
     //Preload images, etc.
   }

})
Peter J
sumber
9
Solusi ini tidak mempertimbangkan acara keyboard.
Daniel Silveira
7
Jangan pernah melewatkan setIntervalstring! Berikan saja fungsi sebagai variabel!
Eric
1
Ini sebenarnya tidak akan berfungsi karena melewatkan string untuk setInterval()mengevaluasi ekspresi dalam lingkup global dan karenanya tidak akan menemukan timerIncrement()fungsi yang ada di dalam fungsi. Ini adalah alasan lain untuk TIDAK PERNAH meneruskan string setInterval(). Cukup berikan referensi fungsi aktual dan Anda tidak akan mengalami masalah ini karena mereka dievaluasi dalam cakupan saat ini.
jfriend00
Terima kasih, saya tidak menyadari perlunya PERNAH melewati string ke setInterval. Memperbarui jawaban saya.
Peter J
24

Mirip dengan solusi Iconic di atas (dengan acara khusus jQuery) ...

// use jquery-idle-detect.js script below
$(window).on('idle:start', function(){
  //start your prefetch etc here...
});

$(window).on('idle:stop', function(){
  //stop your prefetch etc here...
});

//jquery-idle-detect.js
(function($,$w){
  // expose configuration option
  // idle is triggered when no events for 2 seconds
  $.idleTimeout = 2000;

  // currently in idle state
  var idle = false;

  // handle to idle timer for detection
  var idleTimer = null;

  //start idle timer and bind events on load (not dom-ready)
  $w.on('load', function(){
    startIdleTimer();
    $w.on('focus resize mousemove keyup', startIdleTimer)
      .on('blur',idleStart) //force idle when in a different tab/window
      ;
  ]);

  function startIdleTimer() {
    clearTimeout(idleTimer); //clear prior timer

    if (idle) $w.trigger('idle:stop'); //if idle, send stop event
    idle = false; //not idle

    var timeout = ~~$.idleTimeout; // option to integer
    if (timeout <= 100) timeout = 100; // min 100ms
    if (timeout > 300000) timeout = 300000; // max 5 minutes

    idleTimer = setTimeout(idleStart, timeout); //new timer
  }

  function idleStart() {
    if (!idle) $w.trigger('idle:start');
    idle = true;
  }

}(window.jQuery, window.jQuery(window)))
Pelacak1
sumber
20

Anda dapat melakukannya dengan lebih elegan dengan garis bawah dan jquery -

$('body').on("click mousemove keyup", _.debounce(function(){
    // do preload here
}, 1200000)) // 20 minutes debounce
Kruttik
sumber
16

Jawaban saya terinspirasi oleh jawaban vijay , tetapi merupakan solusi yang lebih singkat dan lebih umum yang saya pikir akan saya bagikan kepada siapa pun yang mungkin bisa membantu.

(function () { 
    var minutes = true; // change to false if you'd rather use seconds
    var interval = minutes ? 60000 : 1000; 
    var IDLE_TIMEOUT = 3; // 3 minutes in this example
    var idleCounter = 0;

    document.onmousemove = document.onkeypress = function () {
        idleCounter = 0;
    };

    window.setInterval(function () {
        if (++idleCounter >= IDLE_TIMEOUT) {
            window.location.reload(); // or whatever you want to do
        }
    }, interval);
}());

Seperti saat ini berdiri, kode ini akan segera mengeksekusi dan memuat kembali halaman Anda saat ini setelah 3 menit tanpa gerakan mouse atau penekanan tombol.

Ini menggunakan JavaScript vanilla polos dan ekspresi fungsi yang segera dipanggil untuk menangani waktu tunggu idle dengan cara yang bersih dan mandiri.

johnnyRose
sumber
document.onclick mempertimbangkan fungsi javascript menggunakan .trigger ('klik') yang saya tulis sebagai otomatis. Jadi ini bukan benar-benar interaksi pengguna tetapi itu akan mengatur ulang idleCounter dalam kasus ini
Carmela
@Carmela: Saya tidak yakin mengapa saya hanya melihat ini; Aku pasti melewatkannya. Terima kasih, saya menghapus onclicktugas karena mungkin tidak perlu sebagai tambahan onmousemove, tapi jelas semua peristiwa yang dipicu secara terprogram akan terus diatur ulang idleCounter. Saya tidak yakin mengapa Anda mensimulasikan interaksi pengguna alih-alih hanya memanggil fungsi, tetapi jika itu sesuatu yang perlu Anda lakukan untuk beberapa alasan, jawaban ini jelas tidak akan bekerja untuk Anda, dan sebagian besar dari jawaban lainnya tidak akan saya jawab. Saya telah melihat pertanyaan ini.
johnnyRose
15

Saya tahu itu pertanyaan yang relatif lama, tetapi saya memiliki masalah yang sama dan saya menemukan solusi yang cukup bagus.

Saya menggunakan: jquery.idle dan saya hanya perlu melakukan:

$(document).idle({
  onIdle: function(){
    alert('You did nothing for 5 seconds');
  },
  idle: 5000
})

Lihat demo JsFiddle .

(Hanya untuk Info: lihat ini untuk pelacakan acara back-end browser Leads )

DDan
sumber
Bagaimana saya bisa menghentikan fungsi ini, Mereka menyatakan suatu acara idle: berhenti tetapi saya jujur ​​tidak tahu bagaimana menggunakan ini. Saya ingin bahwa jika saya pindah ke halaman berikutnya (berbasis ajax jadi hanya sebagian dari halaman HTML yang diperbarui) maka fungsi idle berhenti. Tahukah Anda bagaimana mencapai ini?
Mubasher
Di sini tertulis: "idle: stop": akan berhenti dan menghapus pelacakan pengguna
DDan
Saya sudah membaca tetapi tidak tahu cara menggunakannya, Bisakah Anda membantu saya?
Mubasher
Jika Anda ingin mengaktifkannya sekali saja, Anda dapat mengatur keepTrackingopsi ke false. Jika Anda ingin mengatur ulang Anda bisa mencoba untuk menginisialisasi ulang. Berikut ini adalah contoh yang dimodifikasi yang hanya akan diaktifkan sekali: jsfiddle.net/f238hchm/12
DDan
Tidak, saya tidak memecat sekali, keepTracking harus benar, tetapi pada navigasi ke halaman lain saya ingin menghentikan ini
Mubasher
15

Semua jawaban sebelumnya memiliki penangan mouse yang selalu aktif. Jika pawang adalah jQuery, kinerja pemrosesan jQuery tambahan dapat bertambah. Terutama jika pengguna menggunakan mouse gaming, sebanyak 500 peristiwa per detik dapat terjadi.

Solusi ini menghindari penanganan setiap acara mousemove. Ini menghasilkan kesalahan waktu yang kecil, tetapi Anda dapat menyesuaikannya dengan kebutuhan Anda.

function setIdleTimeout(millis, onIdle, onUnidle) {
    var timeout = 0;
    startTimer();

    function startTimer() {
        timeout = setTimeout(onExpires, millis);
        document.addEventListener("mousemove", onActivity);
        document.addEventListener("keydown", onActivity);
    }

    function onExpires() {
        timeout = 0;
        onIdle();
    }

    function onActivity() {
        if (timeout) clearTimeout(timeout);
        else onUnidle();
        //since the mouse is moving, we turn off our event hooks for 1 second
        document.removeEventListener("mousemove", onActivity);
        document.removeEventListener("keydown", onActivity);
        setTimeout(startTimer, 1000);
    }
}

http://jsfiddle.net/jndxq51o/

Sarsaparila
sumber
1
Apakah ini akan bekerja secara otomatis jika ditempatkan pada halaman, atau apakah harus di dalam bungkus $ (dokumen) .ready ()? Terima kasih! Juga, di mana bagian yang melakukan tindakan ketika penghitung waktu berakhir?
Oranges13
1
Anda dapat menelepon ini kapan saja, bahkan sebelum dokumen siap. Anda melewatkan fungsi 'callback' yang akan dipanggil saat timer kedaluwarsa.
Sarsaparilla
1
Ini $(startTimer)setara dengan $(document).ready(startTimer), memastikan bahwa DOM siap sebelum Anda mengaitkan mousemove dan acara menekan tombol.
Sarsaparilla
1
+1 Inilah yang saya lakukan - pengendali mousemove berkontribusi terhadap kelesuan dan mengurangi masa pakai baterai, jadi hanya menyalakannya secara berkala adalah ide bagus jika Anda mampu mengatasi kesalahan pengaturan waktu minor. Saya biasanya menggunakan deteksi waktu idle untuk peringatan kedaluwarsa sesi otomatis (mis. "Apakah Anda masih di sana?"), Jadi saya cenderung punya banyak menit sebelum pengguna "idle", dalam hal ini kesalahan waktu yang kecil sama sekali tidak relevan.
kambing
1
Lebih baik menggunakan "keydown" daripada "keypress" karena tombol panah tidak terdeteksi oleh acara "keypress". Jadi, jika pengguna menavigasi halaman menggunakan tombol panah, itu akan menjadi Idle anyways.
aFerrer
13

Anda mungkin dapat meretas sesuatu bersama-sama dengan mendeteksi gerakan mouse di badan formulir dan memperbarui variabel global dengan waktu gerakan terakhir. Anda kemudian perlu menjalankan timer interval yang secara berkala memeriksa waktu gerakan terakhir dan melakukan sesuatu jika sudah cukup lama sejak gerakan mouse terakhir terdeteksi.

tvanfosson
sumber
Penting untuk dicatat bahwa skrip hanya akan dapat mendeteksi gerakan pada tubuh halaman, tidak semua input pengguna. Saya tidak berpikir ada cara untuk mendapatkan CPU atau memproses info dari javascript.
Dave Swersky
1
Saya mengambil kebebasan menerapkan ide Anda di jQuery.
Peter J
9

Saya menulis kelas ES6 kecil untuk mendeteksi aktivitas dan memecat acara saat idle timeout. Ini mencakup keyboard, mouse, dan sentuhan , dapat diaktifkan dan dinonaktifkan dan memiliki API yang sangat ramping:

const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();

Itu tidak tergantung pada jQuery, meskipun Anda mungkin perlu menjalankannya melalui Babel untuk mendukung browser yang lebih lama.

https://gist.github.com/4547ef5718fd2d31e5cdcafef0208096

Saya mungkin merilisnya sebagai paket npm setelah saya mendapatkan umpan balik.

Capi Etheriel
sumber
8

Jika Anda menargetkan browser yang didukung (Chrome atau Firefox pada Desember 2018), Anda dapat bereksperimen dengan requestIdleCallback dan memasukkan shim requestIdleCallback untuk browser yang tidak didukung.

rajsite
sumber
Dan biarkan browser lain saja?
Frank Conijn
Shim menutupi semua browser. Dan ini adalah satu-satunya jawaban! Jawaban perlambatan lainnya adalah tentang mouse. Interaktivitas atau CPU hanya dikatakan sebagai contoh. Bagaimana mendeteksi CPU idle dengan solusi mouse?
6

Coba kode ini, ini berfungsi dengan sempurna.

var IDLE_TIMEOUT = 10; //seconds
var _idleSecondsCounter = 0;

document.onclick = function () {
    _idleSecondsCounter = 0;
};

document.onmousemove = function () {
    _idleSecondsCounter = 0;
};

document.onkeypress = function () {
    _idleSecondsCounter = 0;
};

window.setInterval(CheckIdleTime, 1000);

function CheckIdleTime() {
    _idleSecondsCounter++;
    var oPanel = document.getElementById("SecondsUntilExpire");
    if (oPanel)
        oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
    if (_idleSecondsCounter >= IDLE_TIMEOUT) {
        alert("Time expired!");
        document.location.href = "SessionExpired.aspx";
    }
}
vijay
sumber
ditambah 1 karena menjadi vanilla js
frostymarvelous
5
<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
    //Increment the idle time counter every minute.
    idleInterval = setInterval(timerIncrement, 60000); // 1 minute

    //Zero the idle timer on mouse movement.
    $('body').mousemove(function (e) {
     //alert("mouse moved" + idleTime);
     idleTime = 0;
    });

    $('body').keypress(function (e) {
      //alert("keypressed"  + idleTime);
        idleTime = 0;
    });



    $('body').click(function() {
      //alert("mouse moved" + idleTime);
       idleTime = 0;
    });

});

function timerIncrement() {
    idleTime = idleTime + 1;
    if (idleTime > 10) { // 10 minutes

        window.location.assign("http://www.google.com");
    }
}
</script> 

Saya pikir kode jquery ini sempurna, walaupun disalin dan dimodifikasi dari jawaban di atas !! jangan lupa untuk memasukkan pustaka jquery dalam file Anda!

SPidey
sumber
4

Masalah dengan semua solusi ini, meskipun benar, mereka tidak praktis, ketika mempertimbangkan set timeout sesi berharga, menggunakan PHP, .NET atau dalam file Application.cfc untuk pengembang Coldfusion. Waktu yang ditentukan oleh solusi di atas perlu disinkronkan dengan batas waktu sesi sisi server. Jika keduanya tidak disinkronkan, Anda dapat mengalami masalah yang hanya akan membuat frustasi dan membingungkan pengguna Anda. Misalnya, batas waktu sesi sisi server mungkin diatur ke 60 menit, tetapi pengguna mungkin percaya bahwa ia aman, karena penangkapan waktu JavaScript yang tidak aktif telah meningkatkan jumlah total waktu yang dapat dihabiskan pengguna pada satu halaman. Pengguna mungkin telah menghabiskan waktu mengisi formulir yang panjang, dan kemudian mengirimkannya. Batas waktu sesi mungkin muncul sebelum pengiriman formulir diproses. Saya cenderung hanya memberi pengguna saya 180 menit, dan kemudian menggunakan JavaScript untuk secara otomatis mengeluarkan pengguna. Pada dasarnya, menggunakan beberapa kode di atas, untuk membuat penghitung waktu yang sederhana, tetapi tanpa menangkap bagian acara mouse. Dengan cara ini sisi klien saya & waktu sisi server disinkronkan dengan sempurna. Tidak ada kebingungan, jika Anda menunjukkan waktu kepada pengguna di UI Anda, karena mengurangi. Setiap kali halaman baru diakses di CMS, sesi sisi server & pengatur waktu JavaScript direset. Sederhana & elegan. Jika pengguna tetap berada di satu halaman selama lebih dari 180 menit, saya pikir ada sesuatu yang salah dengan halaman tersebut. karena mengurangi. Setiap kali halaman baru diakses di CMS, sesi sisi server & pengatur waktu JavaScript direset. Sederhana & elegan. Jika pengguna tetap berada di satu halaman selama lebih dari 180 menit, saya pikir ada sesuatu yang salah dengan halaman tersebut. karena mengurangi. Setiap kali halaman baru diakses di CMS, sesi sisi server & pengatur waktu JavaScript direset. Sederhana & elegan. Jika pengguna tetap berada di satu halaman selama lebih dari 180 menit, saya pikir ada sesuatu yang salah dengan halaman tersebut.

Charles Robertson
sumber
1
Yap, itu sebabnya saya hanya melakukan ini setelah menyingkirkan sesi sisi server dan memuat semuanya dari file html.
Dan Parker
4

JavaScript murni dengan waktu reset dan binding yang diatur dengan benar addEventListener

(function() {

  var t,
    timeout = 5000;

  function resetTimer() {
    console.log("reset: " + new Date().toLocaleString());
    if (t) { 
      window.clearTimeout(t); 
    }
    t = window.setTimeout(logout, timeout);
  }

  function logout() {
    console.log("done: " + new Date().toLocaleString());
  }
  resetTimer();

  //And bind the events to call `resetTimer()`
  ["click", "mousemove", "keypress"].forEach(function(name) {
    console.log(name);
    document.addEventListener(name, resetTimer);
  });

}());
JackTheKnife
sumber
4

(Sebagian terinspirasi oleh logika inti yang baik dari Equiman sebelumnya di utas ini.)

sessionExpiration.js


sessionExpiration.js ringan namun efektif dan dapat disesuaikan. Setelah diimplementasikan, gunakan hanya dalam satu baris:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Mempengaruhi semua tab browser, bukan hanya satu.
  • Ditulis dalam JavaScript murni , tanpa dependensi. Sisi klien sepenuhnya.
  • (Jika diinginkan). Memiliki spanduk peringatan dan jam hitung mundur , yang dibatalkan oleh interaksi pengguna.
  • Cukup sertakan sessionExpiration.js , dan panggil fungsi tersebut, dengan argumen [1] jumlah menit kosong (di semua tab) hingga pengguna keluar, [2] jumlah menit idle hingga peringatan dan hitungan mundur ditampilkan, dan [3] url logout
  • Masukkan CSS ke dalam stylesheet Anda. Kustomisasi jika Anda mau.(Atau lewati dan hapus spanduk jika Anda tidak menginginkannya.)
  • Jika Anda melakukan ingin banner peringatan Namun, maka Anda harus menempatkan div kosong dengan ID sessExpirDiv pada halaman Anda (saran adalah meletakkan itu di footer) .
  • Sekarang pengguna akan keluar secara otomatis jika semua tab tidak aktif selama durasi yang diberikan.
  • Opsional: Anda dapat memberikan argumen keempat (URL serverRefresh) untuk fungsi tersebut, sehingga pengatur waktu sesi sisi server juga disegarkan saat Anda berinteraksi dengan halaman.

Ini adalah contoh dari apa yang terlihat dalam tindakan, jika Anda tidak mengubah CSS.

demo_image

Fom
sumber
3

Saya menulis plugin jQuery sederhana yang akan melakukan apa yang Anda cari.

https://github.com/afklondon/jquery.inactivity

$(document).inactivity( {
    interval: 1000, // the timeout until the inactivity event fire [default: 3000]
    mouse: true, // listen for mouse inactivity [default: true]
    keyboard: false, // listen for keyboard inactivity [default: true]
    touch: false, // listen for touch inactivity [default: true]
    customEvents: "customEventName", // listen for custom events [default: ""]
    triggerAll: true, // if set to false only the first "activity" event will be fired [default: false]
});

Script akan mendengarkan mouse, keyboard, touch, dan aktivitas tidak aktif lainnya (idle) dan menjalankan "aktivitas" global dan "aktivitas" tidak aktif.

Semoga ini membantu :)

Alexandros Filos Kaparelos
sumber
Apakah benar-benar ada kebutuhan untuk penundaan, bukankah memicu acara khusus dari penangan acara khusus cukup?
Hibou57
2

Hanya beberapa pemikiran, satu atau dua jalan untuk dijelajahi.

Apakah mungkin menjalankan fungsi setiap 10 detik, dan memeriksanya sebagai variabel "penghitung"? Jika itu memungkinkan, Anda dapat memiliki mouseover untuk halaman tersebut, bukan? Jika demikian, gunakan event mouseover untuk mereset variabel "counter". Jika fungsi Anda dipanggil, dan penghitung berada di atas rentang yang Anda tentukan sebelumnya, maka lakukan tindakan Anda.

Sekali lagi, hanya beberapa pemikiran ... Semoga ini bisa membantu.

Mark Rullo
sumber
2

Saya telah menguji file kode ini:

var timeout = null;
    var timee = '4000'; // default time for session time out.
    $(document).bind('click keyup mousemove', function(event) {

    if (timeout !== null) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
              timeout = null;
            console.log('Document Idle since '+timee+' ms');
            alert("idle window");
        }, timee);
    });
Vishal Jaura
sumber
2

Inilah solusi terbaik yang saya temukan: http://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

Inilah JS:

idleTimer = null;
idleState = false;
idleWait = 2000;

(function ($) {

    $(document).ready(function () {

        $('*').bind('mousemove keydown scroll', function () {

            clearTimeout(idleTimer);

            if (idleState == true) { 

                // Reactivated event
                $("body").append("<p>Welcome Back.</p>");            
            }

            idleState = false;

            idleTimer = setTimeout(function () { 

                // Idle Event
                $("body").append("<p>You've been idle for " + idleWait/1000 + " seconds.</p>");

                idleState = true; }, idleWait);
        });

        $("body").trigger("mousemove");

    });
}) (jQuery)
Casey
sumber
2

Anda dapat menggunakan solusi yang disebutkan di bawah ini

var idleTime;
$(document).ready(function () {
         reloadPage();
        $('html').bind('mousemove click mouseup mousedown keydown keypress keyup submit change mouseenter scroll resize dblclick', function () {
            clearTimeout(idleTime);
            reloadPage();
        });
});
function reloadPage() {
    clearTimeout(idleTime);
    idleTime = setTimeout(function () {
        location.reload();
    }, 3000);
}
Abhishek
sumber
2

Saya menggunakan pendekatan ini, karena Anda tidak perlu terus-menerus mengatur ulang waktu ketika suatu peristiwa menyala, sebagai gantinya kami hanya mencatat waktu, ini menghasilkan titik awal yang tidak digunakan.

           function idle(WAIT_FOR_MINS, cb_isIdle) {
            var self = this, 
                idle,
                ms = (WAIT_FOR_MINS || 1) * 60000,
                lastDigest = new Date(),
                watch;
            //document.onmousemove = digest;
            document.onkeypress = digest;
            document.onclick = digest;

            function digest() {
               lastDigest = new Date(); 
            }
            // 1000 milisec = 1 sec
            watch = setInterval(function(){
                if (new Date() - lastDigest > ms && cb_isIdel) {
                    clearInterval(watch);
                    cb_isIdle();
                }

            }, 1000*60);    
        },
MartinWebb
sumber
1

Anda mungkin dapat mendeteksi ketidakaktifan pada halaman web Anda menggunakan trik mousemove terdaftar, tetapi itu tidak akan memberi tahu Anda bahwa pengguna tidak pada halaman lain di jendela atau tab lain, atau bahwa pengguna berada di Word atau Photoshop, atau WOW dan tidak melihat halaman Anda saat ini. Secara umum saya hanya akan melakukan prefetch dan mengandalkan multi-tasking klien. Jika Anda benar - benar membutuhkan fungsi ini, Anda melakukan sesuatu dengan kontrol activex di windows, tetapi itu paling jelek.

Walden Leverich
sumber
1

Berikut adalah layanan AngularJS untuk menyelesaikan di Angular.

/* Tracks now long a user has been idle.  secondsIdle can be polled 
   at any time to know how long user has been idle. */
fuelServices.factory('idleChecker',['$interval', function($interval){
    var self = {
        secondsIdle: 0,
        init: function(){
            $(document).mousemove(function (e) {
                self.secondsIdle = 0;
            });
            $(document).keypress(function (e) {
                self.secondsIdle = 0;
            });
            $interval(function(){
                self.secondsIdle += 1;
            }, 1000)
        }
    }
    return self;
}]);

Ingatlah bahwa pemeriksa siaga ini akan berjalan untuk semua rute, sehingga harus diinisialisasi .run()saat memuat aplikasi bersudut. Kemudian Anda dapat menggunakan idleChecker.secondsIdledi dalam setiap rute.

myApp.run(['idleChecker',function(idleChecker){
    idleChecker.init();
}]);
ditenagai uap
sumber
1

Debounce sebenarnya ide bagus! Di sini versi untuk proyek gratis jQuery:

const derivedLogout = createDerivedLogout(30);
derivedLogout(); // it could happen that user too idle)
window.addEventListener('click', derivedLogout, false);
window.addEventListener('mousemove', derivedLogout, false);
window.addEventListener('keyup', derivedLogout, false); 

function createDerivedLogout (sessionTimeoutInMinutes) {
    return _.debounce( () => {
        window.location = this.logoutUrl;
    }, sessionTimeoutInMinutes * 60 * 1000 ) 
}
Gleb Dolzikov
sumber
1

Sesederhana itu bisa, deteksi ketika mouse hanya bergerak:

var idle = false;

document.querySelector('body').addEventListener('mousemove', function(e) {
    if(idle!=false)idle = false;
});

var idleI = setInterval(function()
{   
    if(idle == 'inactive')
    {
        return;
    }

    if(idle == true)
    {
        idleFunction();
        idle = 'inactive';
        return;
    }

    idle = true;
}, 30000);// half the expected time, idle will trigger after 60s in this case.

function idleFuntion()
{
   console.log('user is idle');
}
lucss
sumber
0

Yah Anda bisa melampirkan klik atau acara mouse ke badan dokumen yang mengatur ulang timer. Memiliki fungsi yang Anda panggil pada interval waktu yang memeriksa apakah timer melebihi waktu yang ditentukan (seperti 1000 milis) dan mulai preloading Anda.

Eric Wendelin
sumber
0

Javascript tidak memiliki cara untuk mengatakan penggunaan CPU. Ini akan merusak sandbox javascript berjalan di dalamnya.

Selain itu, mengaitkan peristiwa onmouseover dan onkeydown halaman mungkin akan berhasil.

Anda juga bisa mengatur penggunaan setTimeout di acara onload untuk menjadwalkan fungsi yang akan dipanggil setelah penundaan.

// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);
Powerlord
sumber
3
Saya bertanya-tanya mengapa begitu banyak downvotes pada jawaban ini. Sejauh yang saya bisa lihat, itu memang menjawab pertanyaan yang diajukan, dan secara faktual benar. Hanya saja tidak melanjutkan untuk memberikan contoh kode yang rumit.
Ifedi Okonkwo
1
Sekarang dimungkinkan untuk memanggil fungsi javascript ketika "ada waktu luang di akhir bingkai, atau ketika pengguna tidak aktif." Developers.google.com/web/updates/2015/08/…
Maks.
setTimeout 0 mungkin lebih benar untuk menghitung dalam rata seberapa penuh buffer dengan meluangkan waktu antara FILO