Home > Enterprise >  .getBoundingClientRect() not changing values on scroll
.getBoundingClientRect() not changing values on scroll

Time:09-14

I am trying to make a side pagination bar, and I want it to change colors when different parts of the page come into view, so I am using the .getBoundingClientRect in javascript. However, everytime I scroll, the position of the element is the same in the console logs, even if I have scrolled all the way to the bottom.

Can someone help me so that the values change when they are meant to?

var aboutPage = document.getElementById('about');
var aboutBounding = aboutPage.getBoundingClientRect();

window.addEventListener("scroll", () => {

    console.log(aboutBounding);

    if (
        aboutBounding.top >= 0 &&
        aboutBounding.left >= 0 &&
        aboutBounding.right <= (window.innerWidth || document.documentElement.clientWidth) &&
        aboutBounding.bottom <= (window.innerHeight || document.documentElement.clientHeight)
    ) {
        console.log('In the viewport!');
    } else {
        console.log('Not in the viewport... whomp whomp');
    }
})
/* SIDE PAGEINTATION */

.side-pagination {
  position: fixed;
  top: 50%;
  left: 72px;
  height: 138px;
  width: 24px;
  transform: translateY(-50%);
  z-index: 10;
}

.page-circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: #bcbcbc;
  cursor: pointer;
}

.page-circle.menuactive {
  background-color: var(--secondary-clr);
}

.page-circle:nth-child(1) {
  margin-bottom: 14px;
}

.page-circle:nth-child(2) {
  margin-bottom: 14px;
}

.page-circle:nth-child(3) {
  margin-bottom: 14px;
}

.landing-main-body {
  position: absolute;
  top: 0%;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  background-color: gray;
}

.work-main-body {
  position: absolute;
  top: 200%;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  background-color: pink;
}

.about-main-body {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  background-color: purple;
}
<div >
  <div ></div>
  <div ></div>
  <div ></div>
</div>
<div >
</div>
<div  id="about">

</div>
<div  id="work">

</div>

EDIT: I will try using IntersectionObserver in the morning, stay put till then :D.

CodePudding user response:

When you store the getBoundingClientRect value outside the scroll event listener, you're only storing the rect value once. In other words, it won't update as the scroll event fires.

You need to read the getBoundingClientRect value inside the scroll event listener like so:

var aboutPage = document.getElementById('about');
// var aboutBounding = aboutPage.getBoundingClientRect(); <-- Don't read it here

window.addEventListener("scroll", () => {

    var aboutBounding = aboutPage.getBoundingClientRect(); // <-- Read it inside the scroll listener
    console.log(aboutBounding);

    if (
        aboutBounding.top >= 0 &&
        aboutBounding.left >= 0 &&
        aboutBounding.right <= (window.innerWidth || document.documentElement.clientWidth) &&
        aboutBounding.bottom <= (window.innerHeight || document.documentElement.clientHeight)
    ) {
        console.log('In the viewport!');
    } else {
        console.log('Not in the viewport... whomp whomp');
    }
})

CodePudding user response:

getBoundingClientRect() is not reactive. You get the result of the read operation (at the point in time when you read the value).

By placing

var aboutBounding = aboutPage.getBoundingClientRect();

outside of the function, aboutBounding will remain the same value it was when it was read.

Move that line inside the function which performs on every scroll event and it will start working.

  • Related