Can jQuery copy an element's bounds (position, size, margins, etc.) to another element?
Asked Answered
M

3

5

I have an element of an arbitrary type. I'd like to create another element, of either the same or a different type that has the same position and size as the first. The element may or may not be positioned.

For example, I might start with a <select> with a certain size, possibly dependent on its contents, i.e. width/height auto. I want to create a new <div> that appears at the same position and has the same size.

I've tried copying the element's float, clear, position, width, height, margins and padding, but this is a little cumbersome. Also, while it works in Firefox, I'm running into some strange issues when testing on Webkit. Before I spend much more time figuring it out, I'd like to know whether there's some jQuery or jQuery UI functionality that already takes care of what I want to do.

I realize that this question is similar to an existing one, but mine has the important distinction of needing to work with elements of differing types, which precludes clone as a solution.

Mesdames answered 6/10, 2010 at 18:15 Comment(0)
M
4

This is NOT efficient, tested, or complete. And it is probably similar to what you are already doing. But I thought I'd post it anyways:

var positioningProps = ["float","position","width","height","left","top","marginLeft","marginTop","paddingLeft","paddingTop"];
var select = $("#mySelect");
var div = $("<div>").hide().before(select);
// don't do this kind of loop in production code
// http://www.vervestudios.co/jsbench/
for(var i in positioningProps){
    div.css(positioningProps[i], select.css(positioningProps[i])||"");
}
select.hide();
Mcwhorter answered 6/10, 2010 at 18:53 Comment(0)
M
3

How about just copying the element's offset and absolutely positioning it on the page?

Say you had an input element somewhere on the page with dimensions 100x25px.

<input type="text" id="firstname" style="width: 100px; height: 20px" />

And you wanted to place a div right on top of it (and hide the input).

// Store the input in a variable
var $firstname = $("#firstname");

// Create a new div and assign the width/height/top/left properties of the input
var $newdiv = $("<div />").css({
    'width': $firstname.width(),
    'height': $firstname.height(),
    'position': 'absolute',
    'top': $firstname.offset().top,
    'left': $firstname.offset().left
});

// Add the div to the body
$(body).append($newdiv);
Murcia answered 6/10, 2010 at 18:29 Comment(2)
This approach has issues with fluid layouts. If an element is inserted before "#firstName" which moves firstName down the page "newdiv" would not line up properly.Mcwhorter
This is probably true, a different solution is needed in liquid layout situations.Murcia
T
1

You can find out an elements bounds using this plugin to jQuery. The it would be just a simple matter of setting whatever properties you are interested in to the other object.

http://code.google.com/p/jquery-ui/source/browse/branches/labs/powella/coverslide/res/js/jquery/jquery.bounds.js?r=2698

/*
 * jQuery.bounds
 * author: Andrew Powell
*/

(function($){

        $.fn['bounds'] = function() 
        {
                var t = this, e = t[0];
                if (!e) return;

                var offset = t.offset(), pos = { width:e.offsetWidth, height:e.offsetHeight, left: 0, top: 0, right: 0, bottom: 0, x: 0, y: 0 };

                pos.left = offset.left; 
                pos.top = offset.top;

                //right and bottom
                pos.right = (pos.left + pos.width);
                pos.bottom = (pos.top + pos.height);
                pos.x = pos.left;
                pos.y = pos.top;
                pos.inner = {width: t.width(), height: t.height()};

                $.extend(pos, {toString: function(){ var t = this; return 'x: ' + t.x + ' y: ' + t.y + ' width: ' + t.width + ' height: ' + t.height + ' right: ' + t.right + ' bottom: ' + t.bottom; }});

                return pos;
        };

})(jQuery);
Transmigrant answered 10/2, 2012 at 11:42 Comment(1)
That doesn't work if the left/top margin or left/top padding is set. pos.left isn't offset.left anymore. The bounded rectangle would be shifted to the right by the margin/border/padding amounts.Ferriferous

© 2022 - 2024 — McMap. All rights reserved.