Node#

Node.compareDocumentPosition()#

Metoda compareDocumentPosition() zwraca maskę bitową (liczba całkowita) będącą wynikiem porównania pozycji przekazanego węzła względem danego węzła.

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 bit_mask = node.compareDocumentPosition(other);

gdzie poszczególne człony oznaczają:

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

  1. Niech reference wskazuje na obiekt kontekstu.
  2. Jeśli other i reference są tym samym obiektem, to zwróć zero.
  3. Jeśli other i reference nie należą do tego samego drzewa węzłów, to zwróć wynik będący zsumowaniem wartości z DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC i DOCUMENT_POSITION_PRECEDING lub DOCUMENT_POSITION_FOLLOWING, z wymuszeniem, że wybór między dwiema ostatnimi wartościami ma być realizowany w sposób zrównoważony..

    Zwrócenie DOCUMENT_POSITION_PRECEDING lub DOCUMENT_POSITION_FOLLOWING jest zazwyczaj implementowane za pomocą porównania wskaźnika (pointer comparison). W implementacji Javascript można zastosować polecenie Math.random(), co oznacza, że w masce bitowej stan wysoki dla jednego z tych bitów będzie wybierany losowo.

  4. Jeśli other jest przodkiem w reference, to zwróć wynik będący zsumowaniem wartości z DOCUMENT_POSITION_CONTAINS i DOCUMENT_POSITION_PRECEDING.
  5. Jeśli other jest potomkiem w reference, to zwróć wynik będący zsumowaniem wartości z DOCUMENT_POSITION_CONTAINED_BY i DOCUMENT_POSITION_FOLLOWING.
  6. Jeśli other poprzedza reference, to zwróć wartość z DOCUMENT_POSITION_PRECEDING.
  7. Zwróć wartość z DOCUMENT_POSITION_FOLLOWING.

Maska bitowa zwracana przez metodę compareDocumentPosition() to liczba całkowita typu unsigned short, co oznacza, że może przyjąć wartości od 0 do 65535 (szesnaście bitów), chociaż metoda operuje jedynie na zakresie od 0 do 64 (sześć bitów). Dla osób nieobytych z zapisem dwójkowym pewnym problemem będzie rozpoznanie znaczenia poszczególnych bitów. W poniższej tabeli zamieszczam relację między wartością w zapisie binarnym, dziesiętnym oraz odpowiadającą stałą.

Zapis binarnyZapis dziesiętnyOdpowiadająca stałaZnaczenie
0000000BrakWęzły są identyczne (czyli other to referencja do tego samego węzła, co node).
0000011DOCUMENT_POSITION_DISCONNECTEDWęzły nie należą do tego samego drzewa węzłów.
0000102DOCUMENT_POSITION_PRECEDINGWęzeł other poprzedza węzeł node.
0001004DOCUMENT_POSITION_FOLLOWINGWęzeł other następuje po węźle node.
0010008DOCUMENT_POSITION_CONTAINSWęzeł other zawiera węzeł node.
01000016DOCUMENT_POSITION_CONTAINED_BYWęzeł other jest zawarty przez węzeł node.
10000032DOCUMENT_POSITION_IMPLEMENTATION_SPECIFICDo prywatnego użytku przez implementację. W praktyce ustawiane na tych samych zasadach, co DOCUMENT_POSITION_DISCONNECTED.

Po wywołaniu metody compareDocumentPosition() w zwracanej masce bitowej będziemy mieli zapisane wszystkie informacje na temat relacji między węzłami. Niestety maska bitowa zawsze ma postać dziesiętną, dlatego dla ułatwienia najlepiej zamienić ją na zapis binarny.

Przeanalizujmy jeden teoretyczny przykład, gdzie zwrócona została liczba dziesiętna 20, którą możemy rozpisać następująco (w nawiasach znajduje się zapis dziesiętny):

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
010100 (20) = 000100 (4) + 010000 (16)

Z takiego zapisu możemy wywnioskować następujące rzeczy:

W zasadzie to wystarczy przeanalizować stan każdego bitu w zwracanej wartości (zero lub jeden) , nie ma konieczności rozbijania tego na równanie, choć dla osób początkujących może być to sporym ułatwieniem. Na masce bitowej najczęściej wykonuje się mnożenie w celu określenia, czy dany bit jest ustawiony, czy też nie. Są to podstawy systemu dwójkowego, które wynosi się ze szkoły o profilach elektroniczno-informatycznych.

Więcej informacji oraz przykłady praktycznego wykorzystania metody compareDocumentPosition() opisał John Resig w artykule "Comparing Document Position".

Prosty przykład:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<script>

	var doc = document; // referencja do document
	var newDocXML = document.implementation.createDocument(null, null, null); // nowy dokument XML

	// Porównanie tego samego węzła
	doc.write(doc.compareDocumentPosition(doc)); // 0(d) 00000000(b)
	document.write("<br>");

	// Porównanie węzłów w różnych drzewach węzłów
	doc.write(doc.compareDocumentPosition(newDocXML)); // 35(d) 100011(b) lub 37(d) 100101(b) - zwracane losowo
	document.write("<br>");

	// Porównanie węzłów w różnych drzewach węzłów
	doc.write(newDocXML.compareDocumentPosition(doc)); // 35(d) 100011(b) lub 37(d) 100101(b) - zwracane losowo
	document.write("<br>");

	// Porównanie węzłów w różnych drzewach węzłów
	doc.write(doc.compareDocumentPosition(doc.createElement("div"))); // 35(d) 100011(b) lub 37(d) 100101(b) - zwracane losowo
	document.write("<br>");

	// Porównanie węzłów w różnych drzewach węzłów
	doc.write(doc.createElement("div").compareDocumentPosition(doc)); // 35(d) 100011(b) lub 37(d) 100101(b) - zwracane losowo
	document.write("<br>");

	// Porównanie węzłów w różnych drzewach węzłów
	doc.write(doc.createElement("div").compareDocumentPosition(doc.createElement("div"))); // 35(d) 100011(b) lub 37(d) 100101(b) - zwracane losowo
	document.write("<br>");

	// Porównanie węzłów w tym samym drzewie węzłów
	doc.write(doc.compareDocumentPosition(doc.documentElement)); // 20(d) 010100(b)
	document.write("<br>");

	// Porównanie węzłów w tym samym drzewie węzłów
	doc.write(doc.documentElement.compareDocumentPosition(doc)); // 10(d) 001010(b)

	document.write("<br><br>");

	// Pobranie wartości ze stałych
	doc.write(doc.DOCUMENT_POSITION_DISCONNECTED); // 1(d) 000001(b)
	document.write("<br>");
	doc.write(doc.DOCUMENT_POSITION_PRECEDING); // 2(d) 000010(b)
	document.write("<br>");
	doc.write(doc.DOCUMENT_POSITION_FOLLOWING); // 4(d) 000100(b)
	document.write("<br>");
	doc.write(doc.DOCUMENT_POSITION_CONTAINS); // 8(d) 001000(b)
	document.write("<br>");
	doc.write(doc.DOCUMENT_POSITION_CONTAINED_BY); // 16(d) 010000(b)
	document.write("<br>");
	doc.write(doc.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC); // 32(d) 100000(b)

</script>

Składnia Web IDL#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
interface Node : EventTarget {
	unsigned short compareDocumentPosition(Node other);
}

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

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