user1032531 user1032531 - 5 months ago 19
jQuery Question

Get dimensions of element located in hidden parent

How do I get height, width, outerHeight, etc dimensions for elements located in a hidden parent?

I've looked at How get size of element with hidden parent? but it doesn't work.

Below is what I have tried along with the results.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Testing</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js" type="text/javascript"></script>
<script src="actual/jquery.actual.js" type="text/javascript"></script>
<style type="text/css">
.hidden{display:none;}
a{border: 1px solid black;margin:4px;padding:2px;}
</style>
<script type="text/javascript">
function getDim_normal($t){
var dim = {
outerWidth:$t.outerWidth(),
outerHeight:$t.outerHeight(),
width:$t.css('width'),
height:$t.css('height'),
};
return dim;
}
function getDim_nick($t){
//Based on http://stackoverflow.com/a/2345813/1032531
var previousCss = $t.attr("style");
$t.css({
position: 'absolute',
visibility: 'hidden',
display: 'block'
});
var dim = {
outerWidth:$t.outerWidth(),
outerHeight:$t.outerHeight(),
width:$t.css('width'),
height:$t.css('height'),
};
$t.attr("style", previousCss ? previousCss : "");
return dim;
}

function getDim_actualPlugin($t){
//Based on http://dreamerslab.com/blog/en/get-hidden-elements-width-and-height-with-jquery/
dim={
outerWidth_actual:$t.actual('outerWidth'),
outerHeigh_actualt:$t.actual('outerHeight'),
width_actual:$t.actual('width'),
height_actual:$t.actual('height'),
};
return dim;
}

$(function(){
var o=[];
$('a').each(function(i) {
var $t=$(this);
o[i]={
normal:getDim_normal($t),
nick:getDim_nick($t),
actualPlugin:getDim_actualPlugin($t),
};
}
);
console.log( JSON.stringify(o, null, 2) );
});
</script>
</head>

<body>
<div><a href="#">hello</a></div>
<div class="hidden"><a href="#">hello</a></div>
<div><a href="#" class="hidden">hello</a></div>
</body>
</html>


Results:

[
{
"normal": {
"outerWidth": 38,
"outerHeight": 25,
"width": "31.76666px",
"height": "18.76666px"
},
"nick": {
"outerWidth": 38,
"outerHeight": 26,
"width": "31.76666px",
"height": "19.76666px"
},
"actual": {
"outerWidth_actual": 38,
"outerHeigh_actualt": 25,
"width_actual": 31.76666,
"height_actual": 18.76666
}
},
{
"normal": {
"outerWidth": 6.23334,
"outerHeight": 6.23334,
"width": "0px",
"height": "0px"
},
"nick": {
"outerWidth": 6.23334,
"outerHeight": 6.23334,
"width": "0px",
"height": "0px"
},
"actual": {
"outerWidth_actual": 2120,
"outerHeigh_actualt": 26,
"width_actual": 2113.76666,
"height_actual": 19.76666
}
},
{
"normal": {
"outerWidth": 38,
"outerHeight": 26,
"width": "31.76666px",
"height": "19.76666px"
},
"nick": {
"outerWidth": 38,
"outerHeight": 26,
"width": "31.76666px",
"height": "19.76666px"
},
"actual": {
"outerWidth_actual": 2120,
"outerHeigh_actualt": 26,
"width_actual": 2113.76666,
"height_actual": 19.76666
}
}
]

Answer

Okay, here is what I am thinking. In theory, it should work for any element whether hidden or a child of one or more hidden ancestors. See https://jsbin.com/ruzudututo/edit?html,output for demo of the below script. Maybe not the right forum to request a review, but since started here, would appreciate any constructive criticism.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Testing</title>  
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js" type="text/javascript"></script>
        <style type="text/css">
            .hidden{display:none;}
            a{border: 1px solid black;margin:4px;padding:2px;}
        </style> 
        <script type="text/javascript">
            $.getDimensions=function (e,p)   {
                /*Since I am using jQuery to get element dimensions, make this a jQuery utility method.
                Consider not using jQuery!
                Future.  Allow user to pass those variables desired, and only return those to improve performance.
                Assumes BODY is never hidden
                */
                var hidden=[], style, $e=$(e);
                while(e.parentNode.tagName!='HTML') {
                    style=e.currentStyle?e.currentStyle:getComputedStyle(e,null);
                    if((style.display=='none')) {
                        hidden.push({'e':e,'position':style.position,'visibility':style.visibility,'display':style.display});
                        e.style.position='absolute';
                        e.style.visibility='hidden';
                        e.style.display='block';
                    }
                    e = e.parentNode;
                }
                /* Change to use native JavaScript.
                If changes to accept desired attributes instead of all, using the following:
                var results={}; for (var i = p.length; i > 0; --i) {results[p[i-1]]=this[p[i-1]]();}
                */
                var results={
                    width:$e.width(),
                    height:$e.height(),
                    innerWidth:$e.innerWidth(),
                    innerHeight:$e.innerHeight(),
                    outerWidth:$e.outerWidth(),
                    outerHeight:$e.outerHeight(),
                    outerWidthTrue:$e.outerWidth(true),
                    outerHeightTrue:$e.outerHeight(true),
                };

                //Set it back to what it was
                for (var i = hidden.length; i > 0; --i) {
                    hidden[i-1].e.style.position=hidden[i-1].position;
                    hidden[i-1].e.style.visibility=hidden[i-1].visibility;
                    hidden[i-1].e.style.display=hidden[i-1].display;
                }
                return results;
            }

            function getDimensionsNormal(e) {
                var $e=$(e);
                return {
                    width:$e.width(),
                    height:$e.height(),
                    innerWidth:$e.innerWidth(),
                    innerHeight:$e.innerHeight(),
                    outerWidth:$e.outerWidth(),
                    outerHeight:$e.outerHeight(),
                    outerWidthTrue:$e.outerWidth(true),
                    outerHeightTrue:$e.outerHeight(true),
                };
            }

            $(function(){
                console.log($.getDimensions(document.getElementById("a1")));
                console.log(getDimensionsNormal(document.getElementById("a2")));
            });
        </script>
    </head>

    <body>
        <div class="hidden"><div><p class="hidden"><span class="hidden"><a id="a1" href="#">hello</a></span></p></div></div>
        <div><div><p><span><a id="a2" href="#">hello</a></span></p></div></div>
    </body> 
</html> 
Comments