Last active
December 15, 2015 17:48
-
-
Save jackslocum/5298557 to your computer and use it in GitHub Desktop.
Tooltip timer class for Ext JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Jack Slocum | |
* MIT License | |
* | |
* @class xui.util.DelayTimer | |
* Provides a convenient method for timing delayed show and hide of tooltips, callouts, etc | |
* @constructor | |
* @param {Object} config (optional) | |
*/ | |
Ext.define('xui.util.DelayTimer', { | |
constructor: function(o){ | |
Ext.apply(this, o); | |
this.timerFn = Ext.Function.bind(this.callFn, this); | |
this.timeoutFn = Ext.Function.bind(this.handleTimeout, this); | |
}, | |
/** | |
* @cfg {Function} fn | |
* The function to call | |
*/ | |
fn: undefined, | |
/** | |
* @cfg {Object} scope | |
* The "this" object for fn | |
*/ | |
scope: undefined, | |
/** | |
* @cfg {Array} args | |
* The arguments to pass to fn when called. Generally these are passed to "start". | |
*/ | |
args: undefined, | |
/** | |
* @cfg {Number} timeout | |
* The amount of time for the "active" state to timeout | |
*/ | |
timeout: 1000, | |
/** | |
* @cfg {Number} 500 | |
* The amount of time to delay/buffer the execution of fn | |
*/ | |
delay: 500, | |
/** | |
* @cfg {Function} onEnd | |
* Function to be called any time end() occurs. Passed this DelayTimer. | |
*/ | |
onEnd: undefined, | |
/** | |
* @cfg {Function} onTimeout | |
* Function to be called any time a timeout occurs (See isActive). Passed this DelayTimer. | |
*/ | |
onTimeout: undefined, | |
/** | |
* @cfg {Function} test | |
* Function to be called right before starting the timer in start(). It is called with the same arguments that | |
* start() was called with. Return false to cancel the start(). | |
* This is particularly useful for filtering calls to start() made by events bound with listen(). | |
*/ | |
test: undefined, | |
// private | |
active: false, | |
/** | |
* Returns true if this DelayTimer is "active" (fn will execute immediately when start is called), false if delayed | |
* @returns {boolean} | |
*/ | |
isActive: function(){ | |
return this.active; | |
}, | |
/** | |
* Start the delay or will call immediately with passed arguments if "active" | |
* @param {Mixed} arg1 (optional) | |
* @param {Mixed} arg2 (optional) | |
* @param {mixed} etc (optional) | |
*/ | |
start: function(){ | |
this.cancel(); | |
var args = Array.prototype.slice.call(arguments, 0); | |
if(args.length > 0){ | |
this.args = args; | |
} | |
if(this.test && this.test.apply(this.scope, args) === false){ | |
return; | |
} | |
if(this.active){ | |
this.callFn(); | |
}else{ | |
this.callId = setTimeout(this.timerFn, this.delay); | |
} | |
}, | |
/** | |
* Cancels the timer from the last call to start() | |
*/ | |
cancel: function(){ | |
if(this.callId){ | |
clearTimeout(this.callId); | |
delete this.callId; | |
} | |
}, | |
/** | |
* Starts the timeout duration. (For example, after a tooltip is hidden.) | |
*/ | |
end: function(){ | |
this.cancelTimeout(); | |
this.timeoutId = setTimeout(this.timeoutFn, this.timeout); | |
if(this.onEnd){ | |
this.onEnd.call(this.scope || this, this); | |
} | |
}, | |
/** | |
* Attaches listeners to "obj" to manage calling start / cancel based on events (e.g. mouseenter / mouseleave) | |
* @param {Object} obj This object to listen on | |
* @param {String} startEvent | |
* @param {String} cancelEvent | |
*/ | |
listen: function(obj, startEvent, cancelEvent){ | |
if(startEvent){ | |
obj.on(startEvent, this.start, this); | |
} | |
if(cancelEvent){ | |
obj.on(cancelEvent, this.cancel, this); | |
} | |
}, | |
/** | |
* @param {Object} obj This object previously passed to listen | |
* @param {String} startEvent | |
* @param {String} cancelEvent | |
*/ | |
unlisten: function(obj, startEvent, cancelEvent){ | |
if(startEvent){ | |
obj.un(startEvent, this.start, this); | |
} | |
if(cancelEvent){ | |
obj.un(cancelEvent, this.cancel, this); | |
} | |
}, | |
/** | |
* Resets all timers and exits "active" mode | |
*/ | |
reset: function(){ | |
this.cancel(); | |
this.cancelTimeout(); | |
this.active = false; | |
}, | |
// private | |
callFn: function(){ | |
this.reset(); | |
this.active = true; | |
this.fn.apply(this.scope || this, this.args || []); | |
}, | |
// private | |
handleTimeout: function(){ | |
this.active = false; | |
delete this.timeoutId; | |
if(this.onTimeout){ | |
this.onTimeout.call(this.scope || this, this); | |
} | |
}, | |
// private | |
cancelTimeout: function(){ | |
if(this.timeoutId){ | |
clearTimeout(this.timeoutId); | |
delete this.timeoutId; | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I added undefined properties on the prototype to make it easier to discover config options. You can safely delete them.