Range#
Range.cloneContents()#
Metoda cloneContents()
klonuje zawartość danego zakresu i zwraca referencję do nowej kopii w postaci nowego fragmentu dokumentu.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
var clone_contents = range.cloneContents();
gdzie poszczególne człony oznaczają:
- clone_contents - nowy fragment dokumentu ze skopiowaną zawartością zakresu.
- range - zakres będący obiektem kontekstu.
Algorytm wywołania metody cloneContents()
nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:
- Zwróć wynik klonowania 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 skopiować węzły częściowo zawarte, tak aby otrzymany wynik tworzył poprawną strukturę drzewa węzłów. Teoretyczny opis tego procesu omówiłem w podstawach zakresów.
Sklonowana zawartość zakresu (węzeł typu DocumentFragment
) zwracana przez metodę cloneContents()
nie jest częścią drzewa dokumentu dopóki nie zostanie dodana do innego węzła należącego do drzewa dokumentu. Dlatego samotna kopia nie będzie posiadała rodzica (wartość null
), aczkolwiek dalej posiada jakiegoś właściciela.
Prosty przykład:
<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.";
// 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); // szy węzeł tekstowy. Drugi węzeł tekstowy (dodatkowo w akapicie). Trzeci węzeł teks
document.write("<br><br>");
// Kopiujemy zawartość zakresu
var clone = range.cloneContents();
document.write(clone); // [object DocumentFragment]
document.write("<br>");
document.write(clone.childNodes.length); // 3
document.write("<br>");
document.write(clone.textContent); // szy węzeł tekstowy. Drugi węzeł tekstowy (dodatkowo w akapicie). Trzeci węzeł teks
</script>
Kolejny prosty przykład:
<!DOCTYPE html>
<html>
<head>
<script>
function clone(){
var info = document.getElementById("info");
var box = document.getElementById("box");
// Tworzymy nowy zakres i ustawiamy na pierwszy akapit w DIV
var range = document.createRange();
range.setStart(box, 1);
range.setEnd(box, 2);
// Klonujemy zawartość zakresu
var cloneNode = range.cloneContents();
// Wstawiamy węzeł 'cloneNode' do kontenera DIV
box.appendChild(cloneNode);
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 skopiować pierwszy akapit P1 i dodać na koniec DIV za pomocą zakresu.</p>
<input type="button" value="cloneContents()" onclick="clone()">
<p style="color: blue;">Szczegółowe informacje dla zakresu:</p>
<p id="info"></p>
</body>
</html>
Składnia Web IDL#
interface Range { [NewObject] DocumentFragment cloneContents(); }