This script mods the native jQuery.fn.offset() so that it will set the offset of the elements by accepting a parameter in the form of {left:px,top:px}.
Before jQuery 1.4, the jQuery offset function was only a getter and not a setter. You could set the x,y (let, top) position of the elements by using $(element).css({left:px,top:px}), but it does not always work correctly, especially when the element you are trying to position is nested within relatively or absolutely positioned elements. The problem is that the left and top you try to set with css will be relative to the nearest parent element that has css position of ‘relative’, instead of of being relative to the window itself.
After searching unsuccessfully for a suitable jQuery plugin for setting offset, we created our own.
We recommended that this feature be added to jQuery, and the jQuery developers responded. jQuery 1.4 comes with a setter version of offset. Unfortunately, their version implements it differently and we’ve noticed some bugs in the way elements are placed. Until it’s fixed, we’ll continue using our replacement.
Example usage:
$("#myElement").offset({left:34,top:100});
Just include a js file with this script and you’re all set:
(function($){
/**
* Function for setting offset, created here so it's only created once rather than
* creating an anonymous function every time offset is called
*/
function setOffset(el, newOffset){
var $el = $(el);
// get the current css position of the element
var cssPosition = $el.css('position');
// whether or not element is hidden
var hidden = false;
// if element was hidden, show it
if($el.css('display') == 'none'){
hidden = true;
$el.show();
}
// get the current offset of the element
var curOffset = $el.offset();
// if there is no current jQuery offset, give up
if(!curOffset){
// if element was hidden, hide it again
if(hidden)
$el.hide();
return;
}
// set position to relative if it's static
if (cssPosition == 'static') {
$el.css('position', 'relative');
cssPosition = 'relative';
}
// get current 'left' and 'top' values from css
// this is not necessarily the same as the jQuery offset
var delta = {
left : parseInt($el.css('left'), 10),
top: parseInt($el.css('top'), 10)
};
// if the css left or top are 'auto', they aren't numbers
if (isNaN(delta.left)){
delta.left = (cssPosition == 'relative') ? 0 : el.offsetLeft;
}
if (isNaN(delta.top)){
delta.top = (cssPosition == 'relative') ? 0 : el.offsetTop;
}
if (newOffset.left || 0 === newOffset.left){
$el.css('left', newOffset.left - curOffset.left + delta.left + 'px');
}
if (newOffset.top || 0 === newOffset.top){
$el.css('top', newOffset.top - curOffset.top + delta.top + 'px');
}
// if element was hidden, hide it again
if(hidden)
$el.hide();
}
$.fn.extend({
/**
* Store the original version of offset(), so that we don't lose it
*/
_offset : $.fn.offset,
/**
* Set or get the specific left and top position of the matched
* elements, relative the the browser window by calling setXY
* @param {Object} newOffset
*/
offset : function(newOffset){
return !newOffset ? this._offset() : this.each(function(){
setOffset(this, newOffset);
});
}
});
})(jQuery);
(503) 746-9116 | 17933 NW Evergreen Parkway, Suite 220 | Beaverton, Oregon 97006