wiki.techinc.nl/resources/jquery/jquery.delayedBind.js
Brion Vibber b36d8ace6d Followup r104671: fix regression in jquery.delayedBind() due to change in param processing for jquery's bind()
Problem was per CR comment https://www.mediawiki.org/wiki/Special:Code/MediaWiki/104671#c26836 -- parameter count check changed in upstream jquery.bind(), causing the way we passed params to break if the optional 'data' parameter was left out.

Added QUnit test cases for jquery.delayedBind() with and without the optional 'data' parameter.
Undoes r104671 since the issue it was working around is fixed.
2011-12-02 21:47:46 +00:00

73 lines
No EOL
2.3 KiB
JavaScript

(function( $ ) {
/**
* Function that escapes spaces in event names. This is needed because
* "_delayedBind-foo bar-1000" refers to two events
*/
function encodeEvent( event ) {
return event.replace( /-/g, '--' ).replace( / /g, '-' );
}
$.fn.extend( {
/**
* Bind a callback to an event in a delayed fashion.
* In detail, this means that the callback will be called a certain
* time after the event fires, but the timer is reset every time
* the event fires.
* @param timeout Number of milliseconds to wait
* @param event Name of the event (string)
* @param data Data to pass to the event handler (optional)
* @param callback Function to call
*/
delayedBind: function( timeout, event, data, callback ) {
if ( arguments.length == 3 ) {
// Shift optional parameter down
callback = data;
data = undefined;
}
var encEvent = encodeEvent( event );
return this.each( function() {
var that = this;
// Bind the top half
// Do this only once for every (event, timeout) pair
if ( !( $(this).data( '_delayedBindBound-' + encEvent + '-' + timeout ) ) ) {
$(this).data( '_delayedBindBound-' + encEvent + '-' + timeout, true );
$(this).bind( event, function() {
var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout );
// Cancel the running timer
if ( typeof timerID != 'undefined' )
clearTimeout( timerID );
timerID = setTimeout( function() {
$(that).trigger( '_delayedBind-' + encEvent + '-' + timeout );
}, timeout );
$(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout, timerID );
} );
}
// Bottom half
$(this).bind( '_delayedBind-' + encEvent + '-' + timeout, data, callback );
} );
},
/**
* Cancel the timers for delayed events on the selected elements.
*/
delayedBindCancel: function( timeout, event ) {
var encEvent = encodeEvent( event );
return this.each( function() {
var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout );
if ( typeof timerID != 'undefined' )
clearTimeout( timerID );
} );
},
/**
* Unbind an event bound with delayedBind()
*/
delayedBindUnbind: function( timeout, event, callback ) {
var encEvent = encodeEvent( event );
return this.each( function() {
$(this).unbind( '_delayedBind-' + encEvent + '-' + timeout, callback );
} );
}
} );
} )( jQuery );