One, quick understanding
The Node.compareDocumentPosition() method can be used to compare the positional relationship of two HTML nodes in the document, including front and back, parent and child, self and cross-document. The positional relationship of not only DOM nodes, text nodes, comment nodes and even attribute nodes can be determined, which is very strong.
IE9+ browser support, IE8 can be sourceIndex
used to determine.
2. Deep understanding
compareDocumentPosition
The syntax is as follows:
compareValue = node.compareDocumentPosition(otherNode)
Note: There is a place that is easy to remember. Is the returned position relationship node
relative otherNode
or otherNode
relative node
? The result actually returned is the otherNode
relative node
position!
It may be the difference between Chinese culture and foreign culture. Chinese culture is introverted, sticks to attachments, pays attention to oneself, and tells what to do; foreign cultures outwards, armed aggression, and gesticulation are all what you should do.
Since these API grammars were invented by foreigners, they are conceptually based on the understanding of foreigners. The node node challenged otherNode to judge the document position. The final result is not that I won or I lost, but you lost or you won. That is, otherNode
you are in front and otherNode
you are behind, like this.
The return valuecompareValue
is the return value, which is an integer value. The possible values are as follows:
Binary | return value | Paraphrase | Corresponding constant |
---|---|---|---|
000000 | 0 | Node is consistent | – |
000001 | 1 | The node is in a different document (or one is outside the document) | Node.DOCUMENT_POSITION_DISCONNECTED |
000010 | 2 | Node otherNode before node node | Node.DOCUMENT_POSITION_PRECEDING |
000100 | 4 | Node otherNode is after node node | Node.DOCUMENT_POSITION_FOLLOWING |
001000 | 8 | Node otherNode contains node node | Node.DOCUMENT_POSITION_CONTAINS |
010000 | 16 | Node otherNode is included by node node | Node.DOCUMENT_POSITION_CONTAINED_BY |
100000 | 32 | Specific node location depends on DOM implementation | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
– | Combination value (such as 34, 32+2) | Composite node relationship | – |
Regarding the composite return value of the composite node relationship, we will start with the simple position relationship and get familiar with this API.
// The return value is 0 document.body.compareDocumentPosition(document.body); // The return value is 4, <body> is behind <head> document.head.compareDocumentPosition(document.body)
Next, we look at the combined value returned under the composite node relationship, as follows:
// The return value is 10, 8 + 2 document.body.compareDocumentPosition(document.documentElement); // The return value is 20, 16 + 4 document.documentElement.compareDocumentPosition(document.body)
The return values are 10
and respectively 20
. among them:
10
8+2
The combined value of yes8
means that it isdocumentElement
includedbody
and2
that it isdocumentElement
inbody
front.20
16+4
The combined value of yes16
means that itbody
isdocumentElement
included, which4
meansbody
itdocumentElement
follows.
Therefore, when we actually develop, we cannot ==
judge the positional relationship directly equal to a constant value, but we need to use other operators, such as bitwise operators &
. In JS, a &
represents an operator with the two binary numbers is a bitwise comparison for each, as well as 1
it too 1
, as long as one of 0
it is 0
, the final value is the binary value calculation.
For example, numbers 2
and 8
comparisons, as shown below:
2 & 8; // The result is 00000, which is 0
How about comparing numbers 2
with numbers 10
? As shown below:
2 & 10; // The result is 00010, which is 2
Since the compareDocumentPosition
return value is standard, only 1 bit is a binary value of 1, therefore, it is necessary to judge the position relationship between the front and back or the inner and outer nodes directly by bitwise AND, and the result is not 0.
E.g:
if (document.body.compareDocumentPosition(document.documentElement) & Node.DOCUMENT_POSITION_PRECEDING) { // document.documentElement在document.body前面 // ... }
A character &
instead of ==
yo.
Three, go further
compareDocumentPosition
It can also be used to compare the front and back position relationship of HTML attribute nodes, such as the following HTML:
<img id="compareImg" src="./mm.jpg" alt="示意图">
var altNode = compareImg.getAttributeNode('alt'); var srcNode = compareImg.getAttributeNode('src'); // 结果是34 = 32 + 2 console.log(altNode.compareDocumentPosition(srcNode));
If the 'src'
and 'alt'
attribute positions in the HTML code are replaced, as follows:
<img id="compareImg" alt="示意图" src="./mm.jpg">
The result is:
// The result is 36 = 32 + 4 console.log(altNode.compareDocumentPosition(srcNode));
How does the return value 1 appear?
When our node is in memory and no longer in the document page, or our node is in another iframe within the page, the return value includes 1
.
E.g:
// The result is 35 = 32 + 2 + 1 document.createElement('div').compareDocumentPosition(document.body)
That is, the specific implementation (32), the document.body
first (2), the two documents are not related (1).
For another example, we directly use Blob to dynamically create a non-external link iframe , the code is as follows:
var htmlIframe = '<img id="img" src="https://.../mm.jpg" οnclick="console.log(this.compareDocumentPosition(window.parent.document.body))">'; var iframe = document.createElement('iframe'); var blob = new Blob([htmlIframe], { 'type': 'text/html'}); iframe.src = URL.createObjectURL(blob); iframeBlob1.appendChild(iframe);
The real-time effect is as follows, click on the picture of the girl to see the output result?
The result is 35 (32 + 2 + 1), as shown below:
Four, application scenarios
When do we need to know the front and back position of the node? In some animation+absolute positioning implementations of the slide page transition scene, since the slide direction of returning to the previous page is opposite, we can judge whether the page goes out from right to left or from left to the front and back position relationship of the node. Go out right.
For example, on this demo page , click the tab at the bottom to see different transition directions, which are judged by the compareDocumentPosition method.
You can also click on the video experience below:
Five, conclusion
I’m still too young. At first, I thought about this API too simple. I thought that some positions returned some fixed numbers. I didn’t expect the returned positions to be mixed. The advantage is that we can accurately know the position of certain element nodes in the page. The disadvantage of complicated positional relationship is that it increases our learning and understanding costs.
In fact, we actually develop very few scenes where we need to know very detailed location relationships.
It is recommended to use Node.DOCUMENT_POSITION_DISCONNECTED
such constants for comparison in actual development , which is easier to understand and more readable. The key problem is not easy to remember, and there is no way. Check the document or search on this site compareDocumentPosition
.
Okay, that's all, thanks for reading!