r2741 - + Added support for reverting positioned elements back to their original spots (as closel...
Author: vtGavin
Date: Fri Jun 12 19:41:18 2009
New Revision: 2741
Modified:
branches/dev/positionTo/ui/utils.positionTo.js
Log:
+ Added support for reverting positioned elements back to their original
spots (as closely as possible).
+ Put in stubs for a method wherein positionTo will use a document-bound
data() index for referencing positioned elements within call-backs (to
avoid unnecessary selector latency).
+ Fleshed out revert a bit more.
Modified: branches/dev/positionTo/ui/utils.positionTo.js
==============================================================================
--- branches/dev/positionTo/ui/utils.positionTo.js (original)
+++ branches/dev/positionTo/ui/utils.positionTo.js Fri Jun 12 19:41:18 2009
@@ -10,8 +10,11 @@
* Depends:
* ui.core.js
*/
-
$.fn.positionTo = function(parentElem, options){
+ // !!!
+ // think about implementing an indexing scheme using a document-bound
data tuple to
+ // reduce the need for constant selector invocation
+
var positionTo_handlers = {
scroll: function(){
console.log('scroll detected');
@@ -20,27 +23,39 @@
var $parentElem = $(parentElem),
parentOffset = $parentElem.offset(),
- // store the border widths (if they exist) for the parent element
- parentElem_borderWidths = {
- left:
parseInt($parentElem.css('border-left-width').replace(/px/, '')),
- right:
parseInt($parentElem.css('border-right-width').replace(/px/, '')),
- top:
parseInt($parentElem.css('border-top-width').replace(/px/, '')),
- bottom:
parseInt($parentElem.css('border-bottom-width').replace(/px/, ''))
- },
// calculate parent element coordinates and pad accordingly for
any border styling
parentElem_coords = {
- left: parentOffset.left - parentElem_borderWidths.left,
- right: parentOffset.left + $parentElem.outerWidth() +
parentElem_borderWidths.right,
- top: parentOffset.top - parentElem_borderWidths.top,
- bottom: parentOffset.top + $parentElem.outerHeight() +
parentElem_borderWidths.bottom
+ left: parentOffset.left,
+ right: parentOffset.left + $parentElem.outerWidth(),
+ top: parentOffset.top,
+ bottom: parentOffset.top + $parentElem.outerHeight()
};
+
+ this.data('positionTo_uniqueNodeID', {
+ elem_originalParent: (this.parent().length ? this.parent()[0] :
false),
+ ordinalSibling: {
+ $previous: false,
+ $next: false
+ },
+ originalCSS: {
+ display: this.css('display'),
+ position: this.css('position'),
+ left: this.css('left'),
+ right: this.css('right'),
+ top: this.css('top'),
+ bottom: this.css('bottom')
+ }
+ });
+ // set the pertinent ordinal sibling for this positionable element
before it is appended
+ // to the body
+ // !!!
+
$('body').append(this);
-
+
// prep this element for being positioned
this.css('display', 'block')
- .css('position', 'absolute')
- .css('margin', '0');
+ .css('position', 'absolute');
// !!! arbitrarily position the element
this.css('left', parentElem_coords.right + 'px')
@@ -53,78 +68,6 @@
$(this).bind('scroll.positionTo_uniqueNodeID',
positionTo_handlers.scroll)
.addClass('positionTo_tagged_uniqueNodeID');
});
-
- /**
- var _options = $.extend({
- around: 'mouse',
- direction: 'default',
- forceDirection: false,
- offset: [0, 0]
- }, options);
-
- var leftOffset = 0,
- topOffset = 0,
- height = this[0].offsetHeight,
- width = this[0].offsetWidth,
- op = this.offsetParent(),
- sp = $(this.scrollParent()[0] || document.body),
- spBorderTop = parseInt(op.css('borderTopWidth'),10),
- spBorderLeft= parseInt(op.css('borderLeftWidth'),10),
- opBorderTop = parseInt(op.css('borderTopWidth'),10),
- opBorderLeft= parseInt(op.css('borderLeftWidth'),10),
- opOffset = op.offset(),
- spOffset = sp.offset()
- ;
-
- //Ugly fix for the issues of offset related to the body element
- opOffset = (/(html|body)/).test(op[0].tagName.toLowerCase()) ? { top: 0,
left: 0 } : opOffset;
- spOffset = (/(html|body)/).test(op[0].tagName.toLowerCase()) ? { top: 0,
left: 0 } : spOffset;
-
- var bottomEdge = (/(html|body)/).test(op[0].tagName.toLowerCase()) ?
$(window).height() : spOffset.top + spBorderTop + sp.height();
- var rightEdge = (/(html|body)/).test(op[0].tagName.toLowerCase()) ?
$(window).width() : spOffset.left + spBorderLeft + sp.width();
-
- if($(options.around).length && $(options.around)[0].nodeName) { //If
around is an element
-
- var element = $(options.around),
- offset = element.offset(),
- relHeight = element[0].offsetHeight,
- relWidth = element[0].offsetWidth
- ;
-
- if((/(left|right)/).test(options.direction)) {
-
- leftOffset = ( options.direction == 'left' ? (offset.left -
spOffset.left - spBorderLeft > width || options.forceDirection) :
(rightEdge-offset.left-relWidth < width && !options.forceDirection) ) ?
-(width) : relWidth;
- topOffset = event ? ( bottomEdge - offset.top < height ?
-(height-relHeight) : 0 ) : 0;
- } else {
- topOffset = ( options.direction == 'above' ? (offset.top - spOffset.top
- spBorderTop > height || options.forceDirection) :
(bottomEdge-offset.top-relHeight < height && !options.forceDirection) ) ?
-(height) : relHeight;
- }
-
- this.css({
- left: offset.left - opOffset.left - opBorderLeft + leftOffset +
options.offset[0],
- top: offset.top - opOffset.top - opBorderTop + topOffset +
options.offset[1]
- });
-
- } else {
-
- if((/(below|default)/).test(options.direction)) {
- topOffset = bottomEdge - event.pageY < height
&& !options.forceDirection ? -(height) : 0;
- } else if ((/above/).test(options.direction)) {
- topOffset = (event.pageY - spOffset.top - spBorderTop) > height ||
options.forceDirection ? -(height) : 0;
- }
-
- if((/(right|default)/).test(options.direction)) {
- leftOffset = rightEdge - event.pageX < width
&& !options.forceDirection ? -(width) : 0;
- } else if ((/left/).test(options.direction)) {
- leftOffset = (event.pageX - spOffset.left - spBorderLeft) > width ||
options.forceDirection ? -(width) : 0;
- }
-
-
- this.css({
- left: event.pageX - opOffset.left - opBorderLeft + leftOffset +
options.offset[0],
- top: event.pageY - opOffset.top - opBorderTop + topOffset +
options.offset[1]
- });
-
- }*/
};
/**
@@ -136,8 +79,49 @@
*/
$.fn.positionRevert = function()
{
+ var $elem_parent =
$(this.data('positionTo_uniqueNodeID').elem_originalParent),
+ ordinalSibling = this.data('positionTo_uniqueNodeID').ordinalSibling;
+
+ // if: this positionable element had a valid parent element when it was
first positioned
+ // then: attempt to place it back where it was originally positioned
+ if ($elem_parent.length)
+ {
+ // if: an ordinal previous sibling was specified
+ // AND
+ // it still exists in the DOM
+ // then: insert this element after it
+ if (ordinalSibling.$previous && ordinalSibling.$previous.length)
+ {
+ ordinalSibling.$previous.after(this);
+ }
+ // else if: an ordinal next sibling was specified
+ // AND
+ // it still exists in the DOM
+ // then: insert this element before it
+ else if (ordinalSibling.$next && ordinalSibling.$next.length)
+ {
+ ordinalSibling.$next.before(this);
+ }
+ // else: if all else fails, just append it directly to the parent node
+ else
+ {
+ $elem_parent.append(this);
+ }
+ }
+
+ // reset this positionable element to its original css values
+ var originalCSS = this.data('positionTo_uniqueNodeID').originalCSS;
+ this.css('display', originalCSS.display)
+ .css('position', originalCSS.position)
+ .css('left', originalCSS.left)
+ .css('right', originalCSS.right)
+ .css('top', originalCSS.top)
+ .css('bottom', originalCSS.bottom);
+
$(document).unbind('.positionTo_uniqueNodeID');
$('.positionTo_tagged_uniqueNodeID').unbind('.positionTo_uniqueNodeID')
.removeClass('positionTo_tagged_uniqueNodeID');
+
+ this.removeData('positionTo_uniqueNodeID');
}