Range#
Range.comparePoint()#
Metoda comparePoint()
zwraca liczbę całkowitą (wartość -1
, 0
, 1
) zależną od tego, czy przekazany punkt graniczny znajduje się przed, w środku, lub za danym zakresem.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
var value = range.comparePoint(node, offset);
gdzie poszczególne człony oznaczają:
- value - liczba całkowita zależna od wyniku porównania. Zwracane są następujące wartości:
-1
- przekazany punkt graniczny znajduje się przed zakresem.0
- przekazany punkt graniczny znajduje się wewnątrz zakresu.1
- przekazany punkt graniczny znajduje się za zakresem.
- range - zakres będący obiektem kontekstu.
- node - referencja do porównywanego węzła.
- offset - liczba całkowita reprezentująca przesunięcie końcowe.
Algorytm wywołania metody comparePoint(node, offset)
nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:
- Jeśli korzeń w node jest inny od korzenia w obiekcie kontekstu, to zrzuć wyjątek
"WrongDocumentError"
. - Jeśli node jest węzłem typu
DocumentType
, to zrzuć wyjątek"InvalidNodeTypeError"
. - Jeśli offset jest większy od długości w node, to zrzuć wyjątek
"IndexSizeError"
. - Jeśli (node, offset) jest przed początkiem w obiekcie kontekstu, to zwróć liczbę
-1
. - Jeśli (node, offset) jest za końcem w obiekcie kontekstu, to zwróć liczbę
1
. - Zwróć liczbę
0
.
Dla przekazanego początku i końca z samego zakresu metoda comparePoint()
zwróci wartość 0
, co wynika z algorytmu określającego pozycję dwóch punktów granicznych względem siebie (i w tym przypadku będzie ona równa).
Bardzo podobne działanie prezentuje metoda Range.isPointInRange()
, ale jest mniej uniwersalna (bo sygnalizuje tylko dwa stany: w zakresie albo przed/za zakresem), no i mniej restrykcyjna (bo nie zrzuca błędu dla porównywania punktów granicznych z różnymi korzeniami).
Prosty przykład:
<script>
// Tworzymy nowy zakres
var range = document.createRange();
document.write(range.comparePoint(document, 0)); // 0
document.write("<br>");
document.write(range.comparePoint(document, 1)); // 1
document.write("<br>");
document.write(range.comparePoint(document.firstChild, 0)); // 1
document.write("<br><br>");
// Zmieniamy początek i koniec zakresu na węzeł HEAD
range.setStart(document.firstChild.firstChild, 0);
document.write(range.comparePoint(document, 0)); // -1
document.write("<br>");
document.write(range.comparePoint(document, 1)); // 1
document.write("<br>");
document.write(range.comparePoint(document.firstChild, 0)); // -1
document.write("<br>");
document.write(range.comparePoint(document.firstChild.firstChild, 0)); // 0
document.write("<br><br>");
try{ // Sprawdzamy węzeł z innym korzeniem
range.comparePoint(document.createElement("div"), 0);
}
catch(e){
document.write("Przekazanie do metody comparePoint() węzła z innym korzeniem zrzuca błąd:" + "<br>");
document.write(e); // opis zależny od przeglądarki
document.write("<br>");
document.write(e.constructor); // function DOMException() { [native code] }
}
</script>
Kolejny prosty przykład:
<!DOCTYPE html>
<html>
<head>
<script>
function testCaret(){
var info = document.getElementById("info");
var p2 = document.getElementById("box").children[1];
var selection = window.getSelection(); // odczytujemy aktualne zaznaczenia
var range = document.createRange();
range.selectNode(p2); // zakres rozciągamy na cały akapit P2
// Porównujemy pozycję kursora względem danego zakresu
var placement = range.comparePoint(selection.focusNode, selection.focusOffset);
var placementText = "";
if (placement == -1){
placementText = "Kursor znajduje się przed akapitem P2.";
}
else if (placement == 0){
placementText = "Kursor znajduje się wewnątrz akapitu P2.";
}
else{
placementText = "Kursor znajduje się za akapitem P2.";
}
var result = "comparePoint(): " + placement
+ "<br>" + "Opis: " + placementText
+ "<br><br>" + "range.startContainer: " + range.startContainer
+ "<br>" + "range.startOffset: " + range.startOffset
+ "<br><br>" + "range.endContainer: " + range.endContainer
+ "<br>" + "range.endOffset: " + range.endOffset;
info.innerHTML = result;
}
</script>
</head>
<body>
<div id="box" contenteditable="true" style="background-color:#e0a0b0" onmouseup="testCaret()">
<p>Pierwszy akapit P1 w kontenerze DIV.</p>
<p>Drugi akapit P2 w kontenerze DIV.</p>
<p>Trzeci akapit P3 w kontenerze DIV.</p>
</div>
<p>Kliknij wewnątrz kontenera DIV aby ustalić położenie kursora względem drugiego akapitu P2 za pomocą zakresu.</p>
<p style="color: blue;">Szczegółowe informacje dla zakresu:</p>
<p id="info"></p>
</body>
</html>
Na chwilę obecną wszystkie aktualne przeglądarki obsługują metodę comparePoint()
zgodnie z wymaganiami specyfikacji DOM4, oczywiście z pominięciem IE, która kompletnie nie wspiera tej metody.
Metoda comparePoint()
pojawia się dopiero w specyfikacji DOM4.
Składnia Web IDL#
interface Range { short comparePoint(Node node, unsigned long offset); }