When an element is in the viewport, it appears in the visible part of the screen.
To check if an element is visible in the viewport, you use the following isInViewport()
helper function:
function isInViewport(element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
If the element is in the viewport, the function returns true
. Otherwise, it returns false
.
Checking if an element is visible in the viewport has many applications, for example:
- Perform lazy loading images. You only load the image if its container is visible in the current viewport. This increases the loading speed of the page.
- Load a script to show the ads if it is in the viewport. This saves the advertisers a lot of money spending for impressions that users may not see the below-the-fold ads.
Let’s dive into the isInViewport()
function to understand how it works.
Getting the relative position of an element
The method element.getBoundingClientRect()
provides the element’s position and its relative position to the viewport.
It returns an object that includes element’s height, width, and its distance from the top, left, bottom, and right of the viewport.
Suppose that you have <div>
element as follows:
<div class="box"></div>
To get the <div>
element’s position in the viewport, you use the getBoundingClientRect()
method:
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
console.log(rect);
Output:
{
x: 100
y: 182
width: 300
height: 250
top: 182
right: 400
bottom: 432
left: 100
}
If the <div>
element is in the viewport, its top and left are always greater than or equal zero. In addition, its distance from the right is less than or equal to the width of the viewport, and ids distance from the bottom is less than or equal to the height of the viewport.
To get the width the height of the viewport, you use the window.innerWidth
and window.innerHeight
in modern browsers. Some browsers, however, use the document.documentElement.clientWidth
and document.documentElement.clientHeight
.
To support all browsers, you can try one and fallback to other, like this:
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
The following detects if the <div>
element is in the viewport:
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
const isInViewport = rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth);
console.log(isInViewport);
Hence, you can wrap the logic in a helper function isInViewport()
and use it as follows:
const box = document.querySelector('.box');
const result = isInViewport(box);
When you scroll the document, the box will not be in the viewport. To monitor this, you can listen to the scroll event and show the result in another div element.
The following show the HTML page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Check if an element is visible in the viewport</title>
<link rel="stylesheet" href="css/style-viewport.css">
</head>
<body>
<div class="box"></div>
<div id="message">Please scroll to check if the box is visible</div>
<script src="js/app.js"></script>
</body>
</html>
Here is the JavaScript file:
function isInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
const box = document.querySelector('.box');
const message = document.querySelector('#message');
document.addEventListener('scroll', function () {
const messageText = isInViewport(box) ?
'The box is visible in the viewport' :
'The box is not visible in the viewport';
message.textContent = messageText;
}, {
passive: true
});
Source
https://www.javascripttutorial.net/dom/css/check-if-an-element-is-visible-in-the-viewport/