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:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
var in_range = range.isPointInRange(node, offset);

gdzie poszczególne człony oznaczają:

Algorytm wywołania metody isPointInRange(node, offset) nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:

  1. Jeśli korzeń w node jest inny od korzenia w obiekcie kontekstu, to zwróć boolowską wartość false.
  2. Jeśli node jest węzłem typu DocumentType, to zrzuć wyjątek "InvalidNodeTypeError".
  3. Jeśli offset jest większy od długości w node, to zrzuć wyjątek "IndexSizeError".
  4. Jeśli (node, offset) jest przed początkiem lub za końcem w obiekcie kontekstu, to zwróć boolowską wartość false.
  5. 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:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<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:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<!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#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
interface Range {
	boolean isPointInRange(Node node, unsigned long offset);
}

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

Range (H1) Range.isPointInRange() (H2) Opis działania (H3) Składnia Web IDL (H3) Specyfikacje i inne materiały (H3)