Range (rozszerzenie)#

Range.createContextualFragment()#

Metoda createContextualFragment() pozwala sparsować przekazany łańcuch znakowy i zwrócić wynik w postaci nowego fragmentu dokumentu.

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 new_fragment = range.createContextualFragment(text);

gdzie poszczególne człony oznaczają:

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

  1. Niech node będzie węzłem początkowym w obiekcie kontekstu.

    Niech context będzie następujący, w zależności od interfejsu node:

    Dla Document i DocumentFragment:

    Wartością null.

    Dla Element:

    Węzłem node.

    Dla Text, Comment i ProcessingInstruction:

    Rodzicem elementowym dla node.

    Dla DocumentType:

    DOM4 zapobiega takiej ewentualności (algorytm ustawiania początku lub końca w zakresie musi zrzucić wyjątek "InvalidNodeTypeError").

  2. Jeśli context jest wartością null 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. Dla każdego (for each) skryptu we fragment dezaktywuj flagi "parser-inserted" i "already started".

    Krok ten ma być równoważny z nieustawianiem tych flag w pierwszej kolejności, aby zapewnić, że skrypty zostaną uruchomione dopiero wtedy, kiedy fragment będzie wstawiany do dokumentu.

  5. Zwróć fragment.

Metoda createContextualFragment() przydaje się w chwili, kiedy zależy nam na utworzeniu jakiegoś drzewa węzłów poza drzewem dokumentu. Na podstawie przekazanego tekstu przy wywołaniu metody otrzymamy obiekt typu DocumentFragment, którego zawartością będzie sparsowany tekst. Drzewo takie możemy dowolnie modyfikować za pomocą standardowych poleceń DOM, i dopiero na koniec wstawić do pewnej części aktywnego drzewa dokumentu lub do innego drzewa węzłów.

Za pomocą metody createContextualFragment() w połączeniu z innymi poleceniami wstawiającymi DOM można zasymulować działanie metody Element.insertAdjacentHTML().

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 str1 = "<div>Teks w kontenerze DIV.</div>";
	// Tworzymy nowy zakres
	var range = document.createRange();
	var new_fragment1 = range.createContextualFragment(str1);

	document.write(new_fragment1); // [object DocumentFragment]
	document.write("<br>");
	document.write(new_fragment1.childNodes.length); // 1
	document.write("<br>");
	document.write(new_fragment1.childNodes[0]); // [object HTMLDivElement]
	document.write("<br>");
	document.write(new_fragment1.childNodes[0].textContent); // Teks w kontenerze DIV.

	document.write("<br><br>");

	var str2 = "<strong>Pogrubiony</strong> i <em>pochylony</em> tekst.";
	// Zmieniamy początek zakresu
	range.setStart(document.documentElement, 1);
	var new_fragment2 = range.createContextualFragment(str2);

	document.write(new_fragment2); // [object DocumentFragment]
	document.write("<br>");
	document.write(new_fragment2.childNodes.length); // 4
	document.write("<br>");
	document.write(new_fragment2.childNodes[2]); // [object HTMLElement]
	document.write("<br>");
	document.write(new_fragment2.childNodes[2].textContent); // pochylony.

	document.write("<br><br>");

	var newDoc = document.implementation.createHTMLDocument("");
	document.write(newDoc.firstChild); // [object DocumentType]

	try{
		range.setStart(newDoc.firstChild, 0);
	}
	catch(e){
		document.write("<br>" + "Próba ustawienia DocumentType na węzeł początkowy zakresu zrzuca błąd:" + "<br>");
		document.write(e); // Wyjątek typu "InvalidNodeTypeError"
	}

</script>

Kolejny 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 str = context.value;

			var range = document.createRange();
			var new_fragment = range.createContextualFragment(str);

			box.appendChild(new_fragment);

		}

	</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ść na końcu kontenera DIV.</p>
	<input type="button" value="<p>Nowy akapit z <strong>pogrubieniem</strong> i <em>pochyleniem</em>.</p>" onclick="insertHTML(this)">
	<input type="button" value="<strong> pogrubienie </strong>" onclick="insertHTML(this)">
	<input type="button" value="<em> pochylenie </em>" onclick="insertHTML(this)">
</body>

</html>

Metoda createContextualFragment() 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. Obecnie jest obsługiwana przez wszystkie wiodące przeglądarki internetowe (w IE od wersji 10).

Składnia Web IDL#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
partial interface Range {
	[NewObject] DocumentFragment createContextualFragment(DOMString fragment);
};

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

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