Range#
Range.surroundContents()#
Metoda surroundContents()
otacza zawartość danego zakresu przekazanym węzłem i ustawia dany zakres na przekazany węzeł.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
range.surroundContents(newParent);
gdzie poszczególne człony oznaczają:
- range - zakres będący obiektem kontekstu.
- newParent - referencja do węzła, którym będzie obejmowana zawartość zakresu.
Algorytm wywołania metody surroundContents(newParent)
nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:
- Jeśli węzeł inny niż
Text
jest częściowo zawarty w obiekcie kontekstu, to zrzuć wyjątek"InvalidStateError"
. - Jeśli newParent jest węzłem typu
Document
,DocumentType
lubDocumentFragment
, to zrzuć wyjątek"InvalidNodeTypeError"
. - Niech fragment będzie rezultatem wyciągania zawartości w obiekcie kontekstu.
- Jeśli newParent ma dzieci, to zastąp wszystko wartością
null
w newParent. - Wstaw newParent do obiektu kontekstu.
- Dodaj fragment do newParent.
- Wybierz newParent w obiekcie kontekstu.
Działanie metody surroundContents()
to zlepek kilku algorytmów, z których każdy może wprowadzać jakieś obostrzenia. Najciekawsza sytuacja występuje dla węzłów częściowo zawartych w zakresie, dla których wywołanie metody zawsze zrzuci błąd (prócz węzłów tekstowych). Dzieje się tak dlatego, że próba otoczenia węzłów częściowo zawartych przekazanym węzłem wygenerowałaby nieprawidłową strukturę drzewa węzłów. W przypadku węzła tekstowego nastąpi jego odpowiedni podział na dwa osobne węzły tekstowe, i tylko jeden z nich otoczony zostanie przekazanym węzłem.
Prosty przykład:
<script>
var box = document.createElement("div");
box.innerHTML = "Pierwszy węzeł tekstowy.";
var parent = document.createElement("p");
parent.textContent = "Początkowa zawartość nowego rodzica";
document.write(box.childNodes.length); // 1
document.write("<br>");
document.write(box.textContent); // Pierwszy węzeł tekstowy.
document.write("<br>");
document.write(parent.childNodes.length); // 1
document.write("<br>");
document.write(parent.textContent); // Początkowa zawartość nowego rodzica.
document.write("<br><br>");
// Tworzymy nowy zakres
var range = document.createRange();
// Ustawiamy zakres na słowo 'węzeł' w kontenera DIV
range.setStart(box.childNodes[0], 9);
range.setEnd(box.childNodes[0], 14);
document.write(range.startContainer); // [object Text]
document.write("<br>");
document.write(range.startOffset); // 9
document.write("<br>");
document.write(range.endContainer); // [object Text]
document.write("<br>");
document.write(range.endOffset); // 14
document.write("<br>");
document.write(range); // węzeł
document.write("<br><br>");
// Otaczamy zawartość zakresu węzłem 'parent' i rozciągamy zakres na ten węzeł
range.surroundContents(parent);
document.write(box.childNodes.length); // 3
document.write("<br>");
document.write(box.textContent); // Pierwszy węzeł tekstowy.
document.write("<br>");
document.write(parent.childNodes.length); // 1
document.write("<br>");
document.write(parent.textContent); // węzeł - początkowa zawartość została usunięta
document.write("<br>");
document.write(box.childNodes[1] == parent); // true - węzeł 'parent' wstawiony został do węzła 'box'
document.write("<br><br>");
document.write(range.startContainer); // [object HTMLDivElement], w IE [object Text]
document.write("<br>");
document.write(range.startOffset); // 1, w IE 9
document.write("<br>");
document.write(range.endContainer); // [object HTMLDivElement], w IE [object Text]
document.write("<br>");
document.write(range.endOffset); // 2, w IE 10
document.write("<br>");
document.write(range); // węzeł
</script>
Na chwilę obecną wszystkie aktualne przeglądarki obsługują metodę surroundContents()
zgodnie z najnowszymi wymaganiami specyfikacji DOM4. Wyjątkiem będzie IE, które działa po swojemu, tzn. źle ustala punkty graniczne po zmianach, co widać w powyższym przykładzie.
Składnia Web IDL#
interface Range { void surroundContents(Node newParent); }