Short version: I’m extending a jQuery object function that is intended to take 0-3 arguments and pass them off as the second to fourth arguments into jQuery.animate. Except, I want to isolate the callback and put in another function call at the end of it.
I’m extending the jQuery library the ordinary way, through jQuery.fn.newfunction = .... It’s a custom animation function, specifically one that expands an object so that its outerwidth including margins equals the inner width of its parent node.
jQuery.fn.expand_to_parent_container = function() {
var args = Array.prototype.slice.call(arguments);
return this.each(function(){
var parent = $(this).parent();
parent.inner_width = parent.innerWidth();
var inner_outer_differential = $(this).outerWidth(true) - $(this).width();
// store original width for reversion later
$(this).data('original_width', $(this).width());
args.unshift({ width: parent.inner_width - inner_outer_differential });
$.fn.animate.apply($(this), args );
});
}
Simple enough. I’m using the arguments local variable, “casting” it as an array, and unshifting the first argument, which will go in the properties slot of .animate (API here). The intention, therefore, is to allow .expand_to_parent_container to take the arguments duration, easing, callback, with the usual jQuery convention of making them optional in intuitive patterns (e.g., if only a function is passed, it becomes the callback). It appears as though jQuery.speed is responsible for figuring out this mess, but I’d rather not use it/tamper with it directly because it does not appear to be as public/deprecation-proof as the other jQuery functions, and because I’d rather just delegate the task to .animate.
Here’s my reversion function.
jQuery.fn.contract_to_original_size = function() {
var args = Array.prototype.slice.call(arguments);
var callback_with_width_reset = function(){
callback();
$(this).width('auto');
}
args.unshift({ width: $(this).data('original_width') });
if($(this).data('original_width')) {
$.fn.animate.apply($(this), args );
} else {
$(this).width('auto');
}
}
I make my desired behaviour clear in var callback_with_width_reset ... assignment, in that I’d like for the width property to be reset to auto, both to restore it closer to its original state and to recover from any craziness that might happen over the course of lots of animations. However, I don’t know how to piece out the callback function from arguments or args.
There are a few things I’d like to point out real quick:
expand_to_parent_containeron multiple objects at once, you keep unshifting{width: ...}objects intoargsand never shift them back off.contract_to_original_sizedoesn’t usethis.each()nor does itreturn this, and it will suffer from the same problems with unshifting width objects over and over.original-widthif it isn’t already set, stopping one of your problems here (starting an expand while expanded / whatever wont mess with it! )$.map()on your arguments array to detect and replace your callback function pretty easily, if you still feel you need to.Here is the code adjusted a little:
Check it out in action on jsFiddle