JavaScriptで「アイドル」時間を検出することは可能ですか?
私の主な使用例は、コンテンツをプリフェッチまたはプリロードすることでしょう。
アイドル時間:ユーザーが活動していない期間、またはCPUを使用していない期間
JavaScriptで「アイドル」時間を検出することは可能ですか?
私の主な使用例は、コンテンツをプリフェッチまたはプリロードすることでしょう。
アイドル時間:ユーザーが活動していない期間、またはCPUを使用していない期間
回答:
以下は、movemoveおよび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
応じて。ここでは、それらの違いを確認できます。JavaScriptのウィンドウ、画面、ドキュメントの違いは何ですか?
@ frank-conijnと@daxchenで更新されたコードは改善されました:window.onscroll
スクロールイベントがバブルしないため、スクロールがスクロール可能な要素内にある場合は起動しません。window.addEventListener('scroll', resetTimer, true)
、3番目の引数は、バブルフェーズではなくキャプチャフェーズ中にイベントをキャッチするようリスナーに指示します。
document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
エクイマンの答えを改善する:
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使用率をゼロにするため、間接的にゼロCPU使用率をキャッチします。
window.onscroll
スクロールイベントがバブルしないため、スクロールがスクロール可能な要素内にある場合は発生しないことを指摘したかっただけです。を使用してwindow.addEventListener('scroll', resetTimer, true)
、3番目の引数は、capture
フェーズではなくbubble
フェーズ中にイベントをキャッチするようリスナーに指示します(IE> 8)。この回答を参照してください
document.onscroll
同じ問題はありません。スクロールがスクロール可能な子の内部にある場合は発生しませんか?
addEventListener
代わりに使用することですonscroll
。
私はこれを1年前に行う小さなlibを作成しました:
https://github.com/shawnmclean/Idle.js
説明:
ブラウザーでのユーザーのアクティビティを報告する小さなJavaScriptライブラリ(離れている、アイドル、Webページを見ていない、別のタブでなど)。これは、jqueryなどの他のJavaScriptライブラリから独立しています。
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ハンドラー関数内にある関数を見つけることができないため、これは実際には機能しません。これは、文字列をに渡さないもう1つの理由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)))
私の答えはビジェイの答えに触発されましたが、それが役立つかもしれない人のために私が共有したいと思ったより短く、より一般的な解決策です。
(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デモを参照してください。
以前のすべての回答には、常にアクティブなマウスムーブハンドラがあります。ハンドラーがjQueryの場合、jQueryが実行する追加の処理が追加される可能性があります。特にユーザーがゲーミングマウスを使用している場合は、1秒あたり500ものイベントが発生する可能性があります。
このソリューションでは、すべてのマウスムーブイベントの処理を回避します。これにより、小さなタイミングエラーが発生しますが、必要に応じて調整できます。
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パッケージとしてリリースするかもしれません。
サポートされているブラウザー(2018年12月の時点でChromeまたはFirefox)をターゲットにしている場合は、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ファイルを使用して、セッションタイムアウトの貴重なセットを考慮すると、実用的ではありません。上記のソリューションで設定された時間は、サーバー側のセッションタイムアウトと同期する必要があります。2つが同期しない場合、ユーザーを苛立たせて混乱させるだけの問題が発生する可能性があります。たとえば、サーバー側のセッションタイムアウトは60分に設定されているかもしれませんが、JavaScriptアイドルタイムキャプチャによってユーザーが単一のページに費やすことができる合計時間が増加したため、ユーザーは安全だと信じているかもしれません。ユーザーは長い形式での入力に時間を費やして、それを送信する可能性があります。フォームの送信が処理される前に、セッションタイムアウトが発生する場合があります。ユーザーに180分だけ与える傾向があります。次に、JavaScriptを使用してユーザーを自動的にログアウトします。基本的に、上記のコードの一部を使用して、単純なタイマーを作成しますが、マウスイベントのキャプチャ部分はありません。このようにして、クライアント側とサーバー側の時間が完全に同期します。時間を減らすため、UIでユーザーに時間を表示しても混乱はありません。CMSで新しいページにアクセスするたびに、サーバー側のセッションとJavaScriptタイマーがリセットされます。シンプルでエレガント。ユーザーが1つのページに180分以上滞在した場合、そもそもページに問題があると思います。それが減少するにつれて。CMSで新しいページにアクセスするたびに、サーバー側のセッションとJavaScriptタイマーがリセットされます。シンプルでエレガント。ユーザーが1つのページに180分以上滞在した場合、そもそもページに問題があると思います。それが減少するにつれて。CMSで新しいページにアクセスするたびに、サーバー側のセッションとJavaScriptタイマーがリセットされます。シンプルでエレガント。ユーザーが1つのページに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は軽量でありながら効果的でカスタマイズ可能です。実装したら、1行だけで使用します。
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);
},
おそらく、リストにあるマウスムーブトリックを使用してWebページの非アクティブ状態を検出できますが、それでもユーザーが別のウィンドウまたはタブの別のページにいないか、ユーザーがWordまたはPhotoshop、WOWにいることはわかりません。現時点ではあなたのページを見ていません。通常、私はプリフェッチを実行し、クライアントのマルチタスクに依存します。この機能が本当に必要な場合は、Windowsのactivexコントロールで何かをしますが、見苦しいだけです。
これは、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');
}
タイマーをリセットするクリックまたはマウスムーブイベントをドキュメントの本文に添付できます。タイマーが指定された時間(1000ミリ秒など)を超えているかどうかをチェックし、プリロードを開始する、一定の間隔で呼び出す関数を用意します。
JavaScriptには、CPU使用率を伝える方法がありません。これにより、サンドボックスのjavascriptが内部で実行されます。
それ以外は、ページのonmouseoverイベントとonkeydownイベントをフックすることでおそらく機能します。
onloadイベントでsetTimeoutを設定して、遅延後に呼び出される関数をスケジュールすることもできます。
// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);