Come rilevare elegantemente i tempi di inattività in JavaScript?


479

È possibile rilevare il tempo " inattivo " in JavaScript?
Il mio caso d'uso principale sarebbe probabilmente precaricare o precaricare il contenuto.

Tempo di inattività: periodo di inattività dell'utente o senza utilizzo della CPU


7
Come si definisce IDLE TIME?
Itay Moav -Malimovka,


74
Quasi il 50% delle risposte qui ha utilizzato jQuery per un compito così semplice per Javascript puro. È oltre stupido, soprattutto perché l'OP voleva Javascript. Richiedi il gelato alla fragola ma ottieni invece un fienile semi indipendente.
TheCarver

4
questo è StackOverflow per te
robertmain

5
@TheCarver - Dover installare una libreria jQuery per qualcosa di così semplice è davvero ridicolo e allunga i tempi di rendering e aumenta il consumo di energia. Le persone dovrebbero scorrere un po 'più in basso. Esiste anche una soluzione quasi copia-incolla in Javascript vaniglia.
Frank Conijn,

Risposte:


439

Ecco un semplice script che utilizza JQuery che gestisce gli eventi mousemove e keypress. Se il tempo scade, la pagina viene ricaricata.

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

16
Ti manca un punto e virgola dopo il corpo $ (document) .ready (function (). Inoltre, nella chiamata a setInterval, non funzionerà con virgolette attorno al nome della funzione e non avrai bisogno delle parentesi dopo di esso. Solo: setInterval (timerIncrement, 60000)
Jesse Roper

9
@Jesse: i tuoi suggerimenti sono tutti validi, ecco come dovrebbe essere il codice. Ma volevo solo sottolineare che anche senza queste modifiche, il codice è perfettamente funzionante. I punti e virgola alla fine di un'istruzione di espressione sono facoltativi e puoi infatti passare una stringa a setInterval, che viene quindi valutata come JavaScript.
Felix Kling

6
Potresti semplicemente usare idleTime++;invece diidleTime = idleTime + 1;
Mike Causer il

7
Non è pesante sul sistema di un utente? Diciamo, un utente con un browser abbastanza vecchio su un PC non troppo pesante, lavora in un'applicazione javascript per mezza giornata e sta elaborando queste funzioni ogni volta che l'utente sposta il mouse ... Mi chiedo se questo ha vinto ' influenzano l'esperienza dell'utente ...
Sander,

5
@PietBinnenbocht Inoltre, se inizi a ottimizzare cose come questa, puoi anche cambiare ogni funzione che accetta stringhe come 'mousemove keydown click'usare bit flags ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK), poiché sono più veloci delle operazioni sulle stringhe. Ma vuoi davvero farlo?
Killah,

362

Senza usare jQuery, solo JavaScript vaniglia:

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

E avvia la funzione dove ti serve (ad esempio: onPageLoad).

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

È possibile aggiungere più eventi DOM, se necessario. I più utilizzati sono:

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

Oppure registra gli eventi desiderati utilizzando un array

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

Elenco eventi DOM : http://www.w3schools.com/jsref/dom_obj_event.asp

Ricorda l'uso windowo in documentbase alle tue esigenze. Qui puoi vedere le differenze tra loro: Qual è la differenza tra finestra, schermo e documento in Javascript?

Il codice aggiornato con @ frank-conijn e @daxchen migliora: window.onscrollnon si attiva se lo scorrimento è all'interno di un elemento scorrevole, perché gli eventi di scorrimento non si gonfiano. window.addEventListener('scroll', resetTimer, true), il terzo argomento dice all'ascoltatore di catturare l'evento durante la fase di acquisizione anziché la fase di bolla.


58
Mi piace molto di più l'approccio javascript semplice.
Manatax,

4
reimpostare definitivamente un timer è un approccio più diretto / intuitivo e accurato rispetto al fatto che un timeout faccia la sua cosa, solo per mantenere un numero intero di un'altra cosa, quando il timer stesso può ESSERE il contatore (alta precisione).
Josh Sutterfield,

2
@mpsbhat basta aggiungere un console.log o un avviso per vedere se funziona. O registra questo evento:document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
equiman

2
Sì ... Funzionando. jsfiddle.net/mpsbhat/6b6mja5t/1 . Grazie @equiman
mpsbhat il

