Wie man Leerlaufzeit in JavaScript erkennt
Ist es möglich, "Leerlauf"-Zeit in JavaScript zu erkennen?
Mein Hauptanwendungsfall wäre wahrscheinlich, Inhalte vorab abzurufen oder vorzuladen.
Ich definiere Leerlaufzeit als einen Zeitraum der Benutzerinaktivität oder ohne jegliche CPU-Nutzung
Antwort #1
Mit reinem JavaScript:
var inactivityTime = function () {
var time;
window.onload = resetTimer;
// DOM Events
document.onmousemove = resetTimer;
document.onkeydown = 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
}
};
Und initialisiere die Funktion dort, wo du sie benötigst (zum Beispiel: beim Laden der Seite).
window.onload = function() {
inactivityTime();
}
Sie können bei Bedarf weitere DOM-Ereignisse hinzufügen. Die am häufigsten verwendeten sind:
document.onload = resetTimer;
document.onmousemove = resetTimer;
document.onmousedown = resetTimer; // touchscreen presses
document.ontouchstart = resetTimer;
document.onclick = resetTimer; // touchpad clicks
document.onkeydown = resetTimer; // onkeypress is deprectaed
document.addEventListener('scroll', resetTimer, true); // improved; see comments
Oder registrieren Sie gewünschte Ereignisse mit einem Array
window.addEventListener('load', resetTimer, true);
var events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
events.forEach(function(name) {
document.addEventListener(name, resetTimer, true);
});
DOM-Ereignisse Liste: http://www.w3schools.com/jsref/dom_obj_event.asp
Denken Sie daran, window oder document entsprechend Ihren Bedürfnissen zu verwenden. Hier können Sie die Unterschiede zwischen ihnen sehen: Was ist der Unterschied zwischen window, screen und document in JavaScript?
Code aktualisiert mit @frank-conijn und @daxchen Verbesserung: window.onscroll wird nicht ausgelöst, wenn innerhalb eines scrollbaren Elements gescrollt wird, da Scroll-Ereignisse nicht aufsteigen. In window.addEventListener('scroll', resetTimer, true) gibt das dritte Argument an, dass der Listener das Ereignis während der Erfassungsphase anstelle der Aufstiegsphase abfangen soll.
Antwort #2
Hier ist ein einfaches Skript mit jQuery, das Mausbewegungs- und Tastendrücke-Ereignisse behandelt. Wenn die Zeit abläuft, wird die Seite neu geladen.
<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>
Antwort #3
Verbesserung der (ursprünglichen) Antwort von Equiman:
function noIdlingHere() {
function yourFunction() {
// your function for too long inactivity goes here
// e.g. window.location.href = 'logout.php';
}
let t; // must be declared here
function resetTimer() {
clearTimeout(t); // global function
t = setTimeout(yourFunction, 600000); // time is in milliseconds (10 min)
}
window.addEventListener('load', resetTimer, true);
window.addEventListener('mousemove', resetTimer, true);
window.addEventListener('mousedown', resetTimer, true);
window.addEventListener('touchstart', resetTimer, true);
window.addEventListener('touchmove', resetTimer, true);
window.addEventListener('click', resetTimer, true);
window.addEventListener('keydown', resetTimer, true);
window.addEventListener('scroll', resetTimer, true);
window.addEventListener('wheel', resetTimer, true);
}
noIdlingHere();
Abgesehen von den Verbesserungen bezüglich der Aktivitätserkennung und der Änderung von document zu window, ruft dieses Script tatsächlich die Funktion auf, anstatt sie untätig liegen zu lassen.
Es erfasst nicht direkt null CPU-Auslastung, aber das ist unmöglich, weil die Ausführung einer Funktion CPU-Auslastung verursacht. Und Nutzerinaktivität führt schließlich zu null CPU-Auslastung, also erfasst es indirekt null CPU-Auslastung.
Antwort #4
Ich habe eine kleine Bibliothek erstellt, die Folgendes tut:
https://github.com/shawnmclean/Idle.js
Beschreibung:
Winzige JavaScript-Bibliothek, um die Aktivität des Benutzers im Browser zu melden (abwesend, inaktiv, sieht die Webseite nicht an, in einem anderen Tab usw.), die unabhängig von anderen JavaScript-Bibliotheken wie jQuery ist.
Visual Studio-Benutzer können es über NuGet erhalten, indem sie:
Install-Package Idle.js
Antwort #5
Hier ist eine grobe jQuery-Implementierung von tvanfossons Idee:
$(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 any action.
$(this).bind('mousemove keydown scroll click', function (e) {
idleTime = 0;
//Do something
});
function doPreload()
{
//Preload images, etc.
}
})
Antwort #6
Ähnlich wie bei Peters J-Lösung (mit einem benutzerdefinierten jQuery-Ereignis)...
// Use the 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...
});
Datei 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 the 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; // Minimum 100 ms
if (timeout > 300000)
timeout = 300000; // Maximum 5 minutes
idleTimer = setTimeout(idleStart, timeout); // New timer
}
function idleStart() {
if (!idle)
$w.trigger('idle:start');
idle = true;
}
}(window.jQuery, window.jQuery(window)))
Antwort #7
Sie können es eleganter mit Underscore.js und jQuery machen:
$('body').on("click mousemove keyup", _.debounce(function(){
// do preload here
}, 1200000)) // 20 minutes debounce
Antwort #8
Alle vorherigen Antworten haben einen immer aktiven Mousemove-Handler. Wenn der Handler jQuery ist, kann die zusätzliche Verarbeitung, die jQuery durchführt, sich summieren. Besonders wenn der Benutzer eine Gaming-Maus verwendet, können bis zu 500 Ereignisse pro Sekunde auftreten.
Diese Lösung vermeidet die Verarbeitung jedes Mousemove-Ereignisses. Dies führt zu einem kleinen Zeitfehler, den Sie jedoch nach Ihren Bedürfnissen anpassen können.
function setIdleTimeout(millis, onIdle, onUnidle) {
var timeout = 0;
startTimer();
function startTimer() {
timeout = setTimeout(onExpires, millis);
document.addEventListener("mousemove", onActivity);
document.addEventListener("keydown", onActivity);
document.addEventListener("touchstart", 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);
document.removeEventListener("touchstart", onActivity);
setTimeout(startTimer, 1000);
}
}
http://jsfiddle.net/9exz43v2/
Antwort #9
Meine Antwort wurde von Vijays Antwort inspiriert, ist aber eine kürzere, allgemeinere Lösung, die ich teilen wollte für jeden, dem sie helfen könnte.
(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);
}());
Wie es derzeit aussieht, wird dieser Code sofort ausgeführt und Ihre aktuelle Seite nach 3 Minuten ohne Mausbewegung oder Tastendruck neu laden.
Dies verwendet einfaches Vanilla-JavaScript und einen sofort aufgerufenen Funktionsausdruck, um Leerlauf-Timeouts auf eine saubere und eigenständige Weise zu handhaben.
Antwort #10
Ich hatte dasselbe Problem und ich habe eine ziemlich gute Lösung gefunden.
Ich habe jquery.idle verwendet und musste nur Folgendes tun:
$(document).idle({
onIdle: function(){
alert('You did nothing for 5 seconds');
},
idle: 5000
})
Siehe JsFiddle-Demo.
(Nur zur Information: Siehe dies für das Back-End-Ereignis-Tracking Leads Browserladevorgang)
Antwort #11
Wenn Sie einen unterstützten Browser (Chrome oder Firefox ab Dezember 2018) anvisieren, können Sie mit requestIdleCallback experimentieren und das requestIdleCallback-Shim für nicht unterstützte Browser einfügen.
Antwort #12
Du könntest wahrscheinlich etwas zusammenbasteln, indem du die Mausbewegungen am Formularkörper erkennst und eine globale Variable mit der letzten Bewegungszeit aktualisierst. Dann müsstest du einen Intervall-Timer laufen lassen, der periodisch die letzte Bewegungszeit überprüft und etwas unternimmt, wenn seit der letzten Mausbewegung genügend Zeit vergangen ist.
Antwort #13
Ich habe eine kleine ES6-Klasse geschrieben, um Aktivität zu erkennen und sonst Ereignisse bei Inaktivität auszulösen. Sie deckt Tastatur, Maus und Touch ab, kann aktiviert und deaktiviert werden und hat eine sehr schlanke API:
const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();
Es hängt nicht von jQuery ab, obwohl Sie es möglicherweise durch Babel laufen lassen müssen, um ältere Browser zu unterstützen.
https://gist.github.com/4547ef5718fd2d31e5cdcafef0208096
