Sometimes it's super-handy to know just how far inside the viewport your elements are; at least, it was for me, and so a plugin was born.
PercentWithinViewport is a tiny (640b minified) plugin that you can call just once, or as many times within any event, to find all matching elements within the viewport and simultaneously grant them a data attribute representing a percentage of far they are inside the viewport; and report back an array of all matching elements that are currently visible. It's as simple as:
$('.element').percentWithinViewport();
If you want to do something with all of the elements that are visible within the viewport, then just grab that array:
var elementsInViewport = $('.element').percentWithinViewport();
PercentWithinViewport also accepts an object of parameters, including offsetTop
, offsetBottom
,
offsetTopElement
& offsetBottomElement
. This means you can set a fixed offset from either the top or the bottom;
or set a jQuery DOM element for either the top or the bottom (for example, a fixed header or footer) and let the plugin do the rest:
var elementsInViewport = $('.element').percentWithinViewport({ 'offsetTopElement': $('#header.fixed') });
Scroll down to see the plugin in action. In this example, $('.percentage-box').percentWithinViewport();
is being called within a
$(window).scroll()
event and updating the elements every time the page is scrolled. Note that, if you don't need to know the figures
constantly (or if it's too intensive), I would recommend looking at Ross Allen's scrollStop
instead of using the window scroll event.
The heights of each box are random; refresh the page to change them. Use the handy control panel to change the plugin options on the fly.
$(window).on('scroll', function(e) {
var withinViewportArray = $('.percentage-box').percentWithinViewport({'offsetTopElement': $('#header')});
$.each(withinViewportArray, function(index) {
var myPercVisible = parseInt($(this).attr('data-percent-viewport'));
$(this).css({'opacity': myPercVisible / 100});
$(this).find('.percentage').text(myPercVisible + '%');
});
}).trigger('scroll');
At a minimum, PercentWithinViewport requires jQuery 1.6.0 to be included.
var elementsInViewport = $('.element').percentWithinViewport({
'offsetTop': 100,
'offsetTopElement': $('#header'),
'offsetBottom': 100,
'offsetBottomElement': $('#footer')
});
offsetTop
(int) The amount of offset, in pixels, from the top of the viewport
offsetTopElement
(jQuery DOM element) Calculates the outerHeight()
and uses that as the offset
from the top of the viewport. Best used for fixed
elements.
offsetTop
(int) The amount of offset, in pixels, from the bottom of the viewport.
offsetBottomElement
(jQuery DOM element) Calculates the outerHeight()
and uses that as the offset
from the bottom of the viewport. Best used for fixed
elements.
(Array) An array of all matching elements that have more than 0% of themselves within the viewport. Will return an empty array if no elements matching conditions are found.
The parameters are cumulative. So, if you have a header that is 100px
in height and set a top offset of 150px
, like so:
var elementsInViewport = $('.element').percentWithinViewport({
'offsetTop': 150,
'offsetTopElement': $('#header.height-100')
});
...then your total offset from the top of the viewport will be 250px
.