Home > Software engineering >  Intersection observer not observing specific divs/sections
Intersection observer not observing specific divs/sections

Time:12-29

Basically my intersection observer works fine on all the elements I set him to watch apart from this section. Please help

<section >

// elements
let elements_to_watch = document.querySelectorAll('.watch');
// callback 
let callback = (items) => {
  items.forEach((item) => {
    console.log(item.target.id);
    if (item.isIntersecting) {
      console.log("... now in");
      item.target.classList.add("in-page");
    } else {
      console.log("... now out");

      item.target.classList.remove("in-page");

    }
  });
}
// observer
let observer = new IntersectionObserver(callback, {
  threshold: 0.57
});
// apply
elements_to_watch.forEach((element) => {
  observer.observe(element);
});
.introduction-section {
  background-color: var(--clr-dark);
  align-items: center;
}
.introduction-title-container {
  display: flex;
  flex-grow: 1;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
.introduction-section .title {
  height: 100vh;
  font-size: calc(var(--fs-h2) * 1.2);
  color: var(--clr-light);
  text-align: center;
  max-width: 30rem;
  height: fit-content;
  margin-bottom: 0;
  top: 50%;
  left: calc(25% -20rem);
  position: fixed;

  transition: all 0.9s cubic-bezier(0.215, 0.61, 0.355, 1);
  opacity: 0;
  transform: scale(0.8);
}

.introduction-title-container.in-page .title {
  opacity: 1;
  transform: scale(1);
}
<section  id=section>
  <div  id=wrapper>
    <div  id=introduction1>
      <h2 >
        A SmartWatch is born that goes beyond all limits.
      </h2>
    </div>
    <div  id=introduction2>
      <h2 >For Athletes who challenge the impossible.</h2>
    </div>
    <div  id=introduction3>
      <h2 >The call to the Adventure begins.</h2>
    </div>
  </div>
</section>

It should change the class "watch" to "in-page" but for some reason on this section it won't do it.

As I said the watch class gets changed on the col-12 divs but not on the section, and neither the row because I tried it.

I have console logged the elements_to_watch nodelist in JS and the section was there so I don't understand why it doesnt work...

CodePudding user response:

I think I know what you want to achieve. As you are saying, you want to remove the .watch class every time your Intersection observer is passing throught the specific sections of your page. I tested the code by removing the .watch and adding the .in-page and viceversa.

Open your Google Chrome Elements and observe the DOM changing, while you navigate in and out of the specified sections. You will notice that there is a change of classes in the specific sections that possess the .watch class.

The row section won't change because you are not really applying the class .watch to it. You are only selecting DOM elements which have the class watch. I added the class to every one of the elements and it is working properly. I hope that can give you a hint.

// elements
let elements_to_watch = document.querySelectorAll('.watch');
// callback 
let callback = (items) => {
  console.log(items[0].target.id);
  items.forEach((item) => {
    if (item.isIntersecting) {
      console.log("... now in");
      item.target.classList.remove("watch");
      item.target.classList.add("in-page");
    } else {
      console.log("... now out");
      item.target.classList.add("watch");
      item.target.classList.remove("in-page");

    }
  });
}
// observer
let observer = new IntersectionObserver(callback, {
  threshold: 0.57
});
// apply
elements_to_watch.forEach((element) => {
  observer.observe(element);
});
<section  id=section>
  <div  id=wrapper>
    <div  id=introduction1>
      <h2 >
        A SmartWatch is born that goes beyond all limits.
      </h2>
    </div>
    <div  id=introduction2>
      <h2 >For Athletes who challenge the impossible.</h2>
    </div>
    <div  id=introduction3>
      <h2 >The call to the Adventure begins.</h2>
    </div>
  </div>
</section>

CodePudding user response:

OK, I see the problem now with the added CSS. I don't fully understand why, but with the fancy CSS for the "introduction" elements, the container (the <section> is MUCH bigger. Thus, getting 57% of it into the viewport takes a much larger viewport.

I don't know exactly what you want to do, but you can see what I'm talking about if you take the "watch" class off of the <section>, and then make a new IntersectionObserver with a smaller threshold (like 0.20 maybe), and observe the section (using the same callback) with that observer.

So, with the "watch" removed from the <section>, the JavaScript would be:

// observer for each heading
let observer = new IntersectionObserver(callback, {
  threshold: 0.57
});
// apply
elements_to_watch.forEach((element) => {
  observer.observe(element);
});
// observer for section container
observer = new IntersectionObserver(callback, {
  threshold: 0.20
});
observer.observe(document.getElementById("section"));
  • Related