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

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

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.