6
Sarebbe molto meglio avere una bandiera var notidle; imposta quel flag = vero solo sugli eventi. Quindi nel test di funzione resetTimer se il flag notidle è vero, se viene reimpostato il timer loro o chiama il logout. Ciò eliminerà il sovraccarico di complessità del ripristino costante del timer.
MartinWebb,

75

Migliorare la risposta di 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();

.
A parte i miglioramenti riguardanti il ​​rilevamento delle attività e la modifica da documenta window, questo script in realtà chiama la funzione, piuttosto che lasciarla inattiva.

Non rileva direttamente l'utilizzo della CPU pari a zero, ma ciò è impossibile, poiché l'esecuzione di una funzione provoca l'utilizzo della CPU. E l'inattività dell'utente alla fine porta a zero utilizzo della CPU, quindi indirettamente cattura zero utilizzo della CPU.


3
Volevo solo sottolineare che window.onscrollnon si attiva se lo scorrimento è all'interno di un elemento scorrevole, perché gli eventi di scorrimento non fanno bolle. Usando window.addEventListener('scroll', resetTimer, true), il terzo argomento dice all'ascoltatore di catturare l'evento durante la capturefase anziché la bubblefase (IE> 8), vedi questa risposta
DaxChen

@DaxChen - Non document.onscrollha lo stesso problema, non sparare se lo scorrimento è all'interno di un bambino scorrevole?
Frank Conijn,

2
Sì, il punto che stavo dicendo è usare al addEventListenerposto di onscroll.
DaxChen,

@DaxChen - OK, mi chiedevo se intendevi quello, aggirare il problema, ma ora è chiaro. Ho modificato la risposta di conseguenza. Grazie per il commento.
Frank Conijn,

Aggiornerò la mia risposta con queste informazioni importanti, per evitare altre copie e incollare il mio errore. Grazie @DaxChen e Frank
equiman,

33

Ho creato una piccola libreria che lo fa un anno fa:

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

Descrizione:

Minuscola libreria javascript per segnalare l'attività dell'utente nel browser (assente, inattivo, non guardando la pagina web, in un'altra scheda, ecc.). che è indipendente da qualsiasi altra libreria javascript come jquery.

Gli utenti di Visual Studio possono ottenerlo da NuGet: PM> Install-Package Idle.js


32

Ecco un'implementazione approssimativa di jQuery dell'idea di 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.
   }

})

9
Questa soluzione non considera gli eventi della tastiera.
Daniel Silveira,

7
Non passare mai setIntervaluna stringa! Basta dare una funzione come variabile!
Eric

1
In realtà non funzionerà perché passare una stringa per setInterval()valutare l'espressione nell'ambito globale e quindi non troverà la timerIncrement()funzione che si trova all'interno della funzione del gestore .ready. Questa è un'altra ragione per non passare MAI le stringhe setInterval(). Basta passare un riferimento effettivo alla funzione e non si avrà questo problema perché vengono valutati nell'ambito corrente.
jfriend00,

Grazie, non ero a conoscenza della necessità di NON passare MAI le stringhe per impostareInterval. Aggiornato la mia risposta.
Peter J,

24

Simile alla soluzione di Iconic sopra (con evento personalizzato 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)))

20

Puoi farlo in modo più elegante con underscore e jquery -

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

16

La mia risposta è stata ispirata dalla risposta di Vijay , ma è una soluzione più breve e più generale che pensavo di condividere per chiunque potesse aiutare.

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

Allo stato attuale, questo codice verrà eseguito immediatamente e ricaricherà la pagina corrente dopo 3 minuti di inattività del mouse o della pressione dei tasti.

Questo utilizza JavaScript semplice alla vaniglia e un'espressione di funzione immediatamente invocata per gestire i timeout di inattività in modo pulito e autonomo.


document.onclick considera le funzioni javascript usando .trigger ('click') che ho scritto come automatizzato. Quindi non è in realtà un'interazione dell'utente, ma in questo caso reimposterà l'idleCounter
Carmela,

@Carmela: non sono sicuro del perché stia vedendo questo; Devo averlo perso. Grazie, ho rimosso l' onclickassegnazione poiché probabilmente non è necessario in aggiunta a onmousemove, ma ovviamente tutti questi eventi che sono attivati ​​a livello di programmazione continueranno a reimpostarsi idleCounter. Non sono sicuro del motivo per cui simuleresti l'interazione dell'utente invece di chiamare semplicemente una funzione, ma se è qualcosa che devi fare per qualche motivo, questa risposta ovviamente non funzionerà per te, né la maggior parte delle altre risposte che ' ho esaminato questa domanda.
johnnyRose,

