Como detectar elegantemente o tempo ocioso no JavaScript?

478

É possível detectar " inativo " " no JavaScript?
Meu caso de uso principal provavelmente seria pré-buscar ou pré-carregar o conteúdo.

Tempo ocioso: período de inatividade do usuário ou sem uso da CPU

Cherian
fonte
7
Como você define IDLE TIME?
Itay Moav -Malimovka 20/03/09
4
verifique github.com/kidh0/jquery.idle
apneadiving 14/10
74
Quase 50% das respostas aqui usaram o jQuery para uma tarefa tão simples para Javascript puro. Está além do absurdo, especialmente porque o OP queria Javascript. Peça sorvete de morango, mas pegue um celeiro geminado.
TheCarver
4
isso é StackOverflow para você
robertmain 8/18
5
@TheCarver - Ter que instalar uma biblioteca jQuery para algo tão simples é realmente ridículo, e aumenta o tempo de renderização e aumenta o uso de energia. As pessoas devem rolar um pouco mais para baixo. Existe uma solução quase copiar e colar em Javascript baunilha também.
Frank Conijn

Respostas:

438

Aqui está um script simples usando JQuery que lida com eventos de remoção de teclado e pressionamento de tecla. Se o tempo expirar, a página será recarregada.

<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
fonte
16
Está faltando um ponto-e-vírgula após o corpo $ (document) .ready (function (). Além disso, na chamada para setInterval, ele não funcionará com aspas ao redor do nome da função e você não precisará dos parênteses. Apenas: setInterval (timerIncrement, 60000)
Jesse Roper
9
@ Jessie: Suas sugestões são todas boas, é assim que o código deve ser. Mas eu só queria ressaltar que, mesmo sem essas alterações, o código é totalmente funcional. O ponto e vírgula no final de uma instrução de expressão é opcional e você pode, de fato, passar uma string para setInterval, que é avaliada como JavaScript.
precisa
6
Você pode simplesmente usar em idleTime++;vez deidleTime = idleTime + 1;
Mike Causer
7
Isso não é pesado no sistema de um usuário? Digamos que um usuário com um navegador bastante antigo em um PC não tão pesado esteja trabalhando em um aplicativo javascript por meio dia e processando essas funções toda vez que o usuário move o mouse ... Será que isso acontecerá? t afetar a experiência do usuário ...
Sander
5
@PietBinnenbocht Além disso, se você começar a otimizar coisas como essa, também poderá alterar todas as funções que 'mousemove keydown click'usam cadeias de caracteres, como o uso de sinalizadores de bit ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK), pois são muito mais rápidas que as operações de cadeia de caracteres. Mas você realmente quer fazer isso?
Killah
361

Sem usar o jQuery, apenas JavaScript baunilha:

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 inicie a função onde você precisar (por exemplo: onPageLoad).

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

Você pode adicionar mais eventos DOM, se necessário. Os mais usados ​​são:

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

Ou registre os eventos desejados usando uma matriz

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

Lista de eventos do DOM : http://www.w3schools.com/jsref/dom_obj_event.asp

Lembre-se de usar windowou de documentacordo com suas necessidades. Aqui você pode ver as diferenças entre eles: Qual é a diferença entre janela, tela e documento em Javascript?

O código atualizado com @ frank-conijn e @daxchen aprimoram: window.onscrollnão será acionado se a rolagem estiver dentro de um elemento rolável, porque os eventos de rolagem não borbulham. window.addEventListener('scroll', resetTimer, true), o terceiro argumento informa ao ouvinte para capturar o evento durante a fase de captura em vez da fase de bolha.

equiman
fonte
58
Eu gosto muito da abordagem javascript simples.
Manatax 08/10/2015
4
Definitivamente, redefinir um timer é uma abordagem mais direta / intuitiva e precisa do que fazer um timeout, apenas para manter uma contagem inteira de outra coisa, quando o próprio timer puder ser o contador (de alta precisão).
Josh Sutterfield 04/04
2
@mpsbhat basta adicionar um console.log ou um alerta e ver se funciona. Ou registre estes eventos:document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
equiman
2
Sim ... trabalhando. jsfiddle.net/mpsbhat/6b6mja5t/1 . Obrigado @equiman
mpsbhat
6
Seria muito melhor ter um flag var notidle; defina que flag = true apenas nos eventos. Em seguida, na função resetTimer, teste se o sinalizador de notidle é verdadeiro, se é redefinido o cronômetro ou o logout da chamada. Isso removerá a sobrecarga de complexidade de redefinir constantemente o timer.
MartinWebb
75

