// jquery.events.frame.js // 1.1 - lite // Stephen Band // // Project home: // webdev.stephband.info/events/frame/ // // Source: // http://github.com/stephband/jquery.event.frame (function(jQuery, undefined){ var timer; // Timer constructor // fn - callback to call on each frame, with context set to the timer object // fd - frame duration in milliseconds function Timer( fn, fd ) { var self = this, clock; function update(){ self.frameCount++; fn.call(self); } this.frameDuration = fd || 25 ; this.frameCount = -1 ; this.start = function(){ update(); clock = setInterval(update, this.frameDuration); }; this.stop = function(){ clearInterval( clock ); clock = null; }; } // callHandler() is the callback given to the timer object, // it makes the event object and calls the handler // context is the timer object function callHandler(){ var fn = jQuery.event.special.frame.handler, event = jQuery.Event("frame"), array = this.array, l = array.length; // Give event object properties event.frameCount = this.frameCount; // Call handler on each elem in array while (l--) { fn.call(array[l], event); } } if (!jQuery.event.special.frame) { jQuery.event.special.frame = { // Fires the first time an event is bound per element setup: function(data, namespaces) { if ( timer ) { timer.array.push(this); } else { timer = new Timer( callHandler, data && data.frameDuration ); timer.array = [this]; // Queue timer to start as soon as this thread has finished var t = setTimeout(function(){ timer.start(); clearTimeout(t); t = null; }, 0); } return; }, // Fires last time event is unbound per element teardown: function(namespaces) { var array = timer.array, l = array.length; // Remove element from list while (l--) { if (array[l] === this) { array.splice(l, 1); break; } } // Stop and remove timer when no elems left if (array.length === 0) { timer.stop(); timer = undefined; } return; }, handler: function(event){ // let jQuery handle the calling of event handlers jQuery.event.handle.apply(this, arguments); } }; } })(jQuery);