15

Conosco una domanda relativamente vecchia, ma ho avuto lo stesso problema e ho trovato una soluzione abbastanza buona.

Ho usato: jquery.idle e dovevo solo fare:

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

Guarda la demo di JsFiddle .

(Solo per informazioni: vedere questo per il monitoraggio degli eventi back-end Lead download del browser )


Come posso interrompere questa funzione, hanno dichiarato un evento inattivo: basta ma sinceramente non so come usarlo. Voglio che se passassi alla pagina successiva (basata su Ajax, quindi solo frammento di pagina HTML aggiornato), la funzione inattiva si interrompe. Sapevi come raggiungere questo obiettivo?
Mubasher,

Qui dice: "inattivo: stop": interromperà e rimuoverà il tracciamento degli utenti
DDan

Ho già letto ma non sono riuscito a capire come usarlo, potresti aiutarmi?
Mubasher,

Se vuoi che si attivi solo una volta, puoi impostare l' keepTrackingopzione su false. Se si desidera ripristinare, è possibile provare a reinizializzare è. Ecco un esempio modificato che sparerebbe
DDan

No, non sparo una volta, keepTracking dovrebbe essere vero, ma sulla navigazione verso un'altra pagina voglio fermarlo
Mubasher

15

Tutte le risposte precedenti hanno un gestore mousemove sempre attivo. Se il gestore è jQuery, è possibile aggiungere l'elaborazione aggiuntiva che jQuery esegue. Soprattutto se l'utente utilizza un mouse da gioco, possono verificarsi fino a 500 eventi al secondo.

Questa soluzione evita la gestione di ogni evento mousemove. Ciò si traduce in un piccolo errore di temporizzazione, ma che puoi adattare alle tue necessità.

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/


1
Funzionerà automaticamente se inserito in una pagina o deve essere all'interno di un wrapper $ (document) .ready ()? Grazie! Inoltre, dov'è la parte che esegue un'azione alla scadenza del timer?
Arance13

1
Puoi chiamarlo in qualsiasi momento, anche prima che il documento sia pronto. Si passa una funzione 'callback' che verrà chiamata alla scadenza del timer.
Sarsaparilla,

1
Il $(startTimer)è equivalente a $(document).ready(startTimer), assicura che il DOM è pronto prima di agganciare il mousemove ed eventi di pressione.
Sarsaparilla,

1
+1 Questo è quello che faccio: i gestori mousemove contribuiscono alla lentezza e alla durata della batteria ridotta, quindi accenderlo periodicamente è un'ottima idea se puoi permetterti l'errore di temporizzazione minore. Di solito uso il rilevamento del tempo di inattività per gli avvisi di scadenza automatica della sessione (ad esempio "Sei ancora lì?"), Quindi tendo ad avere molti minuti prima che un utente diventi "inattivo", nel qual caso un piccolo errore di temporizzazione è totalmente irrilevante.
capra

1
È meglio usare "keydown" che "keypress" perché i tasti freccia non vengono rilevati dall'evento "keypress". Quindi, se l'utente sta navigando nella pagina usando i tasti freccia, diventerà comunque Inattivo.
aFerrer

13

Probabilmente potresti hackerare qualcosa insieme rilevando il movimento del mouse sul corpo del modulo e aggiornando una variabile globale con l'ultimo tempo di movimento. Dovresti quindi avere un timer ad intervalli che controlla periodicamente l'ultimo tempo di movimento e fa qualcosa se è stato sufficientemente lungo da quando è stato rilevato l'ultimo movimento del mouse.


È importante notare che lo script sarà in grado di rilevare solo il movimento sul corpo della pagina, non tutti gli input dell'utente. Non credo che ci sia un modo per ottenere informazioni sulla CPU o sul processo da JavaScript.
Dave Swersky,

1
Mi sono preso la libertà di implementare la tua idea in jQuery.
Peter J,

9

Ho scritto una piccola classe ES6 per rilevare attività e altrimenti generare eventi in timeout inattivo. Copre tastiera, mouse e touch , può essere attivato e disattivato e ha un'API molto snella:

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

Essa non dipende da jQuery, anche se potrebbe essere necessario eseguire attraverso Babel per supportare i browser più vecchi.

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