Melhorando a resposta de 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();

.
Além das melhorias relacionadas à detecção de atividades e à mudança de documentpara window, esse script realmente chama a função, em vez de deixá-la ociosa.

Ele não captura o uso zero da CPU diretamente, mas isso é impossível, porque a execução de uma função causa o uso da CPU. E a inatividade do usuário acaba levando a zero uso da CPU; portanto, indiretamente, ele captura zero uso da CPU.

Frank Conijn
fonte
3
Só queria salientar que window.onscrollnão será acionado se a rolagem estiver dentro de um elemento rolável, porque os eventos de rolagem não borbulham. Usando window.addEventListener('scroll', resetTimer, true), o terceiro argumento diz ao ouvinte para o evento capturas durante capturefase em vez de bubblefase (IE> 8), veja esta resposta
DaxChen
@DaxChen - Não document.onscrolltem o mesmo problema, não dispara se a rolagem estiver dentro de um filho rolável?
Frank Conijn
2
Sim, o que eu estava dizendo é usar em addEventListenervez de onscroll.
DaxChen
@DaxChen - OK, eu queria saber se você quis dizer isso, para contornar isso, mas está claro agora. Eu editei a resposta em conformidade. Obrigado pelo comentário.
Frank Conijn
Atualizarei minha resposta com essas informações importantes para evitar outras cópias e colar meu erro. Obrigado @DaxChen e Frank
equiman 18/10/19
33

Eu criei uma pequena lib que faz isso há um ano:

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

Descrição:

Pequena biblioteca javascript para relatar a atividade do usuário no navegador (ausente, ocioso, sem olhar para a página da Web, em uma guia diferente, etc.). que é independente de outras bibliotecas javascript, como jquery.

Os usuários do Visual Studio podem obtê-lo no NuGet: PM> Install-Package Idle.js

Shawn Mclean
fonte
32

Aqui está uma implementação aproximada do jQuery da ideia de 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
fonte
9
Esta solução não considera eventos de teclado.
Daniel Silveira
7
Nunca passe setIntervaluma corda! Apenas dê uma função como uma variável!
Eric
1
Na verdade, isso não funcionará porque passar uma string para setInterval()avaliar a expressão no escopo global e, portanto, não encontrará a timerIncrement()função que está dentro da função manipulador .ready. Esse é mais um motivo para NUNCA passar as strings setInterval(). Basta passar uma referência de função real e você não terá esse problema porque eles são avaliados no escopo atual.
precisa saber é
Obrigado, eu não estava ciente da necessidade de nunca passar seqüências de caracteres para setInterval. Atualizei minha resposta.
Peter J
24

Semelhante à solução da Iconic acima (com evento personalizado 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)))
Tracker1
fonte
20

Você pode fazer isso de forma mais elegante com sublinhado e jquery -

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

Minha resposta foi inspirada na resposta de vijay , mas é uma solução mais curta e geral que pensei em compartilhar para qualquer pessoa que pudesse ajudar.

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

Como está atualmente, esse código será executado imediatamente e recarregará sua página atual após 3 minutos sem nenhum movimento do mouse ou pressionamento de tecla.

Isso utiliza JavaScript simples e uma expressão de função chamada imediatamente para lidar com tempos limite inativos de maneira limpa e independente.

johnnyRose
fonte
O document.onclick considera funções javascript usando .trigger ('click'), que escrevi como automatizado. Portanto, não é realmente uma interação do usuário, mas ele vai redefinir o idleCounter neste caso
Carmela
@Carmela: Não sei por que estou vendo isso; Eu devo ter perdido. Obrigado, removi a onclicktarefa, pois provavelmente não é necessário além disso onmousemove, mas obviamente qualquer um desses eventos acionados programaticamente continuará sendo redefinido idleCounter. Não sei por que você simularia a interação do usuário em vez de apenas chamar uma função, mas se for algo que precisa fazer por algum motivo, essa resposta obviamente não funcionará para você, nem a maioria das outras respostas. Eu olhei para esta questão.
precisa saber é o seguinte
15

