jQuery Swap.js

The following is a modification of jQuery Swapsie Plugin. The mods applied allow the vertical swap between divs with different heights. Enhancements are required to allow horizontal swapping.

/*!  
 * jQuery Swapsie Plugin  
 * Examples and documentation at: http://biostall.com/swap-and-re-order-divs-smoothly-using-jquery-swapsie-plugin  
 * Copyright (c) 2010 Steve Marks - info@biostall.com  
 * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php  
 * Version: 1 (09-JULY-2010)  
*/
var swapping = false;
(function ($) {
    $.fn.extend({
        swap: function (options) { // Init 
            var defaults = {
                target: "",
                speed: 1000,
                opacity: "1",
                callback: function () {}
            };
            options = $.extend(defaults, options);
            // Get the elements  
            return this.each(function () {
                var source = $(this);
                if (options.target != "" && !swapping) {
                    var target = options.target;
                    swapping = true;
                    // Set positions for the elements 
                    var attributes = new Array();
                    attributes['source'] = source.css("position");
                    attributes['target'] = target.css("position");
                    if (attributes['source'] != "relative" && attributes['source'] != "absolute") {
                        source.css("position", "relative");
                    }
                    if (attributes['target'] != "relative" && attributes['target'] != "absolute") {
                        target.css("position", "relative");
                    }
                    // Movement 
                    var position = new Array();
                    var totals = new Array();
                    var totals_source = new Array();
                    var totals_target = new Array();
                    position['source'] = source.offset();
                    position['target'] = target.offset();
                    var height = new Array();
                    height['source'] = source.height();
                    height['target'] = target.height();
                    var width = new Array();
                    width['source'] = source.width();
                    width['target'] = target.width();
                    // y-axis movement                     
                    var direction_y = new Array();
                    direction_y['source'] = '-';
                    direction_y['target'] = '-';
                    if (position['source'].top <= position['target'].top) {
                        direction_y['source'] = '+';
                        totals['y'] = position['target'].top - position['source'].top;
                    } else {
                        totals['y'] = position['source'].top - position['target'].top;
                    }
                    if (direction_y['source'] == '-') {
                        direction_y['target'] = '+';
                    } else {
                        direction_y['target'] = '-';
                    }
                    // correct the values
                    totals_source['y'] = totals['y'];
                    totals_target['y'] = totals['y'];
                    if (height['source'] != height['target']) {
                        // set the difference                         
                        if (height['source'] > height['target']) {
                            var diff = height['source'] - height['target'];
                            if (direction_y['source'] == '-') {
                                totals_target['y'] = totals['y'] + diff;
                            } else {
                                totals_source['y'] = totals['y'] - diff;
                            }
                        } else {
                            var diff = height['target'] - height['source'];
                            if (direction_y['source'] == '-') {
                                totals_target['y'] = totals['y'] - diff;
                            } else {
                                totals_source['y'] = totals['y'] + diff;
                            }
                        }
                    }
                    // x-axis movement
                    var direction_x = new Array();
                    direction_x['source'] = '-';
                    direction_x['target'] = '-';
                    if (position['source'].left <= position['target'].left) {
                        direction_x['source'] = '+';
                        totals['x'] = position['target'].left - position['source'].left;
                    } else {
                        totals['x'] = position['source'].left - position['target'].left;
                    }
                    if (direction_x['source'] == '-') {
                        direction_x['target'] = '+';
                    } else {
                        direction_x['target'] = '-';
                    }
                    // correct the values
                    totals_source['x'] = totals['x'];
                    totals_target['x'] = totals['x'];
                    if (width['source'] != width['target']) {
                        // set the difference                         
                        if (width['source'] > width['target']) {
                            var diff = width['source'] - width['target'];
                            if (direction_y['source'] == '-') {
                                totals_target['x'] = totals['x'] + diff;
                            } else {
                                totals_source['x'] = totals['x'] - diff;
                            }
                        } else {
                            var diff = width['target'] - width['source'];
                            if (direction_y['source'] == '-') {
                                totals_target['x'] = totals['x'] - diff;
                            } else {
                                totals_source['x'] = totals['x'] + diff;
                            }
                        }
                    }
                    // Do the swapping
                    source.animate({
                        opacity: options.opacity
                    }, 100, function () {
                        source.animate({
                            top: direction_y['source'] + "=" + totals_source['y'] + "px",
                            left: direction_x['source'] + "=" + totals_source['x'] + "px"
                        }, options.speed, function () {
                            source.animate({
                                opacity: "1"
                            }, 100);
                        });
                    });
                    target.animate({
                        opacity: options.opacity
                    }, 100, function () {
                        target.animate({
                            top: direction_y['target'] + "=" + totals_target['y'] + "px",
                            left: direction_x['target'] + "=" + totals_target['x'] + "px"
                        }, options.speed, function () {
                            target.animate({
                                opacity: "1"
                            }, 100, function () {
                                swapping = false;
                                // call the callback and apply the scope:
                                options.callback.call(this);
                            });
                        });
                    });
                }
            });
        }
    });
})(jQuery);Code language: JavaScript (javascript)