JavaScript에서 " idle "시간 을 감지 할 수 있습니까?
내 주요 사용 사례는 아마도 콘텐츠를 미리 가져 오거나 미리로드하는 것입니다.
유휴 시간 : 사용자가 활동하지 않거나 CPU를 사용하지 않는 기간
JavaScript에서 " idle "시간 을 감지 할 수 있습니까?
내 주요 사용 사례는 아마도 콘텐츠를 미리 가져 오거나 미리로드하는 것입니다.
유휴 시간 : 사용자가 활동하지 않거나 CPU를 사용하지 않는 기간
답변:
다음은 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>
setInterval
JavaScript로 평가됩니다.
idleTime++;
대신에idleTime = idleTime + 1;
'mousemove keydown click'
비트 플래그 ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK
) 를 사용하는 것과 같은 문자열을 취하는 모든 함수 는 문자열 연산보다 빠르기 때문에 모든 함수를 변경할 수도 있습니다 . 그러나 정말로 이것을하고 싶습니까?
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)
, 세 번째 인수는 리스너에게 버블 단계 대신 캡처 단계 동안 이벤트를 포착하도록 지시합니다.
document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
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이됩니다.
document.onscroll
스크롤이 스크롤 가능한 자식 안에 있으면 실행되지 않는 동일한 문제가 있습니까?
addEventListener
대신에 사용하는 것입니다 onscroll
.
나는 1 년 전에 이것을하는 작은 라이브러리를 만들었습니다.
https://github.com/shawnmclean/Idle.js
기술:
브라우저에서 사용자 활동을보고하는 작은 자바 스크립트 라이브러리 (어웨이, 유휴, 웹 페이지를 보지 않고, 다른 탭 등) 그것은 jquery와 같은 다른 자바 스크립트 라이브러리와 독립적입니다.
Visual Studio 사용자는 다음과 같은 방법으로 NuGet에서 얻을 수 있습니다. PM> Install-Package Idle.js
다음은 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.
}
})
setInterval
문자열을 전달하지 마십시오 ! 함수를 변수로 지정하십시오!
setInterval()
전역 범위에서 표현식 을 평가하기 위해 문자열을 전달하면 실제로 작동 하지 않으므로 timerIncrement()
.ready 핸들러 함수 안에있는 함수를 찾을 수 없습니다 . 이것이 문자열을에 전달하지 않는 또 다른 이유 setInterval()
입니다. 실제 함수 참조를 전달하면 현재 범위에서 평가되므로이 문제가 발생하지 않습니다.
위의 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)))
내 대답은 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와 즉시 호출되는 함수 표현식 을 사용하여 깨끗하고 독립적 인 방식으로 유휴 시간 초과를 처리합니다.
onclick
할당 이외에도 필요하지 않을 것이기 때문에 할당을 제거 onmousemove
했지만 프로그래밍 방식으로 트리거되는 이러한 이벤트는 계속 재설정 idleCounter
됩니다. 왜 함수를 호출하는 대신 사용자 상호 작용을 시뮬레이트하는지 잘 모르겠지만 어떤 이유로 든 필요한 경우이 답변은 분명히 효과가 없으며 다른 답변은 대부분 그렇지 않습니다. 이 질문에 대해 살펴 보았습니다.
나는 그것이 오래된 질문이라는 것을 알고 있지만 같은 문제가 있었고 꽤 좋은 해결책을 찾았습니다.
jquery.idle을 사용 했으며 다음 작업 만 수행하면됩니다.
$(document).idle({
onIdle: function(){
alert('You did nothing for 5 seconds');
},
idle: 5000
})
JsFiddle 데모를 참조하십시오 .
(정보 만 제공 : 백엔드 이벤트 추적 리드 브라우저로드에 대해서는이 내용을 참조하십시오 )
keepTracking
옵션을으로 설정할 수 있습니다 false
. 다시 설정하려면 다시 초기화하십시오. 다음은 한 번만 발생하는 수정 된 예입니다. jsfiddle.net/f238hchm/12
이전의 모든 답변에는 항상 활성화 된 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);
}
}
$(startTimer)
동일합니다 $(document).ready(startTimer)
당신이 MouseMove 이벤트 키 누르기 이벤트를 연결하기 전에 DOM을 사용할 수 있는지, 보장합니다.
폼 본문에서 마우스 움직임을 감지하고 마지막 움직임 시간으로 전역 변수를 업데이트하여 함께 무언가를 해킹 할 수 있습니다. 그런 다음 마지막 이동 시간을 주기적으로 확인하고 마지막 마우스 이동이 감지 된 후 시간이 충분히 길면 간격 타이머를 실행해야합니다.
유휴 시간 초과시 활동을 감지하고 이벤트를 발생시키는 작은 ES6 클래스를 작성했습니다. 키보드, 마우스 및 터치를 다루고 활성화 및 비활성화 할 수 있으며 매우 마른 API가 있습니다.
const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();
이전 브라우저를 지원하기 위해 Babel을 통해 실행해야 할 수도 있지만 jQuery에 의존 하지 않습니다 .
https://gist.github.com/4547ef5718fd2d31e5cdcafef0208096
피드백을 받으면 npm 패키지로 릴리스 할 수 있습니다.
당신이 목표로하는 경우 지원되는 브라우저 (12 월 2018로 크롬이나 파이어 폭스를) 당신은 실험 할 수 requestIdleCallback 과 포함 requestIdleCallback 심 지원되지 않는 브라우저입니다.
이 코드를 사용해보십시오. 완벽하게 작동합니다.
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";
}
}
<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 라이브러리를 포함하는 것을 잊지 마십시오!
이러한 모든 솔루션의 문제점은 정확하지만 PHP, .NET 또는 Coldfusion 개발자를위한 Application.cfc 파일의 세션 시간 초과 값 집합을 고려할 때 실용적이지 않습니다. 위 솔루션에서 설정 한 시간은 서버 측 세션 시간 초과와 동기화되어야합니다. 이 두 가지가 동기화되지 않으면 사용자를 실망시키고 혼동시키는 문제가 발생할 수 있습니다. 예를 들어, 서버 측 세션 시간 초과는 60 분으로 설정 될 수 있지만 JavaScript 유휴 시간 캡처는 사용자가 단일 페이지에서 소비 할 수있는 총 시간을 늘리기 때문에 안전하다고 생각할 수 있습니다. 사용자는 긴 양식을 작성하는 데 시간을 소비 한 후 제출하려고합니다. 양식 제출이 처리되기 전에 세션 시간이 초과 될 수 있습니다. 사용자에게 180 분을주는 경향이 있습니다. 그런 다음 JavaScript를 사용하여 사용자를 자동으로 로그 아웃하십시오. 기본적으로 위의 코드 중 일부를 사용하여 간단한 타이머를 만들지 만 마우스 이벤트 부분을 캡처하지는 않습니다. 이러한 방식으로 클라이언트 측과 서버 측 시간이 완벽하게 동기화됩니다. UI에 사용자에게 시간을 표시하면 시간이 줄어듦에 따라 혼동이 없습니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다. 감소합니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다. 감소합니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다.
재설정 시간과 바인딩을 통해 올바르게 설정된 순수 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);
});
}());
(이 스레드의 앞부분에서 Equiman의 훌륭한 핵심 논리에 부분적으로 영향을 받았습니다.)
sessionExpiration.js 는 가볍지 만 효과적이고 사용자 정의 할 수 있습니다. 일단 구현되면 한 행만 사용하십시오.
sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
이것은 CSS를 변경하지 않으면 실제로 작동하는 모습의 예입니다.
나는 당신이 찾고있는 것을 할 간단한 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]
});
이 스크립트는 마우스, 키보드, 터치 및 기타 사용자 정의 이벤트 비 활동 (유휴)을 청취하고 글로벌 "활동"및 "비 활동"이벤트를 발생시킵니다.
도움이 되었기를 바랍니다 :)
이 코드 작업 파일을 테스트했습니다.
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);
});
내가 찾은 최고의 솔루션은 다음과 같습니다. 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)
아래 언급 된 솔루션을 사용할 수 있습니다
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);
}
이벤트가 발생할 때 지속적으로 시간을 재설정 할 필요가 없기 때문에이 접근법을 사용합니다. 대신 시간을 기록하면 유휴 시작점이 생성됩니다.
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);
},
다음은 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();
}]);
실제로 좋은 아이디어를 포기하십시오! 다음은 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 )
}
가능한 한 간단하게 마우스가 움직일 때만 감지하십시오.
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');
}
자바 스크립트는 CPU 사용량을 알려주는 방법이 없습니다. 이것은 샌드 박스 자바 스크립트가 내부에서 실행되는 것을 깨뜨릴 것입니다.
그 외에는 페이지의 onmouseover 및 onkeydown 이벤트를 연결하는 것이 효과적 일 것입니다.
onload 이벤트에서 setTimeout 사용을 설정하여 지연 후 함수가 호출되도록 예약 할 수도 있습니다.
// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);