0

So in order to check if the user has scrolled at all I found that I can use:

@HostListener("window:scroll", [])
onWindowScroll() {
    this.scrolled = window.scrollY > 0;
}

This works well for the first paragraph after the user scrolls "below-the-fold" (I trigger an animation by adding a css class to a text div).

However how can I repeat the same thing for when a user scrolls past the "second" fold and goes into the third? I want to add the css class to make the text appear every time the user can see it (i.e. he has scrolled enough as in >= some threshold in pixels I need to find) and remove it when the user can't see the div (i.e. he scrolled back up).

How can I do that in Typescript / Angular?

Michael
  • 325
  • 3
  • 14
  • Take a look at using the Intersection Observer: https://stackoverflow.com/questions/67272516/intersection-observer-in-angular – first last Feb 14 '22 at 13:03
  • 2
    Here is already a answer to this Question: https://stackoverflow.com/questions/49215634/angular-check-when-an-element-is-in-view – Daniel Ehrhardt Feb 14 '22 at 13:14

1 Answers1

0

I ended up using the function from the answer here: Check if element is partially in viewport

  @ViewChild("targetDivId", {static: false}) private targetDiv: ElementRef<HTMLDivElement>;

  @HostListener('window:scroll', ['$event'])
  isScrolledIntoView(){
    const isElementXPercentInViewport = function(el: ElementRef, percentVisible=0.5) {
      // https://stackoverflow.com/questions/30943662/check-if-element-is-partially-in-viewport/51121566#51121566
      let
        rect = el.nativeElement.getBoundingClientRect(),
        windowHeight = (window.innerHeight || document.documentElement.clientHeight);
      return !(
        Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-rect.height) * 100)) < percentVisible ||
        Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
      )
    };

    if (this.targetDiv){
      this.scrolled = isElementXPercentInViewport(this.targetDiv);
    }

Very flexible. Would recommend.

Michael
  • 325
  • 3
  • 14