Potrei rilasciarlo come pacchetto npm una volta ricevuto un feedback.


8

Se stai scegliendo come target un browser supportato (Chrome o Firefox a dicembre 2018), puoi provare la richiestaIdleCallback e includere lo shim requestIdleCallback per i browser non supportati.


E lasciare gli altri browser da soli?
Frank Conijn,

Lo spessore copre tutti i browser. E questa è stata l'unica risposta! Altre risposte al rallentamento riguardano il mouse. L'interattività o la CPU sono state dette solo come esempio. Come rilevare la CPU inattiva con una soluzione del mouse?

6

Prova questo codice, funziona perfettamente.

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

più 1 per essere vaniglia js
frostymarvelous il

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> 

Penso che questo codice jquery sia perfetto, anche se copiato e modificato dalle risposte sopra !! non hai dimenticato di includere la libreria jquery nel tuo file!


4

Il problema con tutte queste soluzioni, sebbene corrette, sono poco pratiche, se si tiene conto del prezioso set di timeout della sessione, utilizzando PHP, .NET o nel file Application.cfc per gli sviluppatori Coldfusion. Il tempo impostato dalla soluzione precedente deve essere sincronizzato con il timeout della sessione lato server. Se i due non si sincronizzano, puoi imbatterti in problemi che potrebbero frustrare e confondere i tuoi utenti. Ad esempio, il timeout della sessione lato server potrebbe essere impostato su 60 minuti, ma l'utente può ritenere che sia sicuro, poiché l'acquisizione del tempo di inattività JavaScript ha aumentato il tempo totale che un utente può trascorrere su una singola pagina. L'utente potrebbe aver trascorso del tempo a compilare un modulo lungo, quindi a inviarlo. Il timeout della sessione potrebbe essere avviato prima che l'elaborazione del modulo venga inviato. Tendo a dare ai miei utenti solo 180 minuti, e quindi utilizzare JavaScript per disconnettere automaticamente l'utente. In sostanza, usando parte del codice sopra, per creare un semplice timer, ma senza la parte di evento del mouse di acquisizione. In questo modo il mio lato client e lato server si sincronizza perfettamente. Non c'è confusione, se si mostra il tempo all'utente nell'interfaccia utente, in quanto riduce. Ogni volta che si accede a una nuova pagina nel CMS, la sessione lato server e il timer JavaScript vengono ripristinati. Semplice ed elegante Se un utente rimane su una singola pagina per più di 180 minuti, immagino che ci sia qualcosa di sbagliato nella pagina, in primo luogo. in quanto riduce. Ogni volta che si accede a una nuova pagina nel CMS, la sessione lato server e il timer JavaScript vengono ripristinati. Semplice ed elegante Se un utente rimane su una singola pagina per più di 180 minuti, immagino che ci sia qualcosa di sbagliato nella pagina, in primo luogo. in quanto riduce. Ogni volta che si accede a una nuova pagina nel CMS, la sessione lato server e il timer JavaScript vengono ripristinati. Semplice ed elegante Se un utente rimane su una singola pagina per più di 180 minuti, immagino che ci sia qualcosa di sbagliato nella pagina, in primo luogo.


1
Sì, è per questo che lo sto facendo solo dopo aver eliminato le sessioni lato server e aver caricato tutto dai file html.
Dan Parker,

4

JavaScript puro con tempo di reimpostazione e collegamenti impostati correttamente tramite 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);
  });

}());

4

(In parte ispirato alla buona logica di base di Equiman all'inizio di questo thread.)

sessionExpiration.js


sessionExpiration.js è leggero ma efficace e personalizzabile. Una volta implementato, utilizzare in una sola riga:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Interessa tutte le schede del browser, non solo una.
  • Scritto in puro JavaScript , senza dipendenze. Completamente lato client.
  • (Se desiderato). Ha un banner di avviso e un conto alla rovescia , che viene annullato dall'interazione dell'utente.
  • Includi semplicemente sessionExpiration.js e chiama la funzione, con argomenti [1] numero di minuti di inattività (in tutte le schede) fino a quando l'utente non viene disconnesso, [2] numero di minuti di inattività fino a quando non viene visualizzato l'avviso e il conto alla rovescia, e [3] URL di logout.
  • Inserisci il CSS nel tuo foglio di stile. Personalizzalo se vuoi. (O salta ed elimina il banner se non lo desideri.)
  • Se si fa desiderare la bandiera avvertimento però, è necessario mettere un div vuoto con ID sessExpirDiv sulla tua pagina (un suggerimento sta mettendo nel piè di pagina) .
  • Ora l'utente verrà disconnesso automaticamente se tutte le schede sono state inattive per la durata indicata.
  • Facoltativo: è possibile fornire un quarto argomento (URL serverRefresh) alla funzione, in modo che anche un timer di sessione lato server venga aggiornato quando si interagisce con la pagina.

Questo è un esempio di come appare in azione, se non cambi il CSS.

demo_image


3

Ho scritto un semplice plugin jQuery che farà quello che stai cercando.

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

Lo script ascolterà l'inattività del mouse, della tastiera, del tocco e di altri eventi personalizzati (inattività) e genererà eventi "attività" e "inattività" globali.

Spero che sia di aiuto :)


