DEV Community

Narender Saini
Narender Saini

Posted on

How to check an element is in viewport

How to check an element is in viewport

So, maybe you already have seen the case where developer need to check an element (div) is currently visible to user or not. For solving this problem there is a lot of npm packages available but what if we don’t want to use them. In this article we will gonna learn how to check an element is in viewport.

If you want to use a npm package then this will be a good one.

Problem

Let’s assume we have several elements on our page and we want to perform an operation only if a particular element is visible. To handle this problem we will gonna use our custom util function.

Solution

We will gonna create a custom util function which will gonna receive a element and then it will gonna check is it currently visible or not.

Let’s write a util function isVisible and it will gonna receive only one argument i.e element.

export const isVisible = (el) => {

};

Then we will gonna get the position of that element using getBoundingClientRect.

const rect = el.getBoundingClientRect();

Now we will gonna find window height and width.

  const vWidth = window.innerWidth || document.documentElement.clientWidth;
  const vHeight = window.innerHeight || document.documentElement.clientHeight;

We will gonna write a one more function which basically gonna receive x and y point and gonna return element using elementFromPoint function.

const efp = function (x, y) { return document.elementFromPoint(x, y); };

Then we will gonna check our element is inside or not of window.

  // Return false if it's not in the viewport
  if (rect.right < 0 || rect.bottom < 0
            || rect.left > vWidth || rect.top > vHeight) { return false; }

Check is any corner is visible.

// Return true if any of its four corners are visible
  return (
    el.contains(efp(rect.left, rect.top))
      || el.contains(efp(rect.right, rect.top))
      || el.contains(efp(rect.right, rect.bottom))
      || el.contains(efp(rect.left, rect.bottom))
  );

Full function will gonna look like this.

export const isVisible = (el) => {
  const rect = el.getBoundingClientRect();
  const vWidth = window.innerWidth || document.documentElement.clientWidth;
  const vHeight = window.innerHeight || document.documentElement.clientHeight;
  const efp = function (x, y) { return document.elementFromPoint(x, y); };

  // Return false if it's not in the viewport
  if (rect.right < 0 || rect.bottom < 0
            || rect.left > vWidth || rect.top > vHeight) { return false; }

  // Return true if any of its four corners are visible
  return (
    el.contains(efp(rect.left, rect.top))
      || el.contains(efp(rect.right, rect.top))
      || el.contains(efp(rect.right, rect.bottom))
      || el.contains(efp(rect.left, rect.bottom))
  );
};

Usage

import { isVisible } from '../utils';

.....
const ele = document.getElementById(id);
return isVisible(ele);

I hope you have learned how to check an element is in viewport.

Top comments (1)

Collapse
 
myogeshchavan97 profile image
Yogesh Chavan

There is even an easy way using Intersection Observer JavaScript API. Check out this article to understand how it works