Resize Observer

Pisząc aplikacje webowe, musimy dostosowywać się do mobile i desktop. Co jeśli mamy ruchome elementy na stronie i cześć strony powinna się dostosować do elementów? W takim przypadku będzie trzeba kontrolować elementy JavaScriptem.

Pierwszy sposób – kontrolowanie eventów za pomocą RxJS

Pierwszy event, jaki nasuwa się nam na myśl, jest rozszerzanie okna window. Zakładając, że na stronie są 2 kolumny, możemy znaleźć kolejny event. Jest nim poszerzanie lub zwężanie jednej z kolumn:

  • resize$ – zmiana wielkości okna window
  • drag$ – zmiana wielkości kolumny na stronie Żeby poprawić czytelność, sprowadźmy je do jednej zmiennej.
const layoutChange$ = merge(drag$, resize$);

Teraz już możemy stworzyć główną część kodu. Będziemy potrzebowali zainicjalizować start. Posłuży nam funkcja z RxJS of(). Żeby zoptymalizować działanie przeglądarki, należy ograniczyć w czasie nasz obiekt Observable. Wykorzystam do tego 2 operatory debounceTime() i throttleTime().

merge(
  of(null).pipe(startWith(null)),
  layoutForceChange$.pipe(debounceTime(100)),
  layoutForceChange$.pipe(throttleTime(100))
)

Dzięki takiej zmiennej Observable możemy dostosowywać stronę do swoich potrzeb.

Drugi wybór, nowocześniejszy – ResizeObserver

Lepszym wyborem będzie sprowadzenie kodu z RxJs do jednej funkcji. Może by tak użyć czegoś gotowego z przeglądarki? Oczywiście możemy użyć ResizeObserver. API jest zgodne z większością nowoczesnych przeglądarek. Przy tworzeniu obiektu jako pierwszy argument podajemy funkcje, który będzie się wykonywała gdy zaobserwowane elementy HTML będą się zmieniały wielkość. Następnie z utworzonym obiektem należy zaobserwować konkretny obiekt HTML, a gdy już nie będziemy potrzebowali go, należy go od obserwować.

export class ExampleComponent implements OnInit, OnDestroy {
  observer;

  constructor(private elemRef: ElementRef) {}

  ngOnInit() {
    this.observer = new ResizeObserver(() => {
      // do something
    });

    this.observer.observe(this.elemRef.nativeElement);
  }

  ngOnDestroy() {
    this.observer.unobserve(this.elemRef.nativeElement);
  }
}

Powyżej przedstawiłem przykład użycia ResizeObserver w komponencie Angularowym.

Podsumowanie

Wykorzystanie responsywaności inaczej niż na obiekcie window daje nam więcej możliwości. Przy okazji poprawia nam się UX i UI naszej strony. Niestety nie możemy tego dokonać bez użycia JS.

Copyright © 2021 DevLuk