domingo, 10 de junio de 2012

JavaScript function inBetween

JavaScript function inBetween - be notified when a javascript function is called N times in between a time lapsus of T milliseconds.

This idea borned when reading the work of Ben Alman for function throttle : http://benalman.com/projects/jquery-throttle-debounce-plugin/

In that case the problem is to execute a function no more than once every T milliseconds. This is very helpful when you want to control how much an event handler is called back. I put a common example for events that are called intensively, like mousemove, or drag in my raphaël tutorial: http://cancerbero.vacau.com/raphaeltut/index.html#sec-events-function-throttle   There I explain very usefull cases of function throttle.

The thing is that function throttle made me think on the opposite problem: being notified when a function is called N times in a time lapsus of T milliseconds. This can be useful for registering double, triple, cuadruple clicks, and in general nth-clicks events.I call this, function inBetween (don't have a better name, suggestions accepted). See for example, how I would use inBetween with jquery for neing notified when a triple click occurs in between 1000 ms:

function click3Hendler(evt) {
    alert(this.clickCount+" clicks detected. last click xcoord: "+evt.clientX);
};
$("#someElement").click(inBetween(3, 1000, cb, {clickCount: 3}));

This is a complete working example: http://jsfiddle.net/RP7mW/11/.

Also there is a section in my raphaël tutorial for registering nth-click listeners to raphaël shapes using inBetween(). Link: http://cancerbero.vacau.com/raphaeltut/index.html#sec-events-inbetween

And this is the inBetween function code:
        
/**
 * inBetween resolves the problem of being notified when a function is called N times in in between a time lapsus of T ms.
 * @param n the amount of times.
 * @param t the time lapsus in ms
 * @param callback - the function to be called when the returned fcuntion is called at least n times in a lapsus of n ms.
 * @return a new function - when that function is called n times in a lapsus
 of t ms, then callback function will be called using the context object as
 the callback context.
 */
function inBetween(n, t, callback, context) {    
    var sb = [];
    sb.push("var that = arguments.callee; ")
    sb.push("var thisTime = new Date().getTime(); ")
    sb.push("var arr = that['ARR'];");
    sb.push("if(!arr){");
    sb.push("    arr = []; ");
    sb.push("    for(var i = 0; i < that['N']; i++) arr.push(thisTime); ");
    sb.push("    that['ARR'] = arr;");
    sb.push("    that['COUNT']=0");
    sb.push("}");
    
    sb.push("that['COUNT']++; ");;
    sb.push("arr.push(thisTime);");
    sb.push("var lastTime = arr.shift();");
        
    sb.push("if(that['COUNT'] >= that['N']) {");
    sb.push("    that['COUNT']=1; ");
    sb.push("    for(var i = 0; i < that['N']; i++) arr[i] = thisTime; ");
    sb.push("    if(thisTime-lastTime < that['T']) ");          
    sb.push("        that['CB'].apply(that['CTX'], arguments); ");
    sb.push("}");
        
    var fn = new Function(sb.join(""));    
    fn['N']=n;
    fn['T']=t;
    fn['CB']=callback;
    fn['CTX']=context;
    return fn;        
}; 

Hope this can be of some use for those who need some advance event - function stuff like this.

No hay comentarios: