Zbliżamy się do IntersectionObserver

Komponent IntersectionObservers informuje, gdy obserwowany element pojawia się w widocznym obszarze przeglądarki lub go opuszcza.

Obsługa przeglądarek

  • 51
  • 15
  • 55
  • 12.1

Źródło

Załóżmy, że chcesz śledzić, kiedy element w modelu DOM pojawia się w widocznym widocznym obszarze. Warto to zrobić, aby w odpowiednim momencie ładować obrazy z leniwego ładowania lub aby wiedzieć, czy użytkownik faktycznie widzi określony baner reklamowy. Aby to zrobić, połącz zdarzenie przewijania lub użyj okresowego licznika czasu i wywołaj getBoundingClientRect() dla tego elementu.

To podejście jest jednak powolne, ponieważ każde wywołanie metody getBoundingClientRect() wymusza na przeglądarce przekładanie całej strony i wprowadza w witrynie spore zacięcie. Sprawy stają się niemal niemożliwe, gdy wiesz, że witryna jest wczytywana w elemencie iframe, a chcesz wiedzieć, kiedy użytkownik widzi dany element. Pojedynczy model źródłowy i przeglądarka nie pozwalają na dostęp do żadnych danych ze strony internetowej zawierającej element iframe. Jest to typowy problem np. w przypadku reklam, które są często ładowane za pomocą elementów iframe.

Do czego stworzyliśmy narzędzie IntersectionObserver, aby zwiększyć efektywność testu widoczności. Teraz działa on we wszystkich nowoczesnych przeglądarkach. IntersectionObserver informuje, kiedy obserwowany element pojawia się w widocznym obszarze przeglądarki lub kiedy z niego wychodzi.

Widoczność elementów iframe

Jak utworzyć IntersectionObserver

Interfejs API jest dosyć mały i najlepiej go opisać na przykładzie:

const io = new IntersectionObserver(entries => {
  console.log(entries);
}, {
  /* Using default options. Details below */
});

// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();

W przypadku domyślnych opcji IntersectionObserver wywołanie zwrotne będzie wywoływane zarówno wtedy, gdy element wyświetla się częściowo, jak i gdy całkowicie opuści widoczny obszar.

Jeśli musisz obserwować wiele elementów, możesz to robić. Zalecamy obserwowanie wielu elementów przy użyciu tego samego wystąpienia IntersectionObserver, wywołując metodę observe() wielokrotnie.

Parametr entries jest przekazywany do wywołania zwrotnego, które jest tablicą obiektów IntersectionObserverEntry. Każdy taki obiekt zawiera zaktualizowane dane skrzyżowań jednego z zaobserwowanych elementów.

🔽[IntersectionObserverEntry]
    time: 3893.92
    🔽rootBounds: ClientRect
        bottom: 920
        height: 1024
        left: 0
        right: 1024
        top: 0
        width: 920
    🔽boundingClientRect: ClientRect
    // ...
    🔽intersectionRect: ClientRect
    // ...
    intersectionRatio: 0.54
    🔽target: div#observee
    // ...

Wynik rootBounds jest wynikiem wywołania metody getBoundingClientRect() w elemencie głównym, który jest domyślnie widocznym obszarem. boundingClientRect jest wynikiem wywołania funkcji getBoundingClientRect() w obserwowanym elemencie. intersectionRect to przecięcie tych 2 prostokątów i w praktyce wskazuje, którą część zaobserwowanego elementu jest widoczna. intersectionRatio jest blisko ze sobą powiązany i informuje, jaka część elementu jest widoczna. Dysponując tymi informacjami, możesz teraz wdrożyć takie funkcje, jak automatyczne wczytywanie zasobów, zanim pojawią się one na ekranie. Wydajnie.

Współczynnik przecięcia.

Sieci IntersectionObserver dostarczają dane asynchronicznie, a kod wywołania zwrotnego jest uruchamiany w wątku głównym. Dodatkowo specyfikacja wskazuje, że implementacje IntersectionObserver powinny używać tagu requestIdleCallback(). Oznacza to, że wywołanie podanego wywołania zwrotnego ma niski priorytet i zostanie wykonane przez przeglądarkę w czasie bezczynności. To świadoma decyzja dotycząca projektu.

Przewijane elementy div

Nie przepadam za przewijaniem treści w elemencie, ale nie chcę tu niczego oceniać, podobnie jak IntersectionObserver. Obiekt options przyjmuje opcję root, która umożliwia zdefiniowanie jako poziomu głównego alternatywy dla widocznego obszaru. Pamiętaj, że element root musi być elementem nadrzędnym wszystkich obserwowanych elementów.

Połącz te elementy.

