JavaScript에서 유휴 시간을 우아하게 감지하는 방법은 무엇입니까?


478

JavaScript에서 " idle "시간 을 감지 할 수 있습니까?
내 주요 사용 사례는 아마도 콘텐츠를 미리 가져 오거나 미리로드하는 것입니다.

유휴 시간 : 사용자가 활동하지 않거나 CPU를 사용하지 않는 기간


7
유휴 시간을 어떻게 정의합니까?
Itay Moav-말리 모프 카


74
여기 답변의 거의 50 %가 순수 자바 스크립트를위한 간단한 작업에 jQuery를 사용했습니다. 특히 OP가 자바 스크립트를 원했던 것처럼 까다로울 수 없습니다. 딸기 아이스크림을 요청하지만 대신 반 분리 식 헛간을 얻으십시오.
TheCarver

4
thats 당신을위한 StackOverflow
robertmain

5
@TheCarver-아주 간단한 것을 위해 jQuery 라이브러리를 설치해야한다는 것은 실제로 어리석은 일이며 렌더링 시간을 연장하고 에너지 사용량을 증가시킵니다. 사람들은 조금 더 아래로 스크롤해야합니다. 바닐라 자바 ​​스크립트에는 거의 복사하여 붙여 넣기 솔루션이 있습니다.
Frank Conijn

답변:


437

다음은 mousemove 및 keypress 이벤트를 처리하는 JQuery를 사용하는 간단한 스크립트입니다. 시간이 만료되면 페이지가 새로 고침됩니다.

<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
$ (document) .ready (function () 본문 다음에 세미콜론이 누락되었습니다. 또한 setInterval을 호출하면 함수 이름을 따옴표로 묶을 수 없으며 그 뒤에 괄호가 필요하지 않습니다. 그냥 : setInterval (timerIncrement, 60000)
Jesse Roper

9
@Jesse : 여러분의 제안은 모두 훌륭합니다. 이것이 코드의 방식입니다. 그러나 나는이 변경 사항이 없어도 코드가 완벽하게 작동한다는 것을 지적하고 싶었습니다. 표현식 문 끝에있는 세미콜론은 선택 사항이며 실제로 문자열을에 전달하면 setIntervalJavaScript로 평가됩니다.
Felix Kling

6
당신은 간단하게 사용할 수있는 idleTime++;대신에idleTime = idleTime + 1;
마이크 원인이되는 사람

7
이것은 사용자 시스템에서 무겁지 않습니까? 무거운 PC가 아닌 상당히 오래된 브라우저를 가진 사용자가 반나절 동안 자바 스크립트 응용 프로그램에서 작업하고 있으며 사용자가 마우스를 움직일 때마다 이러한 기능을 처리한다고 가정 해 보겠습니다. t는 사용자의 경험에 영향을 미칩니다.
Sander

5
@PietBinnenbocht 또한 이와 같은 것들을 최적화하기 시작하면, 'mousemove keydown click'비트 플래그 ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK) 를 사용하는 것과 같은 문자열을 취하는 모든 함수 는 문자열 연산보다 빠르기 때문에 모든 함수를 변경할 수도 있습니다 . 그러나 정말로 이것을하고 싶습니까?
Killah

361

jQuery를 사용하지 않고 바닐라 JavaScript 만 :

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

필요한 곳에서 함수를 초기화하십시오 (예 : onPageLoad).

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

필요한 경우 더 많은 DOM 이벤트를 추가 할 수 있습니다. 가장 많이 사용되는 것은 다음과 같습니다.

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

또는 배열을 사용하여 원하는 이벤트를 등록하십시오

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

DOM 이벤트 목록 : http://www.w3schools.com/jsref/dom_obj_event.asp

사용 window또는 document필요에 따라 사용하십시오. 여기서 당신은 그들 사이의 차이를 볼 수 있습니다 자바 스크립트에서 창, 화면 및 문서의 차이점은 무엇입니까?

