Element (rozszerzenie)#

Element.insertAdjacentHTML()#

Metoda insertAdjacentHTML() parsuje przekazany łańcuch znakowy (drugi argument) i wstawia w określone miejsce względem danego elementu (pierwszy argument).

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. #
element.insertAdjacentHTML(position, text);

gdzie poszczególne człony oznaczają:

Algorytm wywołania metody insertAdjacentHTML(position, text) nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:

  1. Użyj pierwszy pasujący element z tej listy:

    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "beforebegin"
    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "afterend"

    Niech context będzie rodzicem posiadanym przez obiekt kontekstu.

    Jeśli context ma wartość null lub jest węzłem typu Document, to zrzuć wyjątek "NoModificationAllowedError".

    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "afterbegin"
    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "beforeend"

    Niech context będzie obiektem kontekstu.

    W przeciwnym razie

    Zrzuć wyjątek "SyntaxError".

  2. Jeśli context nie jest węzłem typu Element lub wszystkie poniższe warunki są prawdziwe:

    niech context będzie nowym węzłem typu Element z:

  3. Niech fragment będzie wynikiem działania algorytmu parsowania fragmentu z łańcuchem znakowym będącym text oraz z elementem kontekstu będącym context.
  4. Użyj pierwszy pasujący element z tej listy:

    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "beforebegin"

    Wstaw fragment do rodzica posiadanego przez obiekt kontekstu przed obiektem kontekstu.

    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "afterbegin"

    Wstaw fragment do obiektu kontekstu przed jego pierwszym dzieckiem.

    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "beforeend"

    Dodaj fragment do obiektu kontekstu.

    Jeśli position pasuje pod względem nieczułości na wielkość znaków ASCII do łańcucha znakowego "afterend"

    Wstaw fragment do rodzica posiadanego przez obiekt kontekstu przed bratem następującym dla obiektu kontekstu.

Działanie metody insertAdjacentHTML() dla pozycji "afterbegin" i "beforeend" w pewnym sensie można by zasymulować za pomocą właściwości Element.innerHTML (np. poleceniem element.innerHTML += "markup";). Niestety, w takim przypadku cała zawartość danego elementu zostaje najpierw zserializowana (ryzyko "zepsucia kodu") i ponownie sparsowana (z dołączeniem nowej zawartości), co z pewnością odbije się na gorszej wydajności takiego rozwiązania, szczególnie w sytuacji, kiedy element posiada rozległą zawartość.

Dlatego też pod względem wydajnościowym metodzie insertAdjacentHTML() bliżej jest do metody Range.createContextualFragment() w połączeniu z innymi poleceniami wstawiającymi DOM, niż do właściwości Element.innerHTML. W praktyce insertAdjacentHTML() może okazać się najszybsza, gdyż w niektórych przypadkach (np. dla pozycji "beforeend") przeglądarki internetowe potrafią odpowiednio zoptymalizować cały proces.

Warto podkreślić, że pozycje "beforebegin" i "afterend" nie będą dostępne w przypadku elementów, które nie posiadają rodzica, lub których rodzicem jest węzeł typu Document (czyli dla elementu dokumentowego, np. <html>), chociaż Chrome dla wspomnianych pozycji (w przeciwieństwie do Firefoksa i IE11) niepotrzebnie zrzuca błąd także dla elementów z rodzicami będącymi fragmentami dokumentów.

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. #
<!DOCTYPE html>
<html>

<head>

	<script>

		var num = 0;

		function insertHTML(context){

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

			num += 1;

			var str = "Nowa sparsowana treść " + num + " (<b>" + input_val + "<b/>). ";

			box.insertAdjacentHTML(input_val, str);

		}

	</script>

</head>

<body>
	<div id="box" style="width:300px; background-color:#e0a0b0;">Kontener będący docelowym elementem.</div>

	<p>Kliknij konkretny przycisk by wstawić nową sparsowaną zawartość względem kontenera DIV.</p>
	<input type="button" value="beforebegin" onclick="insertHTML(this)">
	<input type="button" value="afterbegin" onclick="insertHTML(this)">
	<input type="button" value="beforeend" onclick="insertHTML(this)">
	<input type="button" value="afterend" onclick="insertHTML(this)">
</body>

</html>

Metoda insertAdjacentHTML() była (i do tej pory jest) rzadko stosowana przez programistów, głównie ze względu na długotrwały brak standaryzacji i różnice w implementacjach, aczkolwiek potencjał w niej drzemiący już dawno zauważył sam John Resig i opisał w artykule "DOM insertAdjacentHTML". Uzupełnieniem będzie artykuł Mozilli "insertAdjacentHTML() Enables Faster HTML Snippet Injection", w którym poruszono kilka kluczowych spraw (także wydajnościowych) dla tej metody.

Składnia Web IDL#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
partial interface Element {
	void insertAdjacentHTML(DOMString position, DOMString text);
};

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

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