Range#

Range.extractContents()#

Metoda extractContents() usuwa z drzewa węzłów całą zawartość danego zakresu i zwraca do niej referencję 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 extract_contents = range.extractContents();

gdzie poszczególne człony oznaczają:

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

  1. Zwróć wynik wyciągania zawartości w obiekcie kontekstu.

W ujęciu całościowym powyższy algorytm nie należy do najkrótszych i najłatwiejszych. Chodzi głównie o to, by prawidłowo wydobyć węzły częściowo zawarte, tak aby otrzymany wynik tworzył poprawną strukturę drzewa węzłów. W przeciwieństwie do metody Range.cloneContents(), tutaj część węzłów jest całkowicie przenoszona w nowe miejsce, a tylko niektóre węzły zostają skopiowane. Teoretyczny opis tego procesu omówiłem w podstawach zakresów.

Wyciągnięta zawartość zakresu (węzeł typu DocumentFragment) zwracana przez metodę extractContents() nie jest częścią drzewa dokumentu dopóki nie zostanie dodana do innego węzła należącego do drzewa dokumentu. Dlatego wyciągnięta zawartość nie będzie posiadała rodzica (wartość null), aczkolwiek dalej posiada jakiegoś właściciela.

Po wyciągnięciu zawartości zakresu metodą extractContents() nastąpi automatyczne skorygowanie jego punktów granicznych (zakres zawsze zostanie zwinięty), tak żeby wszystko pasowało do nowej sytuacji.

Skopiowanie zawartości zakresu (bez usuwania z drzewa węzłów) można wykonać metodą Range.cloneContents(). Do całkowitego usunięcia zawartości zakresu z drzewa węzłów (bez zwracania jakiejkolwiek referencji) służy metoda Range.deleteContents().

Prosty przykład:

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

	var box = document.createElement("div");

	box.innerHTML = "Pierwszy węzeł tekstowy. "
		+ "<p>Drugi węzeł tekstowy (dodatkowo w akapicie).</p>"
		+ " Trzeci węzeł tekstowy.";

	document.write(box.childNodes.length); // 3
	document.write("<br>");
	document.write(box.textContent); // Pierwszy węzeł tekstowy. Drugi węzeł tekstowy (dodatkowo w akapicie). Trzeci węzeł tekstowy.

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

	// Tworzymy nowy zakres
	var range = document.createRange();

	// Ustawiamy zakres między różnymi danymi w węzłach tekstowych kontenera DIV
	range.setStart(box.childNodes[0], 5);
	range.setEnd(box.childNodes[2], box.childNodes[2].length - 5);

	document.write(range.startContainer); // [object Text]
	document.write("<br>");
	document.write(range.startOffset); // 5
	document.write("<br>");
	document.write(range.endContainer); // [object Text]
	document.write("<br>");
	document.write(range.endOffset); // 18
	document.write("<br>");
	document.write(range); // szy węzeł tekstowy. Drugi węzeł tekstowy (dodatkowo w akapicie). Trzeci węzeł teks

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

	// Wyciągamy zawartość zakresu
	var extract = range.extractContents();

	document.write(extract); // [object DocumentFragment]
	document.write("<br>");
	document.write(extract.childNodes.length); // 3
	document.write("<br>");
	document.write(extract.textContent); // szy węzeł tekstowy. Drugi węzeł tekstowy (dodatkowo w akapicie). Trzeci węzeł teks

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

	document.write(box.childNodes.length); // 2
	document.write("<br>");
	document.write(box.textContent); // Pierwtowy.

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

	document.write(range.startContainer); // [object HTMLDivElement]
	document.write("<br>");
	document.write(range.startOffset); // 1
	document.write("<br>");
	document.write(range.endContainer); // [object HTMLDivElement]
	document.write("<br>");
	document.write(range.endOffset); // 1
	document.write("<br>");
	document.write(range.collapsed); // true - zakres zwinięty

</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>

		function extract(){

			var info = document.getElementById("info");
			var box = document.getElementById("box");

			// Tworzymy nowy zakres i ustawiamy na pierwszy element w DIV
			var range = document.createRange();
			range.selectNode(box.firstElementChild);

			// Wyciągamy zawartość zakresu
			var extractNode = range.extractContents();

			// Wstawiamy węzeł 'extractNode' do kontenera DIV
			box.appendChild(extractNode);

			var result = "range.startContainer: " + range.startContainer
				+ "<br>" + "range.startOffset: " + range.startOffset
				+ "<br><br>" + "range.endContainer: " + range.endContainer
				+ "<br>" + "range.endOffset: " + range.endOffset
				+ "<br><br>" + "range: " + range;

			info.innerHTML = result;

		}

	</script>

</head>

<body>

	<div id="box" style="background-color:#e0a0b0">
		<p>Pierwszy akapit P1 w kontenerze DIV.</p>
		<p>Drugi akapit P2 w kontenerze DIV.</p>
	</div>

	<p>Kliknij przycisk by przenieść pierwszy element za ostatni element w DIV za pomocą zakresu.</p>
	<input type="button" value="extractContents()" onclick="extract()">
	<p style="color: blue;">Szczegółowe informacje dla zakresu:</p>
	<p id="info"></p>

</body>

</html>

Składnia Web IDL#

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

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

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