Wstawianie kodu HTML w dowolnym miejscu strony za pomocą JS

Treść dodana: 01 września 2017.

Manipulacje na drzewie DOM to chleb powszedni programisty JavaScript. Istnieje wiele metod osadzenia HTML / tekstu, z czego najpopularniejszą metodą jest zwykłe zastępowanie treści przy użyciu `innerHTML`. Przyjmijmy że testowy dokument ma następującą strukturę:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // Treść wykonana po załadowaniu DOM
            // Tutaj osadzamy kod z przykładów
        }, false);
    </script>
</head>
<body>
    <div id="content">
        <p>Przykładowa treść</p>
        <ul>
            <li>Lista 1</li>
            <li>Lista 2</li>
            <li>Lista 3</li>
        </ul>
    </div>
</body>
</html>

Gdybyśmy teraz chcieli zamienić tekst “Przykładowa treść” linkiem, moglibyśmy wstawić kod:

document.addEventListener('DOMContentLoaded', function() {
    document.querySelector('#content > p').innerHTML = '<a href="#">Podlinkowana treść</a>';
}, false);

Zazwyczaj jednak struktura dokumentu jest znacznie bardziej skomplikowana i wymaga precyzyjnego osadzania. Pokażę kilka sposobów na manipulacje drzewem DOM. Na początek będziemy potrzebować nowy element, który można utworzyć korzystając z dostępnych funkcji JS:

var test = document.createElement('p');
    test.id = 'test';
    test.classList.add('klasa1', 'klasa2');
    test.innerHTML = 'Element p wygenerowany w JS';

Funkcja `document.createElement` tworzy nowy element DOM (w tym wypadku `p`), któremu dodajemy identyfikator `test` oraz treść. Specjalnie dodałem 2 klasy (`klasa1` oraz `klasa2`) aby zaprezentować właściwość Element.classList. Powstała ona jako wygodna alternatywa do występujących w JS od dawna funkcji. Możemy dzięki niej w bardzo przejrzysty sposób zarządzać klasami danego elementu. Teraz gdy wszystko jest gotowe możemy przejść dalej.

Wstawianie jako ostatni element listy – appendChild

Metoda appendChild(dziecko) dodaje podane dziecko na sam koniec listy elementów DOM danego rodzica.

Jeśli zatem chcielibyśmy do elementu #content wstawić nasz testowy element za listą `ul` należy użyć kodu:

document.getElementById('content').appendChild(test);

Z kolei, aby dostawić element za tekstem Lista 2, potrzebowalibyśmy kodu:

document.querySelector('#content ul li:nth-child(2)').appendChild(test);

Wstawianie przed elementem – insertBefore

Definicja insertBefore jest następująca:

var wstawionyElement = elementRodzic.insertBefore(nowyElement, danyElement)

Gdzie:
- nowyElement – element który chcemy wstawić
- danyElement – węzeł przed którym nowyElement ma być wstawiony. Jeżeli ustawiony na `null` nowyElement wstawiony będzie na koniec listy (odpowiednik appendChild)
- elementRodzic – rodzic nowo wstawianego elementu
- wstawionyElement – wstawiany węzeł czyli nowyElement

Przykładowo, gdybyśmy chcieli wstawić nasz element `p` przed 2 elementem listy, należało by użyć kodu:

var x = document.querySelector('#content ul li:nth-child(2)');
    x.parentNode.insertBefore(test, x);

Natomiast wykorzystując drugi parametr `null` można, jak w przykładzie dla appendChild, dopisać element po tekście `Lista 2`:

var x = document.querySelector('#content ul li:nth-child(2)');
    x.insertBefore(test, null);

Wstawianie w dowolnym miejscu – insertAdjacentHTML

Doskonałym, a zarazem bardzo często zapominanym sposobem na modyfikację struktury, jest metoda insertAdjacentHTML której definicja jest następująca:

insertAdjacentHTML(pozycja, tekst);

Gdzie `tekst` to tekst do wstawienia, natomiast pozycje są 4:

- beforebegin – przed elementem
- afterbegin – wewnątrz elementu, przed pierwszym dzieckiem
- beforeend – wewnątrz elementu, po ostatnim dziecku
- afterend – po elemencie

<!-- beforebegin -->
    <p>
    <!-- afterbegin -->
        wewnętrzne węzły DOM
    <!-- beforeend -->
    </p>
<!-- afterend -->

Należy pamiętać aby nie wstawiać jako `tekst` danych pochodzących bezpośrednio od użytkownika, gdyż może to spowodować lukę w systemie. Dane należy bezwzględnie i zawsze przefiltrować.

Praca z insertAdjacentHTML() jest chyba najbardziej intuicyjna. Przykładowo, aby wstawić nasz testowy element przed listą `ul` należy użyć kodu:

document.querySelector('#content ul').insertAdjacentHTML('beforebegin', test.outerHTML);

Aby dopisać nowy element listy po 2 elemencie `li`:

document.querySelector('#content ul li:nth-child(2)').insertAdjacentHTML(
    'afterend', 
    '<li>Nowy element listy</li>'
);

Technologie eksperymentalne

Jak to zazwyczaj bywa w takim przypadku, istnieje kilka funkcji które działają wszędzie, oprócz Internet Explorer oraz jego następcy MS Edge. Są to:

- ChildNode.after(węzły)
- ChildNode.before(węzły)
- ChildNode.replaceWith(węzły)
- ParentNode.prepend(węzły)
- ParentNode.apend(węzły)

Jeżeli piszemy aplikację tylko dla nowoczesnych przeglądarek, mogą one znacznie ułatwić życie.

Komentarze

Nie ma jeszcze żadnych komentarzy do wyświetlenia. Może chcesz zostać pierwszą osobą która podzieli się swoją opinią?

Dodaj komentarz

*
Nazwa zostanie wyświetlona wraz z komentarzem. Możesz też utworzyć nowe konto w serwisie, dzięki czemu uzyskasz dodatkową funkcjonalność.
*
Akceptowana jest ograniczona składnia Textile. Wszystkie tagi HTML zostaną usunięte.