Sei que é uma pergunta relativamente antiga, mas tive o mesmo problema e encontrei uma solução muito boa.

Eu usei: jquery.idle e só precisava fazer:

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

Veja a demonstração do JsFiddle .

(Apenas para informações: veja isso para rastreamento de eventos de back-end Leads load do navegador )

DDan
fonte
Como posso parar esta função, Eles declararam um evento ocioso: pare, mas honestamente não sei como usar isso. Eu quero que se eu mudei para a página seguinte (com base no Ajax, para que apenas o fragmento da página HTML seja atualizado), a função ociosa será interrompida. Você sabia como conseguir isso?
Mubasher
Aqui diz: "idle: stop": irá parar e remover o rastreamento do usuário #
DDan
Eu já li, mas não consegui descobrir como usar isso. Você poderia me ajudar?
Mubasher
Se você deseja que ele seja acionado apenas uma vez, você pode definir a keepTrackingopção para false. Se você deseja redefinir, você pode tentar reinicializar. Aqui está um exemplo modificado que seria
acionado
Não, eu não disparar uma vez, keepTracking deve ser verdade, mas na navegação para outra página eu quero parar com isso
Mubasher
15

Todas as respostas anteriores têm um manipulador de ratoeiras sempre ativo. Se o manipulador for jQuery, o processamento adicional que o jQuery executa pode ser adicionado. Especialmente se o usuário estiver usando um mouse para jogos, podem ocorrer até 500 eventos por segundo.

Esta solução evita o manuseio de todos os eventos do mouse. Isso resulta em um pequeno erro de tempo, mas que você pode ajustar à sua necessidade.

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/

Salsaparrilha
fonte
1
Isso funcionará automaticamente se colocado em uma página ou precisa estar dentro de um invólucro $ (document) .ready ()? Obrigado! Além disso, onde está a parte que executa uma ação quando o cronômetro expira?
amigos estão
1
Você pode ligar para isso a qualquer momento, mesmo antes de o documento estar pronto. Você passa uma função 'callback' que será chamada quando o timer expirar.
Sarsaparilla
1
O $(startTimer)que equivale a $(document).ready(startTimer), garante que o DOM está pronto antes de ligar o mousemove e eventos keypress.
Sarsaparilla
1
+1 É isso que eu faço - os manipuladores mousemove contribuem para a lentidão e a vida útil da bateria, portanto, ativá-lo periodicamente é uma ótima idéia se você puder pagar um pequeno erro de temporização. Normalmente, eu uso a detecção de tempo ocioso para avisos automáticos de expiração da sessão (por exemplo, "Você ainda está aí?"), Por isso tenho muitos minutos antes que o usuário fique "ocioso"; nesse caso, um pequeno erro de tempo é totalmente irrelevante.
cabra
1
É melhor usar "keydown" do que "keypress" porque as teclas de seta não são detectadas pelo evento "keypress". Portanto, se o usuário estiver navegando na página usando as teclas de seta, ele ficará ocioso de qualquer maneira.
aFerrer
13

Você provavelmente poderia hackear algo ao detectar o movimento do mouse no corpo do formulário e atualizar uma variável global com a última hora do movimento. Você precisaria então ter um temporizador de intervalo em funcionamento que verifique periodicamente o último tempo de movimento e faça alguma coisa se já tiver sido suficientemente longo desde que o último movimento do mouse foi detectado.

tvanfosson
fonte
Importante observar que o script só poderá detectar movimento no corpo da página, nem todas as entradas do usuário. Eu não acho que há uma maneira de obter CPU ou processar informações de javascript.
Dave Swersky 20/03/09
1
Tomei a liberdade de implementar sua ideia no jQuery.
Peter J
9

Eu escrevi uma pequena classe ES6 para detectar atividades e acionar eventos em tempo limite ocioso. Ele cobre teclado, mouse e toque , pode ser ativado e desativado e possui uma API muito enxuta:

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

Ele não depende do jQuery, embora seja necessário executá-lo no Babel para oferecer suporte a navegadores mais antigos.

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

