Dowiedz się, w jaki sposób w Chrome DevTools możesz debugować zmiany w HTML

Spis treści

  1. Wprowadzenie
  2. Zatrzymywanie się na modyfikacji HTML
    1. Modyfikacja wewnątrz elementu
    2. Modyfikacja atrybutu elementu
    3. Usunięcie elementu
    4. Kod w repozytorium Github
  3. React – zatrzymywanie się na modyfikacji HTML
    1. Kod w repozytorium Github
  4. Podsumowanie

Wprowadzenie

Możliwość debugowania zmian w HTML była funkcjonalnością, o której sam długo nie widziałem. Co prawda jest ona dużo bardziej użyteczna w JS niż w React, warto jednak o niej wiedzieć – nadal przecież powstają strony nieużywające frameworków JS. Możliwość zapięcia się na zmiany HTML może również być użyteczna w sytuacji, gdy nasza aplikacja używa bibliotek zewnętrznych GUI, by móc sprawdzić np dlaczego jakiś element został ukryty. Stąd ten krótki wpis – myślę że to drobna rzecz o której naprawdę warto wiedzieć.

Zatrzymywanie się na modyfikacji HTML

Chrome DevTools umożliwia zareagowanie w 3 sytuacjach:

  1. Modyfikacja wewnątrz elementu
  2. Modyfikacja atrybutu elementu
  3. Usunięcie elementu

By móc przetestować każdy z nich po kolei, stwórzmy plik HTML który zawierał będzie potrzebną nam strukturę DOM:

<div>
  <button id="remove">Remove element</button>
  <button id="add-class">Add class to element</button>
  <button id="add-content">Add content to element</button>
</div>
<div id="element">
  <p>
    Child
  </p>
</div>

Efektem będą 3 przyciski modyfikujące element div pod nimi:

Tak utworzona struktura pozwoli nam na dodawanie obsługi każdej sytuacji.

Modyfikacja wewnątrz elementu

Zaznaczmy opcję Break on > subtree modifications:

Modyfikacja taka może zajść w sytuacji, gdy przykładowo pobraliśmy z żądania do serwera nowe obiekty z listy i chcemy wyświetlić je użytkownikowi. Napiszmy kod, który będzie dodawał nowe dziecko do elementu child:

const element = document.querySelector('#element');
  
document.querySelector('#add-content').addEventListener('click', () => {
  const child = document.createElement('p');
  child.innerHTML = 'Child'; 
  element.appendChild(child);
});

Kod ten po kliknięciu odpowiedniego przycisku utworzy paragraf i doda go wewnątrz elementu.

Kliknięcie przycisku “Add Content” przy włączonych Dev Toolsach spowoduje zatrzymanie się kodu na linii, która modyfikuje drzewo DOM elementu:

Dodatkowo po prawej stronie jest wyświetlona informacja o tym, co się stało – “Child div#element added”.

Modyfikacja atrybutu elementu

Zaznaczmy opcję Break on > attribute modifications:

Konieczność zapięcia się na taką sytuację może pojawić się wtedy, gdy dany element modyfikowany jest w wielu miejscach – przykładowo element jest z różnych powodów ukrywany / pokazywany odpowiednią klasą. Wtedy, by wiedzieć kto dodał klasę, można podpiąć się pod modyfikację atrybutu.
Napiszmy kod, który będzie dodawał losową klasę do elementu:

document.querySelector('#add-class').addEventListener('click', () => {
  element.classList.add(`some-class${new Date().getTime()}`);
});

Kliknięcie przycisku “Add class” spowoduje zatrzymanie wykonywania kodu i przeniesienie nas do miejsca modyfikacji:

Usunięcie elementu

Zaznaczmy opcję Break on > node removal:

Możliwość taka może przydać się np w sytuacji, gdy w złym momencie usuwa nam się informacja o cookie.
Napiszmy kod który po kliknięciu przycisku usunie element:

document.querySelector('#remove').addEventListener('click', () => {
  element.parentElement.removeChild(element);
});

Kliknięcie przycisku “Remove element” spowoduje zatrzymanie aplikacji:

Kod w repozytorium Github

Adres repozytorium: https://github.com/radek-anuszewski/html-debug

React – zatrzymywanie się na modyfikacji HTML

Jeśli używamy Reacta, zatrzymywanie się na modyfikacjach nie jest już tak użyteczne. Napiszmy prosty kod, gdzie widoczność elementu jest zależna od flagi:

function App() {
  const [visible, setVisible] = useState(true);

  const removeElement = () => setVisible(false)
  return (
    <div>
      <div>
        <button onClick={removeElement}>Remove element</button>
      </div>
      {visible && (
        <div>
          <p>
            Child
          </p>
        </div>
      )}
    </div>
  );
}

Jeżeli podepniemy się pod Break on > node removal, oczywiście zatrzymamy się na usunięciu elementu, jednak debug zatrzyma się w kodzie Reacta, sam stos wywołań również będzie Reactowy:

Analogicznie mało powie nam debug przy modyfikacji drzewa DOM czy atrybutów elementu.

Kod w repozytorium Github

Jeśli chcesz na własne oczy przekonać się o prawdziwości wniosków, które wrzuciłem wyżej – możesz pobrać aplikację z repozytorium i uruchomić lokalnie:

https://github.com/radek-anuszewski/html-debug-react

Podsumowanie

Możliwość podpięcia się pod zmianę w HTML jest ciekawą funkcjonalnością, użyteczną w pewnych kontekstach. Warto o niej pamiętać przy pisaniu projektów w czystym JS bądź narzędziu które modyfikuje HTML bardziej bezpośrednio niż na przykład React.