typescript - Angular 2 - Div tarayıcı üstüne ulaştığında bir sınıf ekleme


<div class="main-menu-wrapper home-menu **class to be added here**" >
      <div class="main-menu-inner">
          <a href="#" class="home-logo">
              <i class="logo"></i>

div tarayıcının üstüne ulaştığında bir sınıf eklemem gerekiyor,

Gereksinim, her div üstteye ulaştığında animasyonu başlatmaktır. (Bu, sabitleme yapılan tek sayfalık bir web sitesidir)

angular 2'de bu nasıl yapılabilir;

Cevap #1

Angular'ın HostListener adında bir fonksiyon dekoratörü vardır ve bir olay adını argüman olarak kabul eder. O olay ana (host) element üzerinde tetiklendiğinde ilgili fonksiyonu çağırır. Bunu bir elementin tarayıcıda en üste ulaştığını tespit etmek için kullanabiliriz.

  @ViewChild('componentDiv') componentDiv: ElementRef;

  @HostListener('window:scroll', [])
  onWindowScroll() {
    const element = this.componentDiv.nativeElement;
    const viewportOffset = element.getBoundingClientRect();
    const top = viewportOffset.top;
    if (top <= 0) {
        // Do something
    }
  }

HTML şablonu şöyle bir şey olabilir

<div style="border: solid 1px black" #componentDiv>
  <p>
    Angular is here.
  </p>
</div>

Cevap #2

Kullanmak istediğiniz sınıfı başa ve animasyon yapmak istediğiniz öğelerin sınıfını ekleyin. Sonra dinlemeye başlamak için get() metodunu çağırın. Bu, verilen sınıfa sahip tüm öğelerin bir listesini oluşturacak ve kaydırma sırasında öğelerin üst kısma yakın olup olmadığını kontrol edecektir; eğer öyleyse belirttiğiniz sınıfı ekleyecek ve öğeyi listeden çıkaracaktır. Liste boşaldığında, dinleyicileri kaldıracaktır. Bu tek seferlik bir animasyondur.

import { NgZone } from '@angular/core';

  constructor(
    private ngzone: NgZone
  ) { }

  ngAfterViewInit() {
    // call the listener when you are ready
    this.animateElements.get();
  }

  ngOnDestroy() {
    // don't forget to clear your listeners
    this.ngzone.runOutsideAngular(() => {
      window.removeEventListener('scroll', this.floatingHeader.scroll, true);
    });
  }

  public animateElements = {
    classToAdd: 'active', // will add this class
    classToListenFor: 'myClass', // listen for these elements
    elements: <any>[],
    get: ():void => {
      // run outside angular to prevent change detection on every scroll
      this.ngzone.runOutsideAngular(() => {
        window.addEventListener('scroll', this.animateElements.scroll, true);
      });
      let elements:any = document.getElementsByClassName(this.animateElements.classToListenFor);
      // let angular a moment to build and select the html
      new Promise((resolve) => {
        if (elements) {
          resolve();
        }
      }).then(() => {
        Object.keys(elements).forEach((key:any) => {
          let obj = {
            offset: elements[key].offsetTop,
            element: elements[key]
          }
          this.animateElements.elements.push(obj);
          this.animateElements.check(obj);
        });
      });
    },
    check: (e):void => {
      if ((window.pageYOffset + window.innerHeight) >= e.offset) {
        e.element.classList.add(this.animateElements.classToAdd);
        this.animateElements.elements.splice(this.animateElements.elements.findIndex(row => {
          return row == e;
        }), 1);
      }
    },
    scroll: ():void => {
      if (this.animateElements.elements.length <= 0) {
        window.removeEventListener('scroll', this.animateElements.scroll, true);
        return;
      }
      this.animateElements.elements.forEach(e => {
        this.animateElements.check(e);
      });
    }
  }