Deep Node.compareDocumentPosition API

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 sourceIndexused to determine.

2. Deep understanding

compareDocumentPositionThe syntax is as follows:

compareValue = node.compareDocumentPosition(otherNode)

Note: There is a place that is easy to remember. Is the returned position relationship noderelative otherNodeor otherNoderelative node? The result actually returned is the otherNoderelative nodeposition!

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, otherNodeyou are in front and otherNodeyou are behind, like this.

The return value
compareValue 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 10and respectively 20. among them:

  • 108+2The combined value of yes 8means that it is documentElementincluded bodyand 2that it is documentElementin bodyfront.
  • 2016+4The combined value of yes 16means that it bodyis documentElementincluded, which 4means bodyit documentElementfollows.

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 1it too 1, as long as one of 0it is 0, the final value is the binary value calculation.

For example, numbers 2and 8comparisons, as shown below:

AND result of 2 and 8

2 & 8; // The result is 00000, which is 0

How about comparing numbers 2with numbers 10? As shown below:

2 and 10 and compare

2 & 10; // The result is 00010, which is 2

Since the compareDocumentPositionreturn 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

compareDocumentPositionIt 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.bodyfirst (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:

Position is 35

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_DISCONNECTEDsuch 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!

Guess you like

Origin blog.csdn.net/lu92649264/article/details/113102470