Get the visible height of a div with jQuery
Calculate the amount of px an element (height) is in viewport
This tiny function will return the amount of px
an element is visible in the (vertical) Viewport:
function inViewport($el) { var elH = $el.outerHeight(), H = $(window).height(), r = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom; return Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H));}
Use like:
$(window).on("scroll resize", function(){ console.log( inViewport($('#elementID')) ); // n px in viewport});
that's it.
jQuery .inViewport()
Plugin
from the above you can extract the logic and create a plugin like this one:
/** * inViewport jQuery plugin by Roko C.B. * http://stackoverflow.com/a/26831113/383904 * Returns a callback function with an argument holding * the current amount of px an element is visible in viewport * (The min returned value is 0 (element outside of viewport) */;(function($, win) { $.fn.inViewport = function(cb) { return this.each(function(i,el) { function visPx(){ var elH = $(el).outerHeight(), H = $(win).height(), r = el.getBoundingClientRect(), t=r.top, b=r.bottom; return cb.call(el, Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H))); } visPx(); $(win).on("resize scroll", visPx); }); };}(jQuery, window));
Use like:
$("selector").inViewport(function(px) { console.log( px ); // `px` represents the amount of visible height if(px > 0) { // do this if element enters the viewport // px > 0 }else{ // do that if element exits the viewport // px = 0 }}); // Here you can chain other jQuery methods to your selector
your selectors will dynamically listen to window scroll
and resize
but also return the initial value on DOM ready trough the first callback function argument px
.
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);
edit - small update to also perform the logic when the window is being resized.
Here is a version of Rory's approach above, except written to function as a jQuery plugin. It may have more general applicability in that format. Great answer, Rory - thanks!
$.fn.visibleHeight = function() { var elBottom, elTop, scrollBot, scrollTop, visibleBottom, visibleTop; scrollTop = $(window).scrollTop(); scrollBot = scrollTop + $(window).height(); elTop = this.offset().top; elBottom = elTop + this.outerHeight(); visibleTop = elTop < scrollTop ? scrollTop : elTop; visibleBottom = elBottom > scrollBot ? scrollBot : elBottom; return visibleBottom - visibleTop}
Can be called with the following:
$("#myDiv").visibleHeight();