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:

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

gdzie poszczególne człony oznaczają:

Algorytm wywołania metody comparePoint(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 zrzuć wyjątek "WrongDocumentError".
  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 w obiekcie kontekstu, to zwróć liczbę -1.
  5. Jeśli (node, offset) jest za końcem w obiekcie kontekstu, to zwróć liczbę 1.
  6. 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:

  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.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:

  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.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#

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

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

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