Использование jQuery Idle Timeout от Eric Hynds, но похоже, что это заброшенный проект.
Это используется в проекте киоска (в инструментах Chrome dev разрешение должно быть 1080px в ширину и 1920px в высоту), и будет загружена версия киоска: http://dev.demo38.com/owu/
Тайм-аут используется, когда пользователь уходит из киоска, таймер запускает предупреждение с обратным отсчетом. Этот обратный отсчет может быть сброшен для продолжения просмотра, или, если позволить обратному отсчету, перенаправляет киоск обратно на главный экран.
Раньше это работало нормально, однако начинало появляться следующее сообщение об ошибке консоли:
Uncaught TypeError: Cannot read property 'nodeType' of undefined
at Function.n.acceptData [as accepts] (jquery.js:3531)
at K.key (jquery.js:3556)
at K.set (jquery.js:3593)
at K.access (jquery.js:3652)
at Function.data (jquery.js:3761)
at Object.init (jquery.idletimeout.js?ver=1.2:32)
at Function.$.idleTimeout (jquery.idletimeout.js?ver=1.2:139)
at (index):825
Есть сведения о том, где возникает эта ошибка / как ее устранить?
Первый сценарий написан Полом Айришем с использованием его IdleTimer (jquery.idletimer.js)
(function($){
$.idleTimer = function f(newTimeout){
//$.idleTimer.tId = -1 //timeout ID
var idle = false, //indicates if the user is idle
enabled = true, //indicates if the idle timer is enabled
timeout = 500, //the amount of time (ms) before the user is considered idle
events = 'mousemove keydown DOMMouseScroll mousewheel mousedown', // activity is one of these events
//f.olddate = undefined, // olddate used for getElapsedTime. stored on the function
/* (intentionally not documented)
* Toggles the idle state and fires an appropriate event.
* @return {void}
*/
toggleIdleState = function(){
//toggle the state
idle = !idle;
// reset timeout counter
f.olddate = +new Date;
//fire appropriate event
$(document).trigger( $.data(document,'idleTimer', idle ? "idle" : "active" ) + '.idleTimer');
},
/**
* Stops the idle timer. This removes appropriate event handlers
* and cancels any pending timeouts.
* @return {void}
* @method stop
* @static
*/
stop = function(){
//set to disabled
enabled = false;
//clear any pending timeouts
clearTimeout($.idleTimer.tId);
//detach the event handlers
$(document).unbind('.idleTimer');
},
/* (intentionally not documented)
* Handles a user event indicating that the user isn't idle.
* @param {Event} event A DOM2-normalized event object.
* @return {void}
*/
handleUserEvent = function(){
//clear any existing timeout
clearTimeout($.idleTimer.tId);
//if the idle timer is enabled
if (enabled){
//if it's idle, that means the user is no longer idle
if (idle){
toggleIdleState();
}
//set a new timeout
$.idleTimer.tId = setTimeout(toggleIdleState, timeout);
}
};
/**
* Starts the idle timer. This adds appropriate event handlers
* and starts the first timeout.
* @param {int} newTimeout (Optional) A new value for the timeout period in ms.
* @return {void}
* @method $.idleTimer
* @static
*/
f.olddate = f.olddate || +new Date;
//assign a new timeout if necessary
if (typeof newTimeout == "number"){
timeout = newTimeout;
} else if (newTimeout === 'destroy') {
stop();
return this;
} else if (newTimeout === 'getElapsedTime'){
return (+new Date) - f.olddate;
}
//assign appropriate event handlers
$(document).bind($.trim((events+' ').split(' ').join('.idleTimer ')),handleUserEvent);
//set a timeout to toggle state
$.idleTimer.tId = setTimeout(toggleIdleState, timeout);
// assume the user is active for the first x seconds.
$.data(document,'idleTimer',"active");
}; // end of $.idleTimer()
})(jQuery);
Второй скрипт - это тайм-аут / перенаправление (jquery.idletimeout.js)
(function($, win){
var idleTimeout = {
init: function( element, resume, options ){
var self = this, elem;
this.warning = elem = $(element);
this.resume = $(resume);
this.options = options;
this.countdownOpen = false;
this.failedRequests = options.failedRequests;
this._startTimer();
this.title = document.title;
// expose obj to data cache so peeps can call internal methods
$.data( elem[0], 'idletimeout', this );
// start the idle timer
$.idleTimer(options.idleAfter * 1000);
// once the user becomes idle
$(document).bind("idle.idleTimer", function(){
// if the user is idle and a countdown isn't already running
if( $.data(document, 'idleTimer') === 'idle' && !self.countdownOpen ){
self._stopTimer();
self.countdownOpen = true;
self._idle();
}
});
// bind continue link
this.resume.bind("click", function(e){
e.preventDefault();
win.clearInterval(self.countdown); // stop the countdown
self.countdownOpen = false; // stop countdown
self._startTimer(); // start up the timer again
self._keepAlive( false ); // ping server
options.onResume.call( self.warning ); // call the resume callback
});
},
_idle: function(){
var self = this,
options = this.options,
warning = this.warning[0],
counter = options.warningLength;
// fire the onIdle function
options.onIdle.call(warning);
// set inital value in the countdown placeholder
options.onCountdown.call(warning, counter);
// create a timer that runs every second
this.countdown = win.setInterval(function(){
if(--counter === 0){
window.clearInterval(self.countdown);
options.onTimeout.call(warning);
} else {
options.onCountdown.call(warning, counter);
document.title = options.titleMessage.replace('%s', counter) + self.title;
}
}, 1000);
},
_startTimer: function(){
var self = this;
this.timer = win.setTimeout(function(){
self._keepAlive();
}, this.options.pollingInterval * 1000);
},
_stopTimer: function(){
// reset the failed requests counter
this.failedRequests = this.options.failedRequests;
win.clearTimeout(this.timer);
},
_keepAlive: function( recurse ){
var self = this,
options = this.options;
//Reset the title to what it was.
document.title = self.title;
// assume a startTimer/keepAlive loop unless told otherwise
if( typeof recurse === "undefined" ){
recurse = true;
}
// if too many requests failed, abort
if( !this.failedRequests ){
this._stopTimer();
options.onAbort.call( this.warning[0] );
return;
}
$.ajax({
timeout: options.AJAXTimeout,
url: options.keepAliveURL,
error: function(){
self.failedRequests--;
},
success: function(response){
if($.trim(response) !== options.serverResponseEquals){
self.failedRequests--;
}
},
complete: function(){
if( recurse ){
self._startTimer();
}
}
});
}
};
// expose
$.idleTimeout = function(element, resume, options){
idleTimeout.init( element, resume, $.extend($.idleTimeout.options, options) );
return this;
};
// options
$.idleTimeout.options = {
// number of seconds after user is idle to show the warning
warningLength: 30,
// url to call to keep the session alive while the user is active
keepAliveURL: "",
// the response from keepAliveURL must equal this text:
serverResponseEquals: "OK",
// user is considered idle after this many seconds. 10 minutes default
idleAfter: 600,
// a polling request will be sent to the server every X seconds
pollingInterval: 60,
// number of failed polling requests until we abort this script
failedRequests: 5,
// the $.ajax timeout in MILLISECONDS!
AJAXTimeout: 250,
// %s will be replaced by the counter value
titleMessage: 'Warning: %s seconds until log out | ',
/*
Callbacks
"this" refers to the element found by the first selector passed to $.idleTimeout.
*/
// callback to fire when the session times out
onTimeout: $.noop,
// fires when the user becomes idle
onIdle: $.noop,
// fires during each second of warningLength
onCountdown: $.noop,
// fires when the user resumes the session
onResume: $.noop,
// callback to fire when the script is aborted due to too many failed requests
onAbort: $.noop
};
})(jQuery, window);
И вот сценарий, который вызывает:
$.idleTimeout('#idletimeout', '#idletimeout a', {
idleAfter: 180,
pollingInterval: 5,
keepAliveURL: 'http://dev.demo38.com/owu/wp-content/themes/owu/keepalive.php',
serverResponseEquals: 'OK',
onTimeout: function(){
$(this).slideUp();
// window.location = home_url;
window.location = "http://dev.demo38.com/owu/";
},
onIdle: function(){
$(this).slideDown(); // show the warning bar
},
onCountdown: function( counter ){
$(this).find("span").html( counter ); // update the counter
},
onResume: function(){
$(this).slideUp(); // hide the warning bar
}
});