Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get height of non-overflowed portion of div

Say I have a wrapper div with a overflow:hidden on it and a div inside that that spans far below the visible portion. How can I get the visible height of the internal div?

<div id="wrapper" style="overflow: hidden; height:400px;">
    <div id="inner">
        <!--Lots of content in here-->
    </div>
<div>

Every method I try attempting to get the height of the inner div returns the complete height including the hidden parts, i.e. 2000px. I want to be able to get the height of only the visible portion, so 400px in this example case.

I know I could just get the height of the parentNode, but in production, the inner div might not be a first child. So there might be other divs separating them, and so the height of #inner would be 400 - whatever the offsets of the elements between it and #wrapper.

like image 243
ryandlf Avatar asked Oct 12 '12 23:10

ryandlf


2 Answers

As basic algorithm this could work:

var offset = 0;
var node = document.getElementById("inner");
while (node.offsetParent && node.offsetParent.id != "wrapper")
{
    offset += node.offsetTop;
    node = node.offsetParent;
}
var visible = node.offsetHeight - offset;

But if you're doing these kinds of things, maybe you already use jQuery, which might be of service with its .height() and .offset() functions:

$("#wrapper").height()-
$("#inner").offset()['top']+
$("#wrapper").offset()['top'];  
like image 94
Wolfgang Stengel Avatar answered Oct 11 '22 04:10

Wolfgang Stengel


Quick algorithm that goes up the DOM tree looking at window.getComputedStyle for overflow: hidden

function visibleArea(node){
    var o = {height: node.offsetHeight, width: node.offsetWidth}, // size
        d = {y: (node.offsetTop || 0), x: (node.offsetLeft || 0), node: node.offsetParent}, // position
        css, y, x;
    while( null !== (node = node.parentNode) ){  // loop up through DOM
        css = window.getComputedStyle(node);
        if( css && css.overflow === 'hidden' ){  // if has style && overflow
            y = node.offsetHeight - d.y;         // calculate visible y
            x = node.offsetWidth - d.x;          // and x
            if( node !== d.node ){
                y = y + (node.offsetTop || 0);   // using || 0 in case it doesn't have an offsetParent
                x = x + (node.offsetLeft || 0);
            }
            if( y < o.height ) {
                if( y < 0 ) o.height = 0;
                else o.height = y;
            }
            if( x < o.width ) {
                if( x < 0 ) o.width = 0;
                else o.width = x;
            }
            return o;                            // return (modify if you want to loop up again)
        }
        if( node === d.node ){                   // update offsets
            d.y = d.y + (node.offsetTop || 0);
            d.x = d.x + (node.offsetLeft || 0);
            d.node = node.offsetParent;
        }
    }
    return o;                                    // return if no hidden
}

example fiddle (look at your console).

like image 42
Paul S. Avatar answered Oct 11 '22 05:10

Paul S.