BedroomLANTilde~A: Alexios' HomepageSearch |
![]() |
||
Detecting ‘Idle’ and ‘Away’ Timeouts in JavascriptA short Javascript program to improve detection of users idling or away from their keyboards, which should in turn improve how online users are detected. The file works with both jQuery and Prototype. It autodetects which is available at load time. Putting an AJAX request in one of the handlers can notify the back-end about the online state of a user. Using it purely on the front-end, periodic AJAX requests can be stopped or run more sparsely, for both user intuitiveness and saving bandwidth. The advantage of this implementation is it uses JavaScript timers that tick once every idle timeout, not every second. User activity doesn't create new timers with every mouse or keyboard event, either. It just updates a timestamp, which is then checked when the timer runs. The timer uses the timestamp to tell if user activity has been detected. This makes the whole process very light on resources. APIThis is very simple. There are two functions, There are three event-like callbacks: ExampleHere's a simple example, using jQuery (the only jQuery-specific thing is the code inside the setIdleTimeout(2000); // 2 seconds setAwayTimeout(4000); // 4 seconds document.onIdle = function() {$('#div_idle').css('opacity', '1');} document.onAway = function() {$('#div_away').css('opacity', '1');} document.onBack = function(isIdle, isAway) { if (isIdle) $('#div_idle').css('opacity', '0.2'); if (isAway) $('#div_away').css('opacity', '0.2'); } You can see this running with exaggerated timeouts (two and four seconds for idle and away respectively). Wait a few seconds and the ‘idle’ and ‘away’ boxes will highlight. Moving the mouse or pressing keys should fade them again. Idle
Away
Source// idle.js (c) Alexios Chouchoulas 2009 // Released under the terms of the GNU Public License version 2.0 (or later). var _API_JQUERY = 1; var _API_PROTOTYPE = 2; var _api; var _idleTimeout = 30000; // 30 seconds var _awayTimeout = 600000; // 10 minutes var _idleNow = false; var _idleTimestamp = null; var _idleTimer = null; var _awayNow = false; var _awayTimestamp = null; var _awayTimer = null; function setIdleTimeout(ms) { _idleTimeout = ms; _idleTimestamp = new Date().getTime() + ms; if (_idleTimer != null) { clearTimeout (_idleTimer); } _idleTimer = setTimeout(_makeIdle, ms + 50); //console.log('idle in ' + ms + ', tid = ' + _idleTimer); } function setAwayTimeout(ms) { _awayTimeout = ms; _awayTimestamp = new Date().getTime() + ms; if (_awayTimer != null) { clearTimeout (_awayTimer); } _awayTimer = setTimeout(_makeAway, ms + 50); //console.log('away in ' + ms); } function _makeIdle() { var t = new Date().getTime(); if (t < _idleTimestamp) { //console.log('Not idle yet. Idle in ' + (_idleTimestamp - t + 50)); _idleTimer = setTimeout(_makeIdle, _idleTimestamp - t + 50); return; } //console.log('** IDLE **'); _idleNow = true; try { if (document.onIdle) document.onIdle(); } catch (err) { } } function _makeAway() { var t = new Date().getTime(); if (t < _awayTimestamp) { //console.log('Not away yet. Away in ' + (_awayTimestamp - t + 50)); _awayTimer = setTimeout(_makeAway, _awayTimestamp - t + 50); return; } //console.log('** AWAY **'); _awayNow = true; try { if (document.onAway) document.onAway(); } catch (err) { } } function _initPrototype() { _api = _API_PROTOTYPE; } function _active(event) { var t = new Date().getTime(); _idleTimestamp = t + _idleTimeout; _awayTimestamp = t + _awayTimeout; //console.log('not idle.'); if (_idleNow) { setIdleTimeout(_idleTimeout); } if (_awayNow) { setAwayTimeout(_awayTimeout); } try { //console.log('** BACK **'); if ((_idleNow || _awayNow) && document.onBack) document.onBack(_idleNow, _awayNow); } catch (err) { } _idleNow = false; _awayNow = false; } function _initJQuery() { _api = _API_JQUERY; var doc = $(document); doc.ready(function(){ doc.mousemove(_active); try { doc.mouseenter(_active); } catch (err) { } try { doc.scroll(_active); } catch (err) { } try { doc.keydown(_active); } catch (err) { } try { doc.click(_active); } catch (err) { } try { doc.dblclick(_active); } catch (err) { } }); } function _initPrototype() { _api = _API_PROTOTYPE; var doc = $(document); Event.observe (window, 'load', function(event) { Event.observe(window, 'click', _active); Event.observe(window, 'mousemove', _active); Event.observe(window, 'mouseenter', _active); Event.observe(window, 'scroll', _active); Event.observe(window, 'keydown', _active); Event.observe(window, 'click', _active); Event.observe(window, 'dblclick', _active); }); } // Detect the API try { if (Prototype) _initPrototype(); } catch (err) { } try { if (jQuery) _initJQuery(); } catch (err) { } // End of file. Tags: |
|
|
|
Recent comments
24 weeks 6 days ago
32 weeks 5 days ago
42 weeks 4 days ago
43 weeks 5 days ago
44 weeks 6 days ago
46 weeks 4 days ago
47 weeks 13 hours ago
48 weeks 3 days ago
1 year 1 week ago
1 year 1 week ago