Home > database >  How to apply this function to an array without reusing all elements
How to apply this function to an array without reusing all elements

Time:09-05

I'm fairly new to programming and I'm working on a project,


HTML

<div >
        <span><h2 >Text1</h2></span>
        <span
          ><h2 >Text2</h2></span
        >
        <span
          ><h2 >Text3</h2></span
        >
        <span
          ><h2 >text4</h2></span
        >
        <span><h2 >text5</h2></span>
        <span><h2 >text6</h2></span>
        <span><h2 >text7</h2></span>
        <span><h2 >text8</h2></span>
        <span><h2 >text9</h2></span>
</div>

JavaScript

// Check if is in viewport & animate
      const headers2 = document.querySelector(".twoH");
      function elementInViewportTWO() {
        let bounding = headers2.getBoundingClientRect();

        if (
          bounding.top >= 0 &&
          bounding.left >= 0 &&
          bounding.right <=
            (window.innerWidth || document.documentElement.clientWidth) &&
          bounding.bottom <=
            (window.innerHeight || document.documentElement.clientHeight)
        ) {
          headers2.style.opacity = 1;
        } else {
          headers2.style.opacity = 0.6;
        }
      }
      setInterval(elementInViewportTWO, 10);

My questions is, how to apply this effect, given an array of 9 headings without reusing so much code, how do I make my function work with an array of elements? (My code highlights text when a certain element is in a viewport)

CodePudding user response:

Select them all with document.querySelectorAll and loop through them each time.

// Check if is in viewport & animate
      const headers = document.querySelectorAll(".animatedHeader");
      function elementsInViewport() {
        headers.forEach(header=>{
        let bounding = header.getBoundingClientRect();

        if (
          bounding.top >= 0 &&
          bounding.left >= 0 &&
          bounding.right <=
            (window.innerWidth || document.documentElement.clientWidth) &&
          bounding.bottom <=
            (window.innerHeight || document.documentElement.clientHeight)
        ) {
          header.style.opacity = 1;
        } else {
          header.style.opacity = 0.6;
        }
        })
      }
      setInterval(elementsInViewport, 10);
<div >
        <span><h2 >Text1</h2></span>
        <span
          ><h2 >Text2</h2></span
        >
        <span
          ><h2 >Text3</h2></span
        >
        <span
          ><h2 >text4</h2></span
        >
        <span><h2 >text5</h2></span>
        <span><h2 >text6</h2></span>
        <span><h2 >text7</h2></span>
        <span><h2 >text8</h2></span>
        <span><h2 >text9</h2></span>
</div>

CodePudding user response:

The function you've provided evaluates the dimensions of each .animatedHeader element every 10 milliseconds. This will make your CPU work very hard and has a high chance of hurting your site's peformance. And because of setInterval it will keep on running even if you're not interacting with the site and nothing changes.

Instead, consider using the Intersection Observer API which is specifically designed to detect if elements are within a viewport whilst keeping the performance high.

const headers = document.querySelectorAll('.animatedHeader');

const intersectionCallback = entries => {
  for (const { isIntersecting, target } of entries) {
    if (isIntersecting) {
      target.style.opacity = 1;
    } else {
      target.style.opacity = 0.6;
    }
  }
};

const observer = new IntersectionObserver(intersectionCallback);

for (const header of headers) {
  observer.observe(header);
}
  • Related