C'è davvero bisogno di un ritardo, non è abbastanza innescare un evento personalizzato da un gestore eventi personalizzato?
Hibou57,

2

Solo qualche pensiero, un viale o due da esplorare.

È possibile eseguire una funzione ogni 10 secondi e verificare che una variabile "counter"? Se è possibile, puoi avere un passaggio del mouse per la pagina, no? In tal caso, utilizzare l'evento mouseover per ripristinare la variabile "contatore". Se viene chiamata la tua funzione e il contatore è al di sopra dell'intervallo che hai predeterminato, allora fai la tua azione.

Ancora una volta, solo alcuni pensieri ... Spero che sia d'aiuto.


2

Ho testato questo file di lavoro del codice:

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

2

Ecco la migliore soluzione che ho trovato: http://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

Ecco il 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)

2

È possibile utilizzare la soluzione di seguito indicata

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

2

Uso questo approccio, dal momento che non è necessario reimpostare costantemente l'ora in cui si verifica un evento, invece registriamo solo l'ora, questo genera il punto iniziale inattivo.

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

1

Probabilmente potresti rilevare l'inattività sulla tua pagina web usando i trucchi mousemove elencati, ma ciò non ti dirà che l'utente non si trova su un'altra pagina in un'altra finestra o scheda, o che l'utente si trova in Word o Photoshop o WOW e semplicemente non sta guardando la tua pagina in questo momento. Generalmente farei semplicemente il prefetch e fare affidamento sul multi-tasking del cliente. Se hai davvero bisogno di questa funzionalità, fai qualcosa con un controllo activex in Windows, ma nella migliore delle ipotesi è brutto.


1

Ecco un servizio AngularJS per la realizzazione in 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;
}]);

Tieni presente che questo correttore di inattività verrà eseguito per tutti i percorsi, quindi dovrebbe essere inizializzato .run()al caricamento dell'app angolare. Quindi è possibile utilizzare idleChecker.secondsIdleall'interno di ogni percorso.

myApp.run(['idleChecker',function(idleChecker){
    idleChecker.init();
}]);

1

Debounce in realtà un'ottima idea! Qui versione per progetti gratuiti 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 ) 
}

1

Il più semplice possibile, rileva solo quando il mouse si sposta:

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

0

Bene, è possibile allegare un evento clic o mousemove al corpo del documento che reimposta un timer. Avere una funzione che si chiama a intervalli temporizzati che controlla se il timer è in un periodo di tempo specificato (come 1000 millis) e avviare il precaricamento.


0

Javascript non ha modo di dire l'utilizzo della CPU. Ciò spezzerebbe il sandbox javascript eseguito all'interno.

A parte questo, probabilmente agganciare gli eventi onmouseover e onkeydown della pagina funzionerebbe.

È inoltre possibile impostare utilizzare setTimeout nell'evento onload per pianificare una funzione da chiamare dopo un ritardo.

// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);

3
Mi chiedo perché così tanti voti negativi su questa risposta. Per quanto posso vedere, ha risposto alla domanda posta ed è effettivamente corretta. Solo non è andato avanti per distribuire esempi di codice elaborati.
Ifedi Okonkwo,

1
Ora è possibile chiamare una funzione javascript quando "c'è tempo libero alla fine di un frame o quando l'utente è inattivo." Developers.google.com/web/updates/2015/08/…
Max

setTimeout 0 è probabilmente più corretto per calcolare in media quanto è pieno il buffer prendendo il tempo tra FILO
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.