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}.

When I switched from yahoo to jQuery, this is basically the only thing I missed, as they have a setXY method in their Dom object.

Currently, offset only returns the offset of the first element in the array. You could set the x,y 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 other 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 of ‘position:relative’, instead of of being relative to the window itself.

UPDATE. Sparked by our recommendation to the jQuery developers, they added setting offset to jQuery 1.4. However, we’ve seen instances where it does not accurately position the elements (perhaps when the current ‘left’ or ‘top’ is set to ‘auto’ instead of a pixel value), so this one may still be useful as a fallback.

Example usage:

$("#myElement").offset({left:34,top:100});

Just include a js file with this script and you’re all set:

(function($){

$.fn.extend({

	/**
	 * Stores 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(){
			var el = this;

			var hide = false;

			if($(el).css('display')=='none'){
				hide = true;
				$(el).show();
			};

			var style_pos = $(el).css('position');

			// default to relative
			if (style_pos == 'static') {
				$(el).css('position','relative');
				style_pos = 'relative';
			};

			var offset = $(el).offset();

			if (offset){
				var delta = {
					left : parseInt($(el).css('left'), 10),
					top: parseInt($(el).css('top'), 10)
				};

				// in case of 'auto'
				if (isNaN(delta.left))
					delta.left = (style_pos == 'relative') ? 0 : el.offsetLeft;
				if (isNaN(delta.top))
					delta.top = (style_pos == 'relative') ? 0 : el.offsetTop;

				if (newOffset.left || newOffset.left===0)
					$(el).css('left',newOffset.left - offset.left + delta.left + 'px');

				if (newOffset.top || newOffset.top===0)
					$(el).css('top',newOffset.top - offset.top + delta.top + 'px');
			};
			if(hide) $(el).hide();
		});
	}

});

})(jQuery);

(503) 382-9273 | 17933 NW Evergreen Parkway, Suite 220 | Beaverton, Oregon 97006