Range#
Range.isPointInRange()#
Metoda isPointInRange() zwraca boolowską wartość true jeśli przekazany punkt graniczny znajduje się w danym zakresie, w przeciwnym razie zwrócona zostanie wartość false.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
var in_range = range.isPointInRange(node, offset);gdzie poszczególne człony oznaczają:
- in_range - boolowskie
truelubfalse. - 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 isPointInRange(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 zwróć boolowską wartość
false. - 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 lub za końcem w obiekcie kontekstu, to zwróć boolowską wartość
false. - Zwróć boolowską wartość
true.
Dla przekazanego początku i końca z samego zakresu metoda isPointInRange() zwróci boolowską wartość true, 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 można uzyskać za pomocą uniwersalniejszej metody Range.comparepoint(), gdzie zwracana wartość 0 oznacza, że przekazany punkt graniczny znajduje się wewnątrz zakresu. Zwrócenie wartości -1 lub 1 będzie świadczyło o tym, że przekazany punkt graniczny znajduje się przed lub za zakresem. Trzeba jednak wyraźnie zaznaczyć, że metoda isPointInRange() jest mniej restrykcyjna dla porównywania punktów granicznych z różnymi korzeniami, gdzie nie zrzuca żadnego błędu tylko od razu zwraca boolowską wartość false.
Prosty przykład:
<script>
// Tworzymy nowy zakres
var range = document.createRange();
document.write(range.isPointInRange(document, 0)); // true
document.write("<br>");
document.write(range.isPointInRange(document, 1)); // false
document.write("<br>");
document.write(range.isPointInRange(document.firstChild, 0)); // false
document.write("<br>");
document.write(range.isPointInRange(document.createElement("div"), 0)); // false
document.write("<br>");
document.write(range.isPointInRange(document.implementation.createDocumentType("a", "", ""), 0)); // false
document.write("<br><br>");
// Zmieniamy początek i koniec zakresu na węzeł HEAD
range.setStart(document.firstChild.firstChild, 0);
document.write(range.isPointInRange(document, 0)); // false
document.write("<br>");
document.write(range.isPointInRange(document, 1)); // false
document.write("<br>");
document.write(range.isPointInRange(document.firstChild, 0)); // false
document.write("<br>");
document.write(range.isPointInRange(document.firstChild.firstChild, 0)); // true
document.write("<br><br>");
try{ // Sprawdzamy węzeł typu DocumentType z tym samym korzeniem
var newDTD = document.implementation.createDocumentType("a", "", "");
document.insertBefore(newDTD, document.documentElement);
range.isPointInRange(newDTD, 0);
}
catch(e){
document.write("Przekazanie do metody isPointInRange() węzła typu DocumentType z tym samym 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.isPointInRange(selection.focusNode, selection.focusOffset);
var placementText = "";
if (placement){
placementText = "Kursor znajduje się wewnątrz akapitu P2.";
}
else{
placementText = "Kursor znajduje się poza 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ę isPointInRange() zgodnie z wymaganiami specyfikacji DOM4, oczywiście z pominięciem IE, która kompletnie nie wspiera tej metody.
Metoda isPointInRange() pojawia się dopiero w specyfikacji DOM4.
Składnia Web IDL#
interface Range { boolean isPointInRange(Node node, unsigned long offset); }