Posso liberá-lo como um pacote npm assim que receber algum feedback.

Capi Etheriel
fonte
8

Se você estiver direcionando um navegador suportado (Chrome ou Firefox em dezembro de 2018), poderá experimentar o requestIdleCallback e incluir o shim requestIdleCallback para navegadores não suportados.

rajsite
fonte
E deixar os outros navegadores em paz?
Frank Conijn
O calço cobre todos os navegadores. E essa foi a única resposta! Outras respostas de lentidão são sobre o mouse. A interatividade ou CPU foi citada apenas como exemplo. Como detectar CPU ociosa com uma solução de mouse?
6

Experimente este código, ele funciona perfeitamente.

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
fonte
mais 1 por ser vanilla js
frostymarvelous 15/12/2015
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> 

Eu acho que esse código jquery é perfeito, apesar de copiado e modificado das respostas acima !! Não esqueça de incluir a biblioteca jquery no seu arquivo!

SPidey
fonte
4

O problema com todas essas soluções, apesar de corretas, é impraticável ao levar em consideração o conjunto valioso de tempo limite da sessão, usando PHP, .NET ou no arquivo Application.cfc para desenvolvedores do Coldfusion. O tempo definido pela solução acima precisa sincronizar com o tempo limite da sessão no servidor. Se os dois não sincronizarem, você poderá encontrar problemas que apenas frustram e confundem seus usuários. Por exemplo, o tempo limite da sessão no servidor pode ser definido como 60 minutos, mas o usuário pode acreditar que está seguro, porque a captura de tempo ocioso do JavaScript aumentou a quantidade total de tempo que um usuário pode gastar em uma única página. O usuário pode ter passado algum tempo preenchendo um formulário longo e depois enviá-lo. O tempo limite da sessão pode ocorrer antes que o envio do formulário seja processado. Costumo dar aos meus usuários 180 minutos, e use o JavaScript para desconectar automaticamente o usuário. Essencialmente, usando parte do código acima, para criar um timer simples, mas sem a parte do evento de captura do mouse. Dessa maneira, meu horário do lado do cliente e do servidor é sincronizado perfeitamente. Não há confusão, se você mostrar o tempo para o usuário na sua interface do usuário, pois ele reduz. Sempre que uma nova página é acessada no CMS, a sessão do servidor e o timer JavaScript são redefinidos. Simples e elegante. Se um usuário permanecer em uma única página por mais de 180 minutos, acho que há algo errado com a página, em primeiro lugar. como reduz. Sempre que uma nova página é acessada no CMS, a sessão do servidor e o timer JavaScript são redefinidos. Simples e elegante. Se um usuário permanecer em uma única página por mais de 180 minutos, acho que há algo errado com a página, em primeiro lugar. como reduz. Sempre que uma nova página é acessada no CMS, a sessão do servidor e o timer JavaScript são redefinidos. Simples e elegante. Se um usuário permanecer em uma única página por mais de 180 minutos, acho que há algo errado com a página, em primeiro lugar.

Charles Robertson
fonte
1
Sim, é por isso que só faço isso depois de me livrar das sessões do lado do servidor e carregar tudo, desde arquivos html.
Dan Parker
4

JavaScript puro com tempo de redefinição e ligações adequadamente configurados via 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
fonte
4

(Parcialmente inspirado na boa lógica central de Equiman, anteriormente neste tópico.)

sessionExpiration.js


sessionExpiration.js é leve, mas eficaz e personalizável. Uma vez implementado, use em apenas uma linha:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Afeta todas as guias do navegador, não apenas uma.
  • Escrito em JavaScript puro , sem dependências. Totalmente do lado do cliente.
  • (Se assim o desejar.) Possui faixa de aviso e contagem regressiva relógio de , que são cancelados pela interação do usuário.
  • Simplesmente inclua o sessionExpiration.js e chame a função, com argumentos [1] número de minutos ociosos (em todas as guias) até o logout do usuário, [2] número de minutos ociosos até que o aviso e a contagem regressiva sejam exibidos e [3] URL de logout.
  • Coloque o CSS na sua folha de estilo. Personalize se quiser. (Ou pule e exclua o banner, se você não quiser.)
  • Se você fazer deseja a bandeira de advertência no entanto, em seguida, você deve colocar uma div vazia com ID sessExpirDiv na sua página (a sugestão é colocá-lo no rodapé) .
  • Agora o usuário será desconectado automaticamente se todas as guias estiverem inativas durante o período especificado.
  • Opcional: Você pode fornecer um quarto argumento (URL serverRefresh) para a função, para que um timer de sessão no servidor também seja atualizado quando você interagir com a página.