@ frank-conijn 및 @daxchen으로 업데이트 된 코드 개선 : window.onscroll스크롤 이벤트가 버블 링되지 않기 때문에 스크롤이 스크롤 가능한 요소 안에 있으면 실행되지 않습니다. window.addEventListener('scroll', resetTimer, true), 세 번째 인수는 리스너에게 버블 단계 대신 캡처 단계 동안 이벤트를 포착하도록 지시합니다.


58
나는 일반 자바 스크립트 접근 방식이 훨씬 좋습니다.
Manatax

4
타이머를 재설정하는 것은 타이머 자체가 (고정밀) 카운터가 될 수있을 때 다른 일의 정수 카운트를 유지하기 위해 타임 아웃을하는 것보다 직접적이고 직관적이며 정확한 접근 방식입니다.
Josh Sutterfield

2
@mpsbhat는 console.log를 추가하거나 작동하는지 확인하십시오. 또는 다음 이벤트를 등록하십시오.document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
equiman

2
그래 ... 일하고있어 jsfiddle.net/mpsbhat/6b6mja5t/1 . 감사합니다 @equiman
mpsbhat

6
var notidle 플래그를 사용하는 것이 훨씬 낫습니다. 이벤트에서만 플래그를 true로 설정하십시오. 그런 다음 resetTimer 함수 테스트에서 notidle 플래그가 true인지, 타이머가 재설정 된 경우 또는 로그 아웃을 호출합니다. 이렇게하면 타이머를 지속적으로 재설정하는 복잡한 오버 헤드가 제거됩니다.
MartinWebb

75

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

.
그렇다 활동 감지에 관한 개선 및의 변화로 documentwindow,이 스크립트는 실제로하여 유휴 아닌 것보다도,이 함수를 호출합니다.

CPU 사용량을 직접 포착하지는 않지만 기능을 실행하면 CPU 사용량이 발생하므로 불가능합니다. 또한 사용자 비 활동으로 인해 CPU 사용량이 0이되므로 간접적으로 CPU 사용량이 0이됩니다.


3
window.onscroll스크롤 이벤트가 버블 링되지 않기 때문에 스크롤이 스크롤 가능한 요소 안에 있으면 실행되지 않는 것을 지적하고 싶었습니다 . 사용 window.addEventListener('scroll', resetTimer, true)세 번째 인수는 동안 캐치 이벤트에 대한 리스너를 알려줍니다, capture대신 상 bubble상 (IE> 8), 이 답변을 참조
DaxChen

@DaxChen- document.onscroll스크롤이 스크롤 가능한 자식 안에 있으면 실행되지 않는 동일한 문제가 있습니까?
Frank Conijn

2
예, 내가 말한 요점은 addEventListener대신에 사용하는 것입니다 onscroll.
DaxChen 1

@DaxChen-좋아, 나는 당신이 그 문제를 해결하기 위해 그 의미를 가지고 있는지 궁금해하고 있었지만 지금은 분명하다. 그에 따라 답변을 편집했습니다. 의견 주셔서 감사합니다.
Frank Conijn

이 중요한 정보로 답변을 업데이트하여 다른 사본을 열람하고 실수를 붙여 넣을 것입니다. 감사합니다 @DaxChen와 Frank
equiman

33

나는 1 년 전에 이것을하는 작은 라이브러리를 만들었습니다.

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

기술:

브라우저에서 사용자 활동을보고하는 작은 자바 스크립트 라이브러리 (어웨이, 유휴, 웹 페이지를 보지 않고, 다른 탭 등) 그것은 jquery와 같은 다른 자바 스크립트 라이브러리와 독립적입니다.

Visual Studio 사용자는 다음과 같은 방법으로 NuGet에서 얻을 수 있습니다. PM> Install-Package Idle.js


32

다음은 tvanfosson의 아이디어에 대한 대략적인 jQuery 구현입니다.

