How to check if element is visible after scrolling?
I'm loading elements via AJAX. Some of them are only visible if you scroll down the page. Is there any way I can know if an element is now in the visible part of the page?
This should do the trick:
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
Simple Utility Function This will allow you to call a utility function that accepts the element you're looking for and if you want the element to be fully in view or partially.
function Utils() {
}
Utils.prototype = {
constructor: Utils,
isElementInView: function (element, fullyInView) {
var pageTop = $(window).scrollTop();
var pageBottom = pageTop + $(window).height();
var elementTop = $(element).offset().top;
var elementBottom = elementTop + $(element).height();
if (fullyInView === true) {
return ((pageTop < elementTop) && (pageBottom > elementBottom));
} else {
return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
}
}
};
var Utils = new Utils();
Usage
var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);
if (isElementInView) {
console.log('in view');
} else {
console.log('out of view');
}
This answer in Vanilla:
function isScrolledIntoView(el) {
var rect = el.getBoundingClientRect();
var elemTop = rect.top;
var elemBottom = rect.bottom;
// Only completely visible elements return true:
var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
// Partially visible elements return true:
//isVisible = elemTop < window.innerHeight && elemBottom >= 0;
return isVisible;
}
Update: use IntersectionObserver
The best method I have found so far is the jQuery appear plugin. Works like a charm.
Mimics a custom "appear" event, which fires when an element scrolls into view or otherwise becomes visible to the user.
$('#foo').appear(function() { $(this).text('Hello world'); });
This plugin can be used to prevent unnecessary requests for content that's hidden or outside the viewable area.
Using IntersectionObserver API
(native in modern browsers)
It's easy & efficient to determine if an element is visible in the viewport, or in any scrollable container, by using an observer.
The need to attach a scroll
event and manually checking on the event callback is eliminated, which is more efficient:
// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
root: null, // default is the viewport
threshold: .5 // percentage of taregt's visible area. Triggers "onIntersection"
})
// callback is called on intersection change
function onIntersection(entries, opts){
entries.forEach(entry =>
entry.target.classList.toggle('visible', entry.isIntersecting)
)
}
// Use the bserver to observe an element
observer.observe( document.querySelector('.box') )
// To stop observing:
// observer.unobserve(entry.target)
span{ position:fixed; top:0; left:0; }
.box{ width:100px; height:100px; background:red; margin:1000px; transition:.75s; }
.box.visible{ background:green; border-radius:50%; }
<span>Scroll both Vertically & Horizontally...</span>
<div class='box'></div>