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
true
lubfalse
. - 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); }