innerHTML vs textContent
innerHTML odczytuje i ustawia kod HTML elementu, parsując napis na nowe elementy, a textContent odczytuje i ustawia czysty tekst, bez znaczników.
Porównanie w tabeli
#Co zwraca przy odczycie
- Element.innerHTML
- Kod HTML zawartości jako napis, ze znacznikami
- Node.textContent
- Czysty tekst zawartości i jej potomków, bez znaczników
Przypisanie napisu ze znacznikami
- Element.innerHTML
- Tworzy z nich prawdziwe elementy HTML
- Node.textContent
- Wyświetla znaczniki jako zwykły tekst
Bezpieczeństwo przy danych od użytkownika
- Element.innerHTML
- Ryzyko ataku XSS, dane trzeba oczyścić
- Node.textContent
- Bezpieczne, tekst nigdy nie staje się znacznikiem
Wydajność
- Element.innerHTML
- Wolniejsze, wymaga parsowania HTML
- Node.textContent
- Szybsze, bez parsowania znaczników
Wpływ na istniejące elementy potomne
- Element.innerHTML
- Niszczy je razem z podpiętą obsługą zdarzeń
- Node.textContent
- Niszczy je razem z podpiętą obsługą zdarzeń
Typowe użycie
- Element.innerHTML
- Wstawianie większego, znanego z góry fragmentu HTML
- Node.textContent
- Wyświetlanie dowolnego tekstu, też od użytkownika
Przykład
#const box = document.querySelector('#box')
console.log(box.innerHTML)
console.log(box.textContent)
box.textContent = 'Wszystkie zadania zrobione'
console.log(box.innerHTML)Definicja i zastosowanie
#Obie właściwości odczytują i nadpisują zawartość elementu, a przypisanie nowej wartości zawsze usuwa dotychczasowe dzieci. Różni je to, jak traktują napis. innerHTML zwraca znaczniki HTML jako tekst i parsuje przypisany napis jako HTML, tworząc z niego prawdziwe elementy. textContent zwraca sam tekst elementu i jego potomków, a przypisany napis wstawia dosłownie, jako jeden węzeł tekstowy.
Z tej różnicy wynika ryzyko. Wstawienie przez innerHTML napisu od użytkownika albo z API otwiera drogę do ataku XSS, bo znaki < i > zamieniają się w działające znaczniki. textContent jest bezpieczny: te same znaki pojawią się na ekranie jako tekst. innerHTML jest też wolniejszy, bo wymaga parsowania HTML, i niszczy obsługę zdarzeń podpiętą do starych elementów przy każdym przypisaniu.
Do wyświetlania tekstu, zwłaszcza danych od użytkownika, używaj textContent. innerHTML zostaw do wstawiania większych fragmentów znanego z góry kodu HTML, na przykład listy zbudowanej w template literal, pamiętając o oczyszczeniu każdej wartości pochodzącej od użytkownika.
Składnia
#const html = element.innerHTML
element.innerHTML = htmlString
const text = element.textContent
element.textContent = newTextWięcej przykładów
#const list = document.querySelector('#list')
const firstItem = document.querySelector('#first')
list.innerHTML += '<li>Kolejny krok</li>'
console.log(document.querySelector('#first') === firstItem)
console.log(firstItem.isConnected)innerHTML += odczytuje cały kod HTML, dolepia nowy fragment i parsuje wszystko od nowa. Nowy element #first wygląda tak samo, ale to inny obiekt, a stary jest odłączony od dokumentu.
const comment = document.querySelector('#comment')
comment.textContent = 'Użyj <strong>, żeby pogrubić tekst'
console.log(comment.children.length)
console.log(comment.textContent)Napis trafia do elementu dosłownie, jako jeden węzeł tekstowy. Znaki < i > nie tworzą znacznika, więc children.length zostaje równe 0.
Dobre praktyki
#- Do wyświetlania tekstu od użytkownika zawsze używaj
textContent.innerHTMLz nieoczyszczonymi danymi to otwarta droga do ataku XSS. - Unikaj
innerHTML +=w pętli: każdy krok przebudowuje całą zawartość od nowa. Zbuduj najpierw cały napis albo użyjinsertAdjacentHTML(). - Do wyczyszczenia elementu wystarczy
element.textContent = "", bez ryzyka związanego z parsowaniem HTML.
Powiązane hasła
#- Element.innerHTMLOdczytuje lub zastępuje zawartość elementu w postaci kodu HTML.
- Node.textContentOdczytuje lub ustawia cały tekst elementu, bez znaczników HTML.
- document.querySelector()Zwraca pierwszy element pasujący do selektora CSS albo null, gdy nic nie pasuje.
- document.createElement()Tworzy nowy element HTML o podanej nazwie znacznika, gotowy do wstawienia na stronę.
Widzisz błąd albo brakuje przykładu? Napisz do nas.