Reputation: 1860
I am using this plugin - isOnScreen to check whether an element is visible on the viewport (to check if posts has been viewed or not).
But is it possible to have a callback of some sort so that instead of having a setTimeOut and checking the visibility of each and every post every time, fire a callback when the respective element is visible?
Or is there any other library I can use to do this?
I am talking about the visual viewport. (Not css visibility)
Upvotes: 5
Views: 14760
Reputation: 199
There are mainly two ways to check if an element is visible/hidden on the screen during scrolling:
Scroll events have a lot of performance issues.
The new way is using Intersection Observer API. Intersection Observer API makes it possible to know when an element enters or exits the browser viewport. This API is asynchronous
var observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting === true)
console.log('Element is fully visible in screen');
}, { threshold: [1] });
observer.observe(document.querySelector("#element"));
Threshold is a number between 0 and 1, that represents the viewable area of the target element in the screen. For example, 0 represents no area of element is visible. A value of 0.10 represents about 10% area is viewable in the screen. Value of 1 means element is fully viewable in the screen.
Upvotes: 5
Reputation: 6162
I recently worked on a small library that checks when an element is on the viewport called viewport-action. It could be handy for cases like yours.
Feel details to consider:
DOMContentLoaded
event in browsers or deviceready
in Cordova apps before starting checking for elements (in case it's a Cordova app).Promise
(yet) to support applications without it and older browsers.See the example below where it checks for how much of the element is shown based on percentage.
var options = {
once: true
};
viewportAction.add('#check', function (e) {
var percentageShown = (e.detail.availableArea / (e.detail.width * e.detail.height)) * 100;
// Load an image inside the element when the area visible is bigger
// than 60% of its area.
if (percentageShown > 60) {
e.target.innerText = 'Showing ' + percentageShown.toFixed(0) + '% of the element';
// Remove handler if you don't want to use options
// e.removeHandler();
} else {
e.target.innerText = 'Showing less than 60%';
}
// Use options, optionally
//}, options);
});
#check {
background-color: #F00;
color: #FFF;
height:500px;
width; 100%;
}
.spacer {
background-color: #CCC;
height: 300px;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/viewportAction.min.js"></script>
<div class="spacer">Scroll down or up</div>
<div id="check"></div>
<div class="spacer"></div>
Upvotes: 0
Reputation: 276266
Here is a script returning a promise using the new IntersectionObserver
API for checking whether or not an element is actually visible in the viewport:
function isVisible(domElement) {
return new Promise(resolve => {
const o = new IntersectionObserver(([entry]) => {
resolve(entry.intersectionRatio === 1);
o.disconnect();
});
o.observe(domElement);
});
}
Which you can use in your code:
const visible = await isVisible(document.querySelector('#myElement'));
console.log(visible);
Upvotes: 21