JavaScript에서 유휴 시간을 우아하게 감지하는 방법은 무엇입니까?
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>
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.onscroll = resetTimer; // scrolling with arrow keys
document.onkeypress = resetTimer;
또는 배열을 사용하여 원하는 이벤트를 등록하십시오
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
필요에 따라 사용하십시오. 여기서 당신은 그들 사이의 차이를 볼 수 있습니다 자바 스크립트에서 창, 화면 및 문서의 차이점은 무엇입니까?
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이됩니다.
나는 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.
}
})
위의 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)))
당신은 더 우아하게 그것을 할 수 밑줄 및 JQuery와 -
$('body').on("click mousemove keyup", _.debounce(function(){
// do preload here
}, 1200000)) // 20 minutes debounce
내 대답은 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와 즉시 호출되는 함수 표현식 을 사용하여 깨끗하고 독립적 인 방식으로 유휴 시간 초과를 처리합니다.
나는 그것이 비교적 오래된 질문이라는 것을 알고 있지만, 같은 문제가 있었고 꽤 좋은 해결책을 찾았습니다.
jquery.idle을 사용 했으며 다음 작업 만 수행하면됩니다.
$(document).idle({
onIdle: function(){
alert('You did nothing for 5 seconds');
},
idle: 5000
})
JsFiddle 데모를 참조하십시오 .
(정보 용 : 백엔드 이벤트 추적 리드 브라우저로드에 대해서는이 내용을 참조하십시오 )
이전의 모든 답변에는 항상 활성화 된 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);
}
}
폼 본문에서 마우스 움직임을 감지하고 마지막 움직임 시간으로 전역 변수를 업데이트하여 함께 무언가를 해킹 할 수 있습니다. 그런 다음 마지막 이동 시간을 주기적으로 확인하고 마지막 마우스 이동이 감지 된 후 시간이 충분히 길면 간격 타이머를 실행해야합니다.
당신이 목표로하는 경우 지원되는 브라우저 (12 월 2018로 크롬이나 파이어 폭스를) 당신은 실험 할 수 requestIdleCallback 과 포함 requestIdleCallback 심 지원되지 않는 브라우저입니다.
<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 라이브러리를 포함하는 것을 잊지 마십시오!
유휴 시간 초과시 활동을 감지하고 이벤트를 발생시키는 작은 ES6 클래스를 작성했습니다. 키보드, 마우스 및 터치를 다루고 활성화 및 비활성화 할 수 있으며 매우 마른 API가 있습니다.
const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();
이전 브라우저를 지원하기 위해 Babel을 통해 실행해야 할 수도 있지만 jQuery에 의존 하지 않습니다 .
https://gist.github.com/4547ef5718fd2d31e5cdcafef0208096
피드백을 받으면 npm 패키지로 릴리스 할 수 있습니다.
이 코드를 사용해보십시오. 완벽하게 작동합니다.
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";
}
}
재설정 시간과 바인딩을 통해 올바르게 설정된 순수 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);
});
}());
나는 당신이 찾고있는 것을 할 간단한 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);
});
이러한 모든 솔루션의 문제점은 올바르지 만 PHP, .NET 또는 Coldfusion 개발자를위한 Application.cfc 파일의 세션 시간 초과 값 집합을 고려할 때 실용적이지 않습니다. 위 솔루션에서 설정 한 시간은 서버 측 세션 시간 초과와 동기화되어야합니다. 이 두 가지가 동기화되지 않으면 사용자를 실망시키고 혼동시키는 문제가 발생할 수 있습니다. 예를 들어, 서버 측 세션 시간 초과는 60 분으로 설정 될 수 있지만 JavaScript 유휴 시간 캡처는 사용자가 단일 페이지에서 소비 할 수있는 총 시간을 늘리기 때문에 안전하다고 생각할 수 있습니다. 사용자는 긴 양식을 작성하는 데 시간을 소비 한 후 제출하려고합니다. 양식 제출이 처리되기 전에 세션 시간이 초과 될 수 있습니다. 사용자에게 180 분을주는 경향이 있습니다. 그런 다음 JavaScript를 사용하여 사용자를 자동으로 로그 아웃하십시오. 기본적으로 위의 코드 중 일부를 사용하여 간단한 타이머를 만들지 만 마우스 이벤트 부분을 캡처하지는 않습니다. 이러한 방식으로 클라이언트 측과 서버 측 시간이 완벽하게 동기화됩니다. UI에 시간을 줄이면 사용자에게 시간을 표시하면 혼란이 없습니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다. 감소합니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다. 감소합니다. CMS에서 새 페이지에 액세스 할 때마다 서버 측 세션 및 JavaScript 타이머가 재설정됩니다. 간단하고 우아합니다. 사용자가 단일 페이지에 180 분 이상 머무르면 우선 페이지에 문제가있는 것 같습니다.
내가 찾은 최고의 솔루션은 다음과 같습니다. 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);
},
(이 스레드의 앞부분에서 Equiman의 우수한 핵심 논리에 부분적으로 영향을 받았습니다.)
sessionExpiration.js
sessionExpiration.js 는 가볍지 만 효과적이고 사용자 정의 할 수 있습니다. 일단 구현되면 한 행만 사용하십시오.
sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
- 하나의 탭 이 아니라 브라우저의 모든 탭 에 영향을줍니다 .
- 의존성이없는 순수한 JavaScript로 작성되었습니다 . 완전 고객 측.
- (그래서 원하는 경우.) 했습니다 배너 경고 및 카운트 다운이 사용자 상호 작용에 의해 취소 된 시계.
- 간단히 포함 sessionExpiration.js을 하고, 인수, 함수를 호출 [1] 사용자가 로그 아웃 할 때까지 (모든 탭에 걸쳐) 유휴 시간 (분), [2] 경고 및 카운트까지 유휴 시간 (분)이 표시되고, [3] 로그 아웃 URL.
- CSS를 스타일 시트에 넣으십시오. 원하는 경우 사용자 정의하십시오. (또는 원하지 않는 배너는 건너 뛰고 삭제하십시오.)
- 당신이 경우에 할 수 있지만 경고 배너를 원하는, 당신은 ID와 빈 DIV 삽입해야 sessExpirDiv을 페이지에 (제안이 바닥 글에 그것을두고있다) .
- 지정된 기간 동안 모든 탭이 비활성화 된 경우 사용자가 자동으로 로그 아웃됩니다.
이것은 CSS를 변경하지 않으면 실제로 작동하는 모습의 예입니다.
몇 가지 생각, 길을 탐험하십시오.
10 초마다 함수를 실행하고 "카운터"변수를 검사 할 수 있습니까? 가능하다면 페이지 위에 마우스를 올려 놓을 수 있습니까? 그렇다면 mouseover 이벤트를 사용하여 "counter"변수를 재설정하십시오. 함수가 호출되고 카운터가 미리 결정한 범위를 초과하면 작업을 수행하십시오.
다시 한 번, 몇 가지 생각 만하면 도움이되기를 바랍니다.
나열된 mousemove 트릭을 사용하여 웹 페이지에서 비활성을 감지 할 수 있지만 사용자가 다른 창이나 탭의 다른 페이지에 있지 않거나 사용자가 Word 또는 Photoshop 또는 WOW 및 현재 귀하의 페이지를보고 있지 않습니다. 일반적으로 프리 페치를 수행하고 클라이언트의 멀티 태스킹에 의존합니다. 이 기능이 실제로 필요한 경우 Windows에서 ActiveX 컨트롤을 사용하여 무언가를 수행하지만 추악합니다.
같은 문제를 가진 다른 사용자의 경우. 여기 내가 방금 만든 기능이 있습니다.
사용자가 마우스를 움직일 때마다 실행되지 않거나 마우스가 움직일 때마다 타이머가 지워집니다.
<script>
// Timeout in seconds
var timeout = 10; // 10 seconds
// You don't have to change anything below this line, except maybe
// the alert('Welcome back!') :-)
// ----------------------------------------------------------------
var pos = '', prevpos = '', timer = 0, interval = timeout / 5 * 1000;
timeout = timeout * 1000 - interval;
function mouseHasMoved(e){
document.onmousemove = null;
prevpos = pos;
pos = e.pageX + '+' + e.pageY;
if(timer > timeout){
timer = 0;
alert('Welcome back!');
}
}
setInterval(function(){
if(pos == prevpos){
timer += interval;
}else{
timer = 0;
prevpos = pos;
}
document.onmousemove = function(e){
mouseHasMoved(e);
}
}, interval);
</script>
다음은 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();
}]);
가능한 한 간단하게 마우스가 움직일 때만 감지하십시오.
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');
}
클릭 또는 mousemove 이벤트를 문서 본문에 첨부하여 타이머를 재설정 할 수 있습니다. 타이머가 지정된 시간 (예 : 1000 밀리 초)을 초과하는지 확인하는 시간 간격으로 호출하는 기능을 가지고 사전로드를 시작하십시오.
@freddoo 솔루션을 시도했지만 1 분 시간 초과로 작동하지 않았으므로 사용자가 페이지를 마지막으로 클릭했을 때 날짜와 시간을 기록하도록 약간 변경했습니다. 내 timerIncrement
기능에서 현재 시간과 마지막 시간의 차이를 계산합니다. 클릭 한 시간과 값이 시간 초과 값보다 크거나 같으면 리디렉션합니다.
var clickedDate = new Date();
var idleTime = 1;//
function timerIncrement() {
var nowDate = new Date();
var diffMs = (nowDate - clickedDate); //Milliseconds between now & the last time a user clicked somewhere on the page
var diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000); //Convert ms to minutes
if (diffMins >= idleTime) {
//Redirect user to home page etc...
}
}
$(document).ready(function () {
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute
$(this).click(function (e) {
clickedDate = new Date();
});
});
참고 URL : https://stackoverflow.com/questions/667555/how-to-detect-idle-time-in-javascript-elegantly
도와주세요.
'development' 카테고리의 다른 글
jQuery : 아약스 호출 성공 후 데이터 반환 (0) | 2020.02.17 |
---|---|
MySQL에서 열의 데이터 유형을 어떻게 변경합니까? (0) | 2020.02.17 |
프로그래밍 방식으로 머신에서 코어 수 찾기 (0) | 2020.02.17 |
Docker 컨테이너에 셸한 후 파일을 어떻게 편집합니까? (0) | 2020.02.17 |
백업 세트는 기존 이외의 데이터베이스 백업을 보유합니다. (0) | 2020.02.17 |