Nie! Niegrzeczny programista. Nie jest to świadome wykorzystanie cykli procesora przez użytkownika. Weźmy na przykład nieskończone przewijanie. W takiej sytuacji zdecydowanie zalecamy dodanie do DOM wartowników i ich obserwację (i ich recykling). Pamiętaj, by dodać czujnik blisko ostatniego elementu w przewijaniu nieskończonym. Gdy pojawi się komunikat, możesz użyć wywołania zwrotnego, by wczytać dane, utworzyć następne elementy, dołączyć je do DOM i odpowiednio zmienić pozycję nadawcy. Jeśli prawidłowo poddasz recykling, nie jest wymagane żadne dodatkowe wywołanie metody observe(). IntersectionObserver działa dalej.

Przewijanie nieskończone

Prosimy o więcej informacji

Jak już wspomnieliśmy, wywołanie zwrotne będzie się uruchamiać raz, gdy obserwowany element znajdzie się częściowo w widocznym obszarze, a drugi raz, gdy znajdzie się on poza widocznym obszarem. Dzięki temu IntersectionObserver uzyskasz odpowiedź na pytanie „Czy element X jest widoczny?”. W niektórych przypadkach może to jednak nie wystarczyć.

W tym celu warto skorzystać z opcji threshold. Pozwala zdefiniować tablicę progów intersectionRatio. Wywołanie zwrotne będzie wykonywane za każdym razem, gdy intersectionRatio przekroczy jedną z tych wartości. Domyślna wartość dla threshold to [0], która objaśnia domyślne działanie. Jeśli zmienimy threshold na [0, 0.25, 0.5, 0.75, 1], będziemy otrzymywać powiadomienie za każdym razem, gdy pojawi się dodatkowa ćwierć elementu:

Animacja progu.

Czy są jakieś inne opcje?

Obecnie oprócz powyższych opcji jest dostępnych tylko 1 dodatkowa opcja. rootMargin umożliwia określanie marginesów elementu głównego, dzięki czemu można zwiększać lub zmniejszać obszar używany na skrzyżowaniach. Marginesy te są określane za pomocą ciągu znaków w stylu CSS á la "10px 20px 30px 40px", określającego odpowiednio górny, prawy, dolny i lewy margines. Podsumowując, struktura opcji IntersectionObserver obejmuje te opcje:

new IntersectionObserver(entries => {/* … */}, {
  // The root to use for intersection.
  // If not provided, use the top-level document's viewport.
  root: null,
  // Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
  // If an explicit root element is specified, components may be percentages of the
  // root element size.  If no explicit root element is specified, using a
  // percentage is an error.
  rootMargin: "0px",
  // Threshold(s) at which to trigger callback, specified as a ratio, or list of
  // ratios, of (visible area / total area) of the observed element (hence all
  // entries must be in the range [0, 1]).  Callback will be invoked when the
  // visible ratio of the observed element crosses a threshold in the list.
  threshold: [0],
});

Magia <iframe>

Elementy IntersectionObserver zostały zaprojektowane specjalnie z myślą o usługach reklamowych i widżetach sieci społecznościowych, które często korzystają z elementów <iframe> i mogą być przydatne, jeśli wiadomo, czy są widoczne. Jeśli <iframe> wykryje jeden z jego elementów, zarówno przewinięcie elementu <iframe>, jak i przewinięcie okna zawierającego element <iframe> spowoduje wywołanie zwrotne w odpowiednich momentach. W drugim przypadku zasada rootBounds ma jednak wartość null, aby uniknąć wycieku danych między źródłami.

Czego IntersectionObserver nie dotyczy?

Pamiętaj, że IntersectionObserver nie celowo nie ma idealnych pikseli ani nie ma małego opóźnienia. Korzystanie z nich w takich zadaniach jak animacje zależne od przewijania z pewnym prawdopodobieństwem zakończy się niepowodzeniem, ponieważ dane staną się nieaktualne w chwili ich użycia. Wyjaśnienie zawiera więcej informacji o pierwotnych przypadkach użycia właściwości IntersectionObserver.

Ile mogę jeszcze zrobić w trakcie oddzwonienia?

Short 'n Sweet: zbyt wiele czasu na oddzwonienie spowoduje opóźnienie aplikacji – obowiązują wszystkie typowe metody.

Idźcie dalej i przecinajcie swoje elementy

Przeglądarka IntersectionObserver jest dobrze obsługiwana, ponieważ działa we wszystkich nowoczesnych przeglądarkach. W razie potrzeby można użyć kodu polyfill w starszych przeglądarkach. Znajdziesz go w repozytorium WICG. Oczywiście nie przyniesie to korzyści związanych z wydajnością, które zapewnia implementacja kodu polyfill.

Możesz już zacząć korzystać z IntersectionObserver. Powiedz nam, jaki był pomysł.