$(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
이 솔루션은 키보드 이벤트를 고려하지 않습니다.
Daniel Silveira

7
setInterval문자열을 전달하지 마십시오 ! 함수를 변수로 지정하십시오!
Eric

1
setInterval()전역 범위에서 표현식 을 평가하기 위해 문자열을 전달하면 실제로 작동 하지 않으므로 timerIncrement().ready 핸들러 함수 안에있는 함수를 찾을 수 없습니다 . 이것이 문자열을에 전달하지 않는 또 다른 이유 setInterval()입니다. 실제 함수 참조를 전달하면 현재 범위에서 평가되므로이 문제가 발생하지 않습니다.
jfriend00

고맙게도 문자열을 setInterval에 전달할 필요가 없다는 것을 알지 못했습니다. 내 답변을 업데이트했습니다.
피터 J

24

위의 Iconic의 솔루션과 유사합니다 (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

당신은 더 우아하게 그것을 할 수 밑줄JQuery와 -

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

16

내 대답은 vijay의 답변에서 영감을 얻었 지만 더 짧고 일반적인 솔루션으로 도움이 될 수있는 사람과 공유 할 것이라고 생각했습니다.

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

현재 상태이므로이 코드는 3 분 동안 마우스를 움직이거나 키를 누르지 않으면 즉시 실행되고 현재 페이지를 다시로드합니다.

이는 일반 바닐라 JavaScript와 즉시 호출되는 함수 표현식 을 사용하여 깨끗하고 독립적 인 방식으로 유휴 시간 초과를 처리합니다.


document.onclick은 자동화로 쓴 .trigger ( 'click')를 사용하는 자바 스크립트 함수를 고려합니다. 실제로 사용자 상호 작용은 아니지만이 경우 idleCounter를 재설정합니다.
Carmela

@Carmela : 왜 이걸보고 있는지 잘 모르겠습니다. 나는 그것을 놓쳤다. 고맙게도, onclick할당 이외에도 필요하지 않을 것이기 때문에 할당을 제거 onmousemove했지만 프로그래밍 방식으로 트리거되는 이러한 이벤트는 계속 재설정 idleCounter됩니다. 왜 함수를 호출하는 대신 사용자 상호 작용을 시뮬레이트하는지 잘 모르겠지만 어떤 이유로 든 필요한 경우이 답변은 분명히 효과가 없으며 다른 답변은 대부분 그렇지 않습니다. 이 질문에 대해 살펴 보았습니다.
johnnyRose

15

나는 그것이 오래된 질문이라는 것을 알고 있지만 같은 문제가 있었고 꽤 좋은 해결책을 찾았습니다.

jquery.idle을 사용 했으며 다음 작업 만 수행하면됩니다.

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

JsFiddle 데모를 참조하십시오 .

(정보 만 제공 : 백엔드 이벤트 추적 리드 브라우저로드에 대해서는이 내용을 참조하십시오 )


이 기능을 어떻게 중지시킬 수 있습니까? 그들은 유휴 상태 인 이벤트를 언급했습니다. 다음 페이지로 이동하면 (ajax 기반 HTML 페이지 조각 만 업데이트 됨) 유휴 기능이 중지되고 싶습니다. 이것을 달성하는 방법을 알고 있습니까?
Mubasher

다음 은 말한다 : "대기 : 정지"중지 및 제거 사용자 추적합니다
DDan

이미 읽었지만 이것을 사용하는 방법을 알 수 없었습니다. 도와 주시겠습니까?
Mubasher

한 번만 실행하려면 keepTracking옵션을으로 설정할 수 있습니다 false. 다시 설정하려면 다시 초기화하십시오. 다음은 한 번만 발생하는 수정 된 예입니다. jsfiddle.net/f238hchm/12
DDan

아니요, 한 번만 실행하지 마십시오. keepTracking은 사실이어야하지만 다른 페이지로 이동하면이를 중지하고 싶습니다
Mubasher

15

이전의 모든 답변에는 항상 활성화 된 mousemove 핸들러가 있습니다. 핸들러가 jQuery 인 경우 jQuery가 수행하는 추가 처리가 추가 될 수 있습니다. 특히 사용자가 게임용 마우스를 사용하는 경우 초당 500 개의 이벤트가 발생할 수 있습니다.

이 솔루션은 모든 mousemove 이벤트를 처리하지 않습니다. 이로 인해 작은 타이밍 오류가 발생하지만 필요에 따라 조정할 수 있습니다.

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
페이지에 배치 된 경우 자동으로 작동합니까, 아니면 $ (document) .ready () 래퍼 안에 있어야합니까? 감사합니다! 또한 타이머가 만료 될 때 작업을 수행하는 부분은 어디에 있습니까?
Oranges13

1
문서가 준비되기 전에도 언제든지 전화 할 수 있습니다. 타이머가 만료되면 호출되는 함수 '콜백'을 전달합니다.
Sarsaparilla

1
$(startTimer)동일합니다 $(document).ready(startTimer)당신이 MouseMove 이벤트 키 누르기 이벤트를 연결하기 전에 DOM을 사용할 수 있는지, 보장합니다.
Sarsaparilla

1
+1 이것이 내가하는 일-mousemove 핸들러는 부진 및 배터리 수명 단축에 기여하므로, 약간의 타이밍 오류가 발생할 수 있으면 주기적으로 켜는 것이 좋습니다. 일반적으로 자동 세션 만료 경고 (예 : "아직 있습니까?")에 유휴 시간 감지를 사용하므로 사용자가 "유휴"상태가되기까지 몇 분이 걸리는 경향이 있습니다.이 경우 작은 타이밍 오류는 전혀 관련이 없습니다.
염소

1
화살표 키는 "keypress"이벤트에 의해 감지되지 않으므로 "keypress"보다 "keydown"을 사용하는 것이 좋습니다. 따라서 사용자가 화살표 키를 사용하여 페이지를 탐색하는 경우 어쨌든 유휴 상태가됩니다.
aFerrer

13

폼 본문에서 마우스 움직임을 감지하고 마지막 움직임 시간으로 전역 변수를 업데이트하여 함께 무언가를 해킹 할 수 있습니다. 그런 다음 마지막 이동 시간을 주기적으로 확인하고 마지막 마우스 이동이 감지 된 후 시간이 충분히 길면 간격 타이머를 실행해야합니다.


스크립트는 모든 사용자 입력이 아니라 페이지 본문의 움직임 만 감지 할 수 있습니다. 자바 스크립트에서 CPU 또는 프로세스 정보를 얻는 방법이 없다고 생각합니다.
Dave Swersky

1
jQuery에서 아이디어를 구현할 자유를 얻었습니다.
Peter J

9

유휴 시간 초과시 활동을 감지하고 이벤트를 발생시키는 작은 ES6 클래스를 작성했습니다. 키보드, 마우스 및 터치를 다루고 활성화 및 비활성화 할 수 있으며 매우 마른 API가 있습니다.

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

이전 브라우저를 지원하기 위해 Babel을 통해 실행해야 할 수도 있지만 jQuery에 의존 하지 않습니다 .

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

피드백을 받으면 npm 패키지로 릴리스 할 수 있습니다.


8

당신이 목표로하는 경우 지원되는 브라우저 (12 월 2018로 크롬이나 파이어 폭스를) 당신은 실험 할 수 requestIdleCallback 과 포함 requestIdleCallback 심 지원되지 않는 브라우저입니다.


그리고 다른 브라우저를 내버려 두시겠습니까?
Frank Conijn

심은 모든 브라우저를 다룹니다. 그리고 이것이 유일한 대답이었습니다! 다른 느린 답변은 마우스에 관한 것입니다. 인터랙티비티 또는 CPU는 단지 예로서 언급되었습니다. 마우스 솔루션으로 CPU 유휴를 감지하는 방법?

6

이 코드를 사용해보십시오. 완벽하게 작동합니다.

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

+ 1 바닐라 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> 

위의 답변에서 복사하고 수정했지만이 jquery 코드는 완벽한 코드라고 생각합니다! 파일에 jquery 라이브러리를 포함하는 것을 잊지 마십시오!


4

이러한 모든 솔루션의 문제점은 정확하지만 PHP, .NET 또는 Coldfusion 개발자를위한 Application.cfc 파일의 세션 시간 초과 값 집합을 고려할 때 실용적이지 않습니다. 위 솔루션에서 설정 한 시간은 서버 측 세션 시간 초과와 동기화되어야합니다. 이 두 가지가 동기화되지 않으면 사용자를 실망시키고 혼동시키는 문제가 발생할 수 있습니다. 예를 들어, 서버 측 세션 시간 초과는 60 분으로 설정 될 수 있지만 JavaScript 유휴 시간 캡처는 사용자가 단일 페이지에서 소비 할 수있는 총 시간을 늘리기 때문에 안전하다고 생각할 수 있습니다. 사용자는 긴 양식을 작성하는 데 시간을 소비 한 후 제출하려고합니다. 양식 제출이 처리되기 전에 세션 시간이 초과 될 수 있습니다. 사용자에게 180 분을주는 경향이 있습니다. 그런 다음 JavaScript를 사용하여 사용자를 자동으로 로그 아웃하십시오. 기본적으로 위의 코드 중 일부를 사용하여 간단한 타이머를 만들지 만 마우스 이벤트 부분을 캡처하지는 않습니다. 이러한 방식으로 클라이언트 측과 서버 측 시간이 완벽하게 동기화됩니다. UI에 사용자에게 시간을 표시하면 시간이 줄어듦에 따라 혼동이 없습니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다. 감소합니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다. 감소합니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다.


1
그렇기 때문에 서버 측 세션을 제거하고 html 파일에서 모든 것을로드 한 후에 만이 작업을 수행하는 이유입니다.
Dan Parker

4

재설정 시간과 바인딩을 통해 올바르게 설정된 순수 JavaScript 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

(이 스레드의 앞부분에서 Equiman의 훌륭한 핵심 논리에 부분적으로 영향을 받았습니다.)

sessionExpiration.js


sessionExpiration.js 는 가볍지 만 효과적이고 사용자 정의 할 수 있습니다. 일단 구현되면 한 행만 사용하십시오.

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • 하나의 이 아니라 브라우저의 모든 탭영향을줍니다 .
  • 의존성이없는 순수한 JavaScript로 작성되었습니다 . 완전 고객 측.
  • (그래서 원하는 경우.) 했습니다 배너 경고카운트 다운이 사용자 상호 작용에 의해 취소 된 시계.
  • 간단히 포함 sessionExpiration.js을 하고, 인수, 함수를 호출 [1] 사용자가 로그 아웃 할 때까지 (모든 탭에 걸쳐) 유휴 시간 (분), [2] 경고 및 카운트까지 유휴 시간 (분)이 표시되고, [3] 로그 아웃 URL.
  • CSS를 스타일 시트에 넣으십시오. 원하는 경우 사용자 정의하십시오. 원하지 않는 경우 배너를 건너 뛰거나 삭제하십시오.
  • 당신이 경우에 할 수 있지만 경고 배너를 원하는, 당신은 ID와 빈 DIV 삽입해야 sessExpirDiv을 페이지에 (제안이 바닥 글에 그것을두고있다) .
  • 지정된 기간 동안 모든 탭이 비활성화 된 경우 사용자가 자동으로 로그 아웃됩니다.
  • 선택 사항 : 페이지와 상호 작용할 때 서버 측 세션 타이머도 새로 고치도록 함수에 네 번째 인수 (URL serverRefresh)를 제공 할 수 있습니다.

이것은 CSS를 변경하지 않으면 실제로 작동하는 모습의 예입니다.

demo_image


3

나는 당신이 찾고있는 것을 할 간단한 jQuery 플러그인을 작성했습니다.

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

이 스크립트는 마우스, 키보드, 터치 및 기타 사용자 정의 이벤트 비 활동 (유휴)을 청취하고 글로벌 "활동"및 "비 활동"이벤트를 발생시킵니다.

도움이 되었기를 바랍니다 :)


실제로 지연이 필요합니까, 사용자 정의 이벤트 핸들러에서 사용자 정의 이벤트를 충분히 트리거하지 않습니까?
Hibou57

2

몇 가지 생각, 길을 탐험하십시오.

10 초마다 함수를 실행하고 "카운터"변수를 검사 할 수 있습니까? 가능하다면 페이지 위에 마우스를 올려 놓을 수 있습니까? 그렇다면 mouseover 이벤트를 사용하여 "counter"변수를 재설정하십시오. 함수가 호출되고 카운터가 미리 결정한 범위를 초과하는 경우 작업을 수행하십시오.

다시 한 번, 몇 가지 생각 만하면 도움이되기를 바랍니다.


2

이 코드 작업 파일을 테스트했습니다.

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

내가 찾은 최고의 솔루션은 다음과 같습니다. http://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

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

아래 언급 된 솔루션을 사용할 수 있습니다

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

이벤트가 발생할 때 지속적으로 시간을 재설정 할 필요가 없기 때문에이 접근법을 사용합니다. 대신 시간을 기록하면 유휴 시작점이 생성됩니다.

           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

나열된 mousemove 트릭을 사용하여 웹 페이지에서 비활성을 감지 할 수는 있지만 사용자가 다른 창이나 탭의 다른 페이지에 있지 않거나 사용자가 Word 또는 Photoshop 또는 WOW 및 현재 귀하의 페이지를보고 있지 않습니다. 일반적으로 프리 페치를 수행하고 클라이언트의 멀티 태스킹에 의존합니다. 이 기능이 실제로 필요한 경우 Windows에서 ActiveX 컨트롤을 사용하여 무언가를 수행하지만 추악합니다.


1

다음은 Angular에서 달성하기위한 AngularJS 서비스입니다.

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

이 유휴 검사기는 모든 경로에 대해 실행되므로 .run()각도 앱을로드 할 때 초기화되어야합니다 . 그런 다음 idleChecker.secondsIdle각 경로 내부에서 사용할 수 있습니다 .

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

1

실제로 좋은 아이디어를 포기하십시오! 다음은 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

가능한 한 간단하게 마우스가 움직일 때만 감지하십시오.

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

클릭 또는 mousemove 이벤트를 문서 본문에 첨부하여 타이머를 재설정 할 수 있습니다. 타이머가 지정된 시간 (예 : 1000 밀리 초)을 초과하는지 확인하는 시간 간격으로 호출하는 기능을 가지고 사전로드를 시작하십시오.


0

자바 스크립트는 CPU 사용량을 알려주는 방법이 없습니다. 이것은 샌드 박스 자바 스크립트가 내부에서 실행되는 것을 깨뜨릴 것입니다.

그 외에는 페이지의 onmouseover 및 onkeydown 이벤트를 연결하는 것이 효과적 일 것입니다.

onload 이벤트에서 setTimeout 사용을 설정하여 지연 후 함수가 호출되도록 예약 할 수도 있습니다.

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

3
이 답변에 왜 그렇게 많은 다운 보트가 있는지 궁금합니다. 내가 볼 수있는 한, 그것은 질문에 대답했으며 실제로 정확합니다. 정교한 코드 예제를 계속 출시하지 않았습니다.
Ifedi Okonkwo

1
이제 "프레임 끝에 자유 시간이 있거나 사용자가 비활성 상태 일 때 Javascript 함수를 호출 할 수 있습니다." developers.google.com/web/updates/2015/08/…
Max

setTimeout 0은 아마도 FILO 사이의 시간을 사용하여 버퍼가 얼마나 가득 찬지를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.