,

Wzorzec obserwatora w Javascripcie

Wzorzec obserwatora jest bardzo prosty. W swoim założeniu polega na tym, że jeden obiekt powiadamia inne obiekty o swojej zmianie. W JavaScript istnieją predefiniowane observators, które ułatwiają życie programistom.

MutationObserver

Pozwala na śledzenie zmian, takich jak zmiana atrybutów czy dodanie nowego węzła w strukturze DOM.

Konstruktor klasy MutationObserver przyjmuje jako parametr callback. Callback z kolei otrzyma tablicę z obiektami MutationRecord oraz jako drugi parametr instancję MutationObserver.

Aby rozpocząć obserwację, należy wywołać metodę observe, która jako argumenty przyjmuje Node (np. HTMLElement) oraz konfigurację.

Przykład

Załóżmy, że mamy pole tekstowe i chcemy zliczać ilość znaków.

function mutationObserverCallback(mutations) {
  mutations.forEach((mutation) => {
    if (mutation.type === 'characterData') {
      updateCounter(mutation.target.value.length);
    }
  });
}

function updateCounter(length) {
  document.getElementById('char-counter')?.innerText = length;
}

const observeConfig = {
  characterData: true,
};

(new MutationObserver(mutationObserverCallback))
  .observe(document.getElementById('text-area'), observeConfig);

Code language: JavaScript (javascript)

Przy wprowadzaniu tekstu do textarea za każdym razem będzie aktualizowana wartość w elemencie #char-counter.

IntersectionObserver

Stałym problemem we frontend developmencie od zawsze było ustalenie, czy dany element jest widoczny w obszarze użytkownika, czy nie. Stara szkoła uczyła, aby nasłuchiwać zdarzenia scroll, a następnie ustalać przesunięcie elementu względem góry dokumentu i przesunięcia. Było to obciążające zadanie, zwłaszcza gdy musieliśmy śledzić wiele takich elementów w ogromnej strukturze DOM. Ten problem rozwiązuje IntersectionObserver.

Podobnie jak inne interfejsy, konstruktor IntersectionObserver przyjmuje Callback, który reaguje na zmiany oraz konfigurację. Callback przyjmuje tablicę IntersectionObserverEntry oraz instancję obserwatora.

Do uruchomienia obserwacji służy metoda observe, która jako argument przyjmuje obiekt dziedziczący po Element.

Przykład

Załóżmy, że chcemy wykrywać elementy .ad, w których występują reklamy.

function itersectionObserverCallback(entries) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('Element jest widoczny');
    } else {
      console.log('Element jest poza obszarem widzenia');
    }
  });
}

// konfiguracja domyślna
const observer = new IntersectionObserver(itersectionObserverCallback);

document.querySelectorAll('.ad').forEach(element => observer.observe(element));Code language: JavaScript (javascript)

Kod wybierze wszystkie elementy z klasą .ad i zacznie je obserwować. Gdy znikną lub pojawią się na ekranie, w konsoli zostanie zalogowany odpowiedni komunikat.

ResizeObserver

Ostatnim prezentowanym dzisiaj obserwatorem jest ResizeObserver i służy do obserwowania rozmiaru elementu. Chociaż większość zadań związanych z rozmiarem można wykonać za pomocą media query, czasem istnieją specyficzne przypadki, kiedy ResizeObserver znajdzie zastosowanie.

Konstruktor jako parametr otrzymuje Callback, który przyjmuje dwa argumenty: tablicę z ResizeObserverEntry oraz instancję obserwatora.

Do zainicjowania obserwacji służy metoda observe, która jako argument przyjmuje obiekt dziedziczący po Element oraz konfigurację. W chwili pisania tego artykułu, konfiguracja ma tylko jedną właściwość box z możliwymi parametrami: border-box, content-box, device-pixel-content-box.

Przykład

Załóżmy, że na stronie znajdują się reklamy, które są pobierane dynamicznie. Zanim zostaną pobrane i wyświetlany jest obraz zastępczy. Chcemy dynamicznie zamieniać obraz zastępczy z prawdziwą reklamą.

function resizeObserverCallback(entries, observer) {
  entries.forEach(entry => {
    if (entry.contentRect.height > 20) {
      entry.target.nextElementSibling.remove();
      observer.unsubscribe(entry.target);
    }
  });
}

const observer = new ResizeObserver(resizeObserverCallback);

document.querySelectorAll('.ad').forEach(element => observer.observe(element));Code language: JavaScript (javascript)


Jeśli reklama będzie miała wysokość większą niż 20px, wtedy zostanie usunięty element występujący po nim. W naszym przykładzie jest to domyślna reklama. Zadbaliśmy również o zaprzestanie obserwacji na elemencie .ad, gdy reklama zostanie wyświetlona.

Podsumowanie

Observators w JavaScript to potężne narzędzia, które pozwalają wprowadzić jeszcze lepszą interakcję z stroną internetową. Jednak niewłaściwe lub nadmierne ich stosowanie może pogorszyć wydajność. Dlatego powinny być stosowane z ostrożnością, a konfiguracja powinna być dostosowana do wymagań.

Nasza pasja do technologii nie kończy się na dostarczaniu wnikliwych treści poprzez ten blog. Zapraszamy po więcej tajników specjalistycznej wiedzy dla entuzjastów takich jak Ty.

Tematy

animacje animate Attribute inheritance Block Theme Branża IT bug Code Comments CSS CSS Flexbox developer tools Doc Blocks dostępność www Edge Edge computing Editor Flex Gap FSE Full Site Editing GIT GIT Submodules Gutenberg HTTP HTTP/2 HTTP/3 IT JS Memcached Optimization plik SVG Praca praca w IT Rozmowy o WordPress strony www SVG Text-overflow theme.json v-model Vue.js wcag web accessibility Web development webkit line clamp Wordpress wp postmeta api wp transient