Materiał edukacyjny · Informatyka JavaScript w przeglądarce · Moduł 11

MODUŁ 11

Dynamiczne tworzenie i usuwanie elementów DOM

PPrezentacja dla nauczyciela

Zamiast ograniczać się do elementów przygotowanych na stałe w kodzie HTML, aplikacje internetowe generują treść na żywo: dopisują nowe komentarze, renderują karty katalogu z danych i usuwają wybrane pozycje z koszyka. W tym module opanujesz metody programowego tworzenia, wstawiania oraz usuwania węzłów DOM.

Tworzenie i dołączanie elementów createElement

Dynamiczne rozbudowywanie strony o nowe pozycje (np. dodawanie wpisów na forum, kolejnych zadań czy produktów) opiera się na tworzeniu węzłów DOM za pomocą metody document.createElement(nazwaZnacznika).

Nowo utworzony element istnieje początkowo wyłącznie w pamięci operacyjnej przeglądarki i nie jest jeszcze widoczny w oknie strony. Przed dołączeniem go do dokumentu konfigurujemy jego właściwości: przypisujemy tekst za pomocą element.textContent, nadajemy klasy CSS przez element.className lub modyfikujemy inne atrybuty.

Aby element pojawił się w strukturze strony, musimy wstawić go do wybranego kontenera nadrzędnego (np. listy <ul> lub bloku <div>) za pomocą metody rodzic.appendChild(nowyElement). Metoda ta dołącza węzeł na samym końcu listy dzieci danego kontenera.

function dodajNowyWpis() {
  const pole = document.getElementById('trescWpisu');
  const tekst = pole.value.trim();

  if (tekst === '') {
    alert('Wpis nie może być pusty!');
    return;
  }

  const lista = document.getElementById('listaWiadomosci');
  const nowyWpis = document.createElement('li');
  nowyWpis.textContent = tekst;

  lista.appendChild(nowyWpis);
  pole.value = '';
}
1. Która metoda służy do utworzenia nowego węzła elementu w pamięci przeglądarki?
2. W jaki sposób dołączyć nowo utworzony element potomny na koniec wskazanego kontenera rodzica?
3. Co się stanie z nowo utworzonym elementem, jeśli utworzymy go za pomocą document.createElement, ale nie wywołamy metody dołączającej do DOM?

Generowanie struktur w pętli i czyszczenie kontenera

Przy budowaniu katalogów produktów, cenników czy tabel z danymi najczęściej powtarzamy operację tworzenia elementów w pętli (np. metodą tablica.forEach()). Dla każdego obiektu z danymi tworzymy zestaw węzłów, łączymy je w spójny kafelek i wstawiamy do wspólnego kontenera.

Kluczową zasadą higieny interfejsu przed ponownym generowaniem treści (np. po kliknięciu przycisku odświeżenia lub zmiany filtra) jest wyczyszczenie dotychczasowej zawartości kontenera. Najszybciej osiągamy to przypisaniem pustego ciągu znaków: kontener.innerHTML = ''.

Gdy liczba elementów nie wynika z tablicy, lecz z wartości podanej przez użytkownika, wygodniej użyć klasycznej pętli for z licznikiem. Nagłówek pętli ma trzy części: inicjalizację licznika, warunek wykonywania i krok po każdym obrocie — blok powtarza się tak długo, jak warunek jest prawdziwy:

const ile = parseInt(document.getElementById('ilePunktow').value, 10);

for (let i = 1; i <= ile; i++) {
  const punkt = document.createElement('li');
  punkt.textContent = 'Punkt ' + i;
  lista.appendChild(punkt);
}

Pominięcie czyszczenia kontenera spowodowałoby dopisywanie kolejnych kopii elementów poniżej już istniejących za każdym razem, gdy użytkownik wywoła funkcję generującą.

const uslugi = [
  { nazwa: 'Instalacja systemu', cena: 80 },
  { nazwa: 'Czyszczenie układu', cena: 120 },
  { nazwa: 'Odzyskiwanie danych', cena: 250 }
];

function generujKartyUslug() {
  const kontener = document.getElementById('kontenerUslug');
  kontener.innerHTML = '';

  uslugi.forEach(function(u) {
    const karta = document.createElement('div');
    karta.className = 'karta-uslugi';

    const tytul = document.createElement('h4');
    tytul.textContent = u.nazwa;

    const cena = document.createElement('p');
    cena.className = 'cena';
    cena.textContent = u.cena + ' zł';

    karta.appendChild(tytul);
    karta.appendChild(cena);
    kontener.appendChild(karta);
  });
}

function wyczyscKatalog() {
  document.getElementById('kontenerUslug').innerHTML = '';
}
4. W jaki sposób najszybciej usunąć całą dotychczasową zawartość kontenera przed ponownym wygenerowaniem elementów?
5. Dlaczego przed ponownym generowaniem listy kart z tablicy należy wyczyścić kontener?
6. Jaka pętla lub metoda tablicy jest najwygodniejsza do utworzenia kafelka dla każdego obiektu w kolekcji?

Usuwanie elementów z drzewa dokumentu

Usuwanie elementów jest nieodzownym elementem interfejsów takich jak koszyki zakupowe czy listy zadań. Nowoczesny standard DOM udostępnia prostą metodę element.remove(), którą wywołujemy bezpośrednio na węźle, który ma zniknąć ze strony.

Gdy przycisk usuwania znajduje się wewnątrz usuwanego wiersza (np. w elemencie <li>), możemy przekazać referencję do klikniętego przycisku za pomocą słowa kluczowego this w atrybucie zdarzenia: onclick="usunPozycje(this)". Wewnątrz funkcji odwołujemy się do rodzica przez przycisk.parentElement i wywołujemy na nim metodę remove().

Po usunięciu węzła warto zaktualizować stan powiązanych liczników na stronie (np. zliczając pozostałe elementy za pomocą document.querySelectorAll('ul li').length) lub przeliczyć sumę zamówienia.

function usunPozycje(przycisk) {
  const elementLi = przycisk.parentElement;
  elementLi.remove();

  const pozostalo = document.querySelectorAll('#listaKoszyka li').length;
  const licznik = document.getElementById('licznikKoszyka');

  licznik.textContent = 'Pozycji w koszyku: ' + pozostalo;
}
7. Która nowoczesna metoda pozwala na bezpośrednie usunięcie elementu węzła ze strony?
8. W jaki sposób uzyskać referencję do nadrzędnego elementu li z poziomu klikniętego przycisku przekazanego jako this?
9. Jaka starsza metoda usuwania węzła wywoływana na elemencie nadrzędnym jest w pełni równoważna metodzie remove?

Ćwiczenia