Get the visible height of a div with jQuery

JacobTheDev picture JacobTheDev · Jul 15, 2014 · Viewed 60k times · Source

I need to retrieve the visible height of a div within a scrollable area. I consider myself pretty decent with jQuery, but this is completely throwing me off.

Let's say I've got a red div within a black wrapper:

In the graphic above, the jQuery function would return 248, the visible portion of the div.

Once the user scrolls past the top of the div, as in the above graphic, it would report 296.

Now, once the user has scrolled past the div, it would again report 248.

Obviously my numbers aren't going to be as consistent and clear as they are in this demo, or I'd just hard code for those numbers.

I have a bit of a theory:

  • Get the height of the window
  • Get the height of the div
  • Get the initial offset of the div from the top of the window
  • Get the offset as the user scrolls.
    • If the offset is positive, it means the top of the div is still visible.
    • if it's negative, the top of the div has been eclipsed by the window. At this point, the div could either be taking up the whole height of the window, or the bottom of the div could be showing
    • If the bottom of the div is showing, figure out the gap between it and the bottom of the window.

It seems pretty simple, but I just can't wrap my head around it. I'll take another crack tomorrow morning; I just figured some of you geniuses might be able to help.

Thanks!

UPDATE: I figured this out on my own, but looks like one of the answers below is more elegant, so I'll be using that instead. For the curious, here's what I came up with:

$(document).ready(function() {
    var windowHeight = $(window).height();
    var overviewHeight = $("#overview").height();
    var overviewStaticTop = $("#overview").offset().top;
    var overviewScrollTop = overviewStaticTop - $(window).scrollTop();
    var overviewStaticBottom = overviewStaticTop + $("#overview").height();
    var overviewScrollBottom = windowHeight - (overviewStaticBottom - $(window).scrollTop());
    var visibleArea;
    if ((overviewHeight + overviewScrollTop) < windowHeight) {
        // alert("bottom is showing!");
        visibleArea = windowHeight - overviewScrollBottom;
        // alert(visibleArea);
    } else {
        if (overviewScrollTop < 0) {
            // alert("is full height");
            visibleArea = windowHeight;
            // alert(visibleArea);
        } else {
            // alert("top is showing");
            visibleArea = windowHeight - overviewScrollTop;
            // alert(visibleArea);
        }
    }
});

Answer

Rory McCrossan picture Rory McCrossan · Jul 16, 2014

Here is a quick and dirty concept. It basically compares the offset().top of the element to the top of the window, and the offset().top + height() to the bottom of the window:

function getVisible() {    
    var $el = $('#foo'),
        scrollTop = $(this).scrollTop(),
        scrollBot = scrollTop + $(this).height(),
        elTop = $el.offset().top,
        elBottom = elTop + $el.outerHeight(),
        visibleTop = elTop < scrollTop ? scrollTop : elTop,
        visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
    $('#notification').text(visibleBottom - visibleTop);
}

$(window).on('scroll resize', getVisible);

Example fiddle

edit - small update to also perform the logic when the window is being resized.