Este é um exemplo de como fica em ação, se você não alterar o CSS.

demo_image

Fom
fonte
3

Eu escrevi um plugin jQuery simples que fará o que você está procurando.

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

O script escutará o mouse, teclado, toque e outros eventos personalizados inativos (inativos) e acionará eventos globais de "atividade" e "inatividade".

Espero que isto ajude :)

Alexandros Filos Kaparelos
fonte
Existe realmente a necessidade de um atraso, não está disparando um evento personalizado a partir de um manipulador de eventos personalizado o suficiente?
precisa saber é o seguinte
2

Apenas alguns pensamentos, uma avenida ou duas para explorar.

É possível executar uma função a cada 10 segundos e verificar essa variável "counter"? Se isso for possível, você pode passar o mouse sobre a página, não é? Nesse caso, use o evento mouseover para redefinir a variável "counter". Se sua função for chamada e o contador estiver acima do intervalo que você pré-determina, faça sua ação.

Mais uma vez, apenas alguns pensamentos ... Espero que ajude.

Mark Rullo
fonte
2

Eu testei este arquivo de trabalho de código:

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

Aqui está a melhor solução que encontrei: http://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

Aqui está o 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
fonte
2

Você pode usar a solução abaixo mencionada

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

Eu uso essa abordagem, já que você não precisa redefinir constantemente o horário em que um evento é disparado; em vez disso, apenas gravamos o horário, isso gera o ponto inicial ocioso.

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

Provavelmente, você pode detectar inatividade em sua página da web usando os truques de remoção de rato listados, mas isso não informa que o usuário não está em outra página em outra janela ou guia, ou que está no Word ou Photoshop, ou WOW e no momento não está visualizando sua página. Geralmente, eu apenas fazia a pré-busca e confiava nas multitarefas do cliente. Se você realmente precisar dessa funcionalidade, faça algo com um controle activex no Windows, mas é feio na melhor das hipóteses.

Walden Leverich
fonte
1

Aqui está um serviço AngularJS para realizar em 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;
}]);

Lembre-se de que esse verificador inativo será executado em todas as rotas; portanto, ele deve ser inicializado no .run()carregamento do aplicativo angular. Então você pode usar idleChecker.secondsIdledentro de cada rota.

myApp.run(['idleChecker',function(idleChecker){
    idleChecker.init();
}]);
a vapor
fonte
1

Debounce realmente uma ótima idéia! Aqui versão para projetos livres do 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
fonte
1

Tão simples quanto possível, detecte quando o mouse se move apenas:

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

Bem, você pode anexar um evento de clique ou remoção do mouse ao corpo do documento que redefine um timer. Tenha uma função que você chama em intervalos de tempo que verifica se o cronômetro está acima de um tempo especificado (como 1000 milis) e inicia sua pré-carga.

Eric Wendelin
fonte
0

Javascript não tem como saber o uso da CPU. Isso quebraria o javascript da sandbox executado dentro.

Fora isso, conectar os eventos onmouseover e onkeydown da página provavelmente funcionaria.

Você também pode definir o uso de setTimeout no evento onload para agendar uma função a ser chamada após um atraso.

// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);
Powerlord
fonte
3
Eu me pergunto por que tantos votos negativos nesta resposta. Tanto quanto posso ver, ele respondeu à pergunta e é factualmente correto. Apenas não lançou exemplos de código elaborados.
Ifedi Okonkwo
1
Agora é possível chamar uma função javascript quando "houver tempo livre no final de um quadro ou quando o usuário estiver inativo". Developers.google.com/web/updates/2015/08/…
Max
setTimeout 0 é provavelmente mais correta para calcular em avarage quão cheio o buffer está por tomar o tempo entre FILO