Skip to content

Commit

Permalink
Fixes issues with position: relative.
Browse files Browse the repository at this point in the history
  • Loading branch information
razorjack committed Feb 12, 2010
1 parent 11875ce commit 01212cd
Showing 1 changed file with 35 additions and 34 deletions.
69 changes: 35 additions & 34 deletions jquery.quicksand.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ Github site: http://github.com/razorjack/quicksand
*/ */



(function ($) { (function ($) {
$.fn.quicksand = function (collection, customOptions) { $.fn.quicksand = function (collection, customOptions) {
var options = { var options = {
Expand All @@ -41,6 +40,9 @@ Github site: http://github.com/razorjack/quicksand
// helping to clean it up after interrupted animation // helping to clean it up after interrupted animation
function cssPath(node) { function cssPath(node) {
var nodes = [] var nodes = []
if ($(node).get(0) == undefined) {
return "";
}
var name = $(node).get(0).nodeName.toLowerCase(); var name = $(node).get(0).nodeName.toLowerCase();
if ($(node).attr('id')) { if ($(node).attr('id')) {
name += '#' + $(node).attr('id'); name += '#' + $(node).attr('id');
Expand All @@ -61,18 +63,10 @@ Github site: http://github.com/razorjack/quicksand
var $sourceParent = $(this); // source, the visible container of source collection var $sourceParent = $(this); // source, the visible container of source collection
var sourceHeight = $(this).css('height'); // used to keep height and document flow during the animation var sourceHeight = $(this).css('height'); // used to keep height and document flow during the animation
var offset = $($sourceParent).offset(); // offset of visible container, used in animation calculations var offset = $($sourceParent).offset(); // offset of visible container, used in animation calculations
var offsets = []; // coordinates of every source collection item var offsets = []; // coordinates of every source collection item

// both variables are used to correct positioning within bordered body
var leftBorderCorrection = parseFloat($('body').css('border-left-width'));
var topBorderCorrection = parseFloat($('body').css('border-top-width'));


var $source = $(this).find(options.selector); // source collection items var $source = $(this).find(options.selector); // source collection items


// used to correct coordinates when any container node has position: relative
var relativeTop = 0;
var relativeLeft = 0;

// Gets called when any animation is finished // Gets called when any animation is finished
var postCallbackPerformed = 0; // prevents the function from being called more than one time var postCallbackPerformed = 0; // prevents the function from being called more than one time
var postCallback = function () { var postCallback = function () {
Expand All @@ -85,19 +79,27 @@ Github site: http://github.com/razorjack/quicksand
postCallbackPerformed = 1; postCallbackPerformed = 1;
} }
}; };

var $correctionParent = $sourceParent.offsetParent();
var correctionOffset = $correctionParent.offset();
if ($correctionParent.css('position') == 'relative') {
if ($correctionParent.get(0).nodeName.toLowerCase() == 'body') {

} else {
correctionOffset.top += parseFloat($correctionParent.css('border-top-width'));
correctionOffset.left += parseFloat($correctionParent.css('border-left-width'));
}
} else {
correctionOffset.top -= parseFloat($correctionParent.css('border-top-width'));
correctionOffset.left -= parseFloat($correctionParent.css('border-left-width'));
correctionOffset.top -= parseFloat($correctionParent.css('margin-top'));
correctionOffset.left -= parseFloat($correctionParent.css('margin-left'));
}



// keeps nodes after source container, holding their position // keeps nodes after source container, holding their position
$sourceParent.css('height', $(this).height()); $sourceParent.css('height', $(this).height());


// find first position: relative node and set it as a point of reference compatible with position: absolute
$($source.parentsUntil("html").toArray().reverse()).each(function (i) {
if ($(this).css('position') == 'relative') {
o = $(this).offset();
relativeTop = o.top;
relativeLeft = o.left;
}
});

// get positions of source collections // get positions of source collections
$source.each(function (i) { $source.each(function (i) {
offsets[i] = $(this).offset(); offsets[i] = $(this).offset();
Expand All @@ -106,6 +108,7 @@ Github site: http://github.com/razorjack/quicksand
// stops previous animations on source container // stops previous animations on source container
$(this).stop(); $(this).stop();



$source.each(function (i) { $source.each(function (i) {
$(this).stop(); // stop animation of collection items $(this).stop(); // stop animation of collection items


Expand All @@ -114,32 +117,30 @@ Github site: http://github.com/razorjack/quicksand
$(this) $(this)
.css('position', 'absolute') .css('position', 'absolute')
.css('margin', 0) .css('margin', 0)
.css('top', offsets[i].top - parseFloat($(this).css('margin-top')) + topBorderCorrection - relativeTop) .css('top', offsets[i].top - parseFloat($(this).css('margin-top')) - correctionOffset.top)
.css('left', offsets[i].left - parseFloat($(this).css('margin-left')) + leftBorderCorrection - relativeLeft); .css('left', offsets[i].left - parseFloat($(this).css('margin-left')) - correctionOffset.left);

}); });

// cleate temporary container with destination collection // create temporary container with destination collection
var $dest = $($sourceParent) var $dest = $($sourceParent)
.clone() .clone()
.html('') .html('')
.attr('id', '') .attr('id', '')
.attr("data-quicksand-owner", $sourceParent.selector) .attr("data-quicksand-owner", $sourceParent.selector)
.css('height', 'auto') .css('height', 'auto')
.css('width', $sourceParent.width() + 'px') .css('width', $sourceParent.width() + 'px')
.append($collection); .append($collection);

// insert node into HTML // insert node into HTML
// Note that the node is under visible source container in the exactly same position // Note that the node is under visible source container in the exactly same position
// The browser render all the items without showing them (opacity: 0.0) // The browser render all the items without showing them (opacity: 0.0)
// No offset calculations are needed, the browser just extracts position from underlayered destination items // No offset calculations are needed, the browser just extracts position from underlayered destination items
// and sets animation to destination positions. // and sets animation to destination positions.
$dest.insertBefore($sourceParent).css('z-index', -1) $dest.insertBefore($sourceParent).css('z-index', 1)
.css('opacity', 0.0) .css('opacity', 0.0)
.css('margin', 0.0) .css('margin', 0.0)
.css('position', 'absolute') .css('position', 'absolute')
.css('top', offset.top + topBorderCorrection - relativeTop) .css('top', offset.top - correctionOffset.top)
.css('left', offset.left + leftBorderCorrection - relativeLeft) .css('left', offset.left - correctionOffset.left)
.attr('data-quicksand-owner', cssPath($sourceParent)); .attr('data-quicksand-owner', cssPath($sourceParent));


// If destination container has different height than source container // If destination container has different height than source container
Expand All @@ -163,9 +164,9 @@ Github site: http://github.com/razorjack/quicksand
if ($.browser.msie) { if ($.browser.msie) {
// Got IE and want gorgeous scaling animation? // Got IE and want gorgeous scaling animation?
// Kiss my butt // Kiss my butt
$(this).animate({top: destElement.offset().top + topBorderCorrection - relativeTop, left: destElement.offset().left + leftBorderCorrection - relativeLeft, opacity: 1.0}, options.duration, options.easing, postCallback); $(this).animate({top: destElement.offset().top - correctionOffset.top, left: destElement.offset().left - correctionOffset.left, opacity: 1.0}, options.duration, options.easing, postCallback);
} else { } else {
$(this).animate({top: destElement.offset().top + topBorderCorrection - relativeTop, left: destElement.offset().left + leftBorderCorrection - relativeLeft, opacity: 1.0, scale: '1.0'}, options.duration, options.easing, postCallback); $(this).animate({top: destElement.offset().top - correctionOffset.top, left: destElement.offset().left - correctionOffset.left, opacity: 1.0, scale: '1.0'}, options.duration, options.easing, postCallback);
} }
} else { } else {
// The item from source collection is not present in destination collections // The item from source collection is not present in destination collections
Expand Down Expand Up @@ -201,8 +202,8 @@ Github site: http://github.com/razorjack/quicksand
.clone() .clone()
.css('position', 'absolute') .css('position', 'absolute')
.css('margin', 0.0) .css('margin', 0.0)
.css('top', destElement.offset().top + topBorderCorrection - relativeTop) .css('top', destElement.offset().top - correctionOffset.top)
.css('left', destElement.offset().left + leftBorderCorrection - relativeLeft) .css('left', destElement.offset().left - correctionOffset.left)
.css('opacity', 0.0) .css('opacity', 0.0)
.css('transform', 'scale(0.0)') .css('transform', 'scale(0.0)')
.appendTo($sourceParent) .appendTo($sourceParent)
Expand Down

0 comments on commit 01212cd

Please sign in to comment.