Element (rozszerzenie)#

Element.innerHTML#

Właściwość innerHTML parsuje (przy ustawianiu) lub serializuje (przy pobieraniu) zawartość danego elementu.

Opis działania#

Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
var actual_content = element.innerHTML; // getting
element.innerHTML = new_content; // setting

gdzie poszczególne człony oznaczają:

W zależności od podejmowanej akcji muszą zostać wykonane następujące kroki:

Odczyt wartości atrybutu (getting):

  1. Zwróć wynik działania algorytmu serializacji fragmentu na obiekcie kontekstu z przekazaniem boolowskiej wartości true dla flagi wymaganego dobrego sformułowani.

    W przypadku dokumentów XML krok ten może zrzucić wyjątek "InvalidStateError" zamiast zwrócenia łańcucha znakowego, kiedy obiekt kontekstu nie może zostać zserializowany zgodnie z wymogami XML-a (kwestia nierozstrzygnięta).

Zmiana wartości atrybutu: (setting):

  1. Niech fragment będzie wynikiem działania algorytmu parsowania fragmentu z łańcuchem znakowym będącym ustawianą wartością oraz z elementem kontekstu będącym obiektem kontekstu.

    W przypadku dokumentów XML krok ten może zrzucić wyjątek "SyntaxError" zamiast zwrócenia struktury znacznikowej, kiedy przekazany łańcuch znakowy nie może zostać sparsowany zgodnie z wymogami XML-a.

  2. Zastąp wszystko przez fragment w obiekcie kontekstu.

Właściwość innerHTML bierze pod uwagę jedynie zawartość (content) danego elementu, bez uwzględniania jego znacznika otwierającego i znacznika zamykającego. Jeśli zależy nam na takim zachowaniu, to można skorzystać z właściwości Element.outerHTML.

Warto podkreślić, że przy serializacji węzłów tekstowych (ewentualnie atrybutów w elementach) może nastąpić samoczynne zastąpienie w danych tekstowych lub w wartościach atrybutów znaków &, <, > i " na odpowiadające im encje nazwane. Szczegóły tego zachowania są zależne od rodzaju przetwarzanego dokumentu, i w razie potrzeby należy je samodzielnie ustalić poprzez dokładną analizę poszczególnych algorytmów. Odczyt danych w oryginalnej postaci można przeprowadzić alternatywnymi poleceniami, np. Node.textContent czy Attr.value.

Parsowanie danych tekstowych pochodzących od osób trzecich stwarza duże zagrożenie i jeśli nie jest niezbędne należy rozważyć alternatywne rozwiązania.

Prosty przykład:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<script>

	var html = document.documentElement; // referencja do elementu HTML

	alert(html.innerHTML); // Zwróci serializację zawartości elementu HTML (bez niego samego)

	html.innerHTML = "<p style='color: blue'>Nowa zawartość!</p>";

</script>

Starsze przeglądarki internetowe mogą obsługiwać właściwość innerHTML z drobnymi uchybieniami względem aktualnych standardów. Przykładowo, przeglądarka Internet Explorer (do wersji 8 włącznie) serializuje wpisaną przez użytkownika wartość do pola <input type="text">, kiedy pozostałe przeglądarki tego nie robią. Od wersji IE9 wszystko działa prawidłowo:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<!DOCTYPE html>
<html>

<head>

	<script>

		function getInnerHTML(){

			var box = document.getElementById("box"); // referencja do kontenera

			alert(box.innerHTML); // Po wpisaniu tekstu do pola input starsze przeglądarki IE uwzględnią zmianę

		}

	</script>

</head>

<body>
	<div id="box">
		<p>Kliknij przycisk by zserializować zawartość kontenera DIV.</p>
		<input type="text">
		<input type="button" value="div.innerHTML" onclick="getInnerHTML()">
	</div>
</body>

</html>

Właściwości innerHTML nigdy nie powinno się używać do zapisu części tabeli - w takiej sytuacji parser przeglądarki internetowej może automatycznie zamknąć część tagów przy aktualizacji drzewa węzłów, aby uzyskać jego poprawną strukturę, a dalszą część (dodawaną w kolejnym wywołaniu polecenia) wstawić dopiero za tabelą. Nie ma natomiast problemów w przypadku zapisywania całej tabeli w jednym kroku lub modyfikacji zawartości pojedynczych komórek.

W związku z powyższym przeglądarka IE specjalnie blokuje możliwość zmiany zawartości niektórych elementów za pomocą właściwości innerHTML, żeby nie dopuścić do problematycznych sytuacji. Na dzień dzisiejszy jest to niestandardowe zachowanie i nie musi być powielane przez pozostałe programy.

Na zakończenie warto omówić kwestię wydajnościową, która najczęściej poruszana jest w różnych publikacjach dla właściwości innerHTML. W przypadku starszych przeglądarek internetowych właściwość innerHTML była szybsza od alternatywnych metod DOM (tworzących i modyfikujących węzły) i oczywiście wygodniejsza, gdyż ten sam fragment kodu można było utworzyć przy użyciu mniejszej liczby poleceń. Wraz z premierą przeglądarki Chrome, gdzie silnik JS oparto na JIT, sytuacja uległa zmianie. Obecnie to alternatywne polecenia DOM okazują się szybsze. W razie potrzeby namawiam do wykonania podstawowego testu, który określi różnice wydajnościowe między kluczowymi technikami modyfikowania zawartości węzłów w aktualnych programach.

Składnia Web IDL#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
partial interface Element {
	[TreatNullAs=EmptyString] attribute DOMString innerHTML;
};

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

Element (rozszerzenie) (H1) Element.innerHTML (H2) Opis działania (H3) Składnia Web IDL (H3) Specyfikacje i inne materiały (H3)