JS Magic Hall: Determine node location relationship

Source: Internet
Author: User

First, preface

In the Polyfill queryselectorall and write pop-up windows need to determine the position between the two nodes, through jquery we can easily fix, but native JS? Below I will collate various judgment methods for future reference.

Ii. relations between our grandchildren

Html

<div id="ancestor">    <div id="parent">        <div id="son">son</div>    </div></div><div id="  Other">other</div>

Common.js

var ancestor = document.getElementById ('ancestor'); var parent = document.getElementById ('parent '); var son = document.getElementById ('son'); var other = document.getElementById ('other');

Method One: Through the Selection object

/** Define and determine the relationship function * @param {htmlelement} parentnode * @param {htmlelement} sonnode*/varhas =function (parentnode, Sonnode) {
if (parentnode = = = Sonnode) return true;
varSelection =window.getselection (); Selection.selectallchildren (parentnode); varret = Selection.containsnode (Sonnode,false); returnret; };//calledConsole.log (Has (ancestor, son));//Display TrueConsole.log (Have (ancestor, other));//Show False

Cons: Only FF support, other browsers are not valid

1. When executing selection.selectallchildren (parentnode) , the content of parentnode will be highlighted and the original highlighted part will be canceled;

2. Under Chrome, Selection.containsnode () constant returns false ;

3. The selection type object under Ie9~11 has no Containsnode method;

4. There is no selection type under ie5.5~8;

About the [object Selection] and [object msselection] types under IE (More on JS Magic Hall: Detailing Selection and msselection types)

1. IE11 only [object Selection] Type

Access method: document.getselection () or window.getselection ()

2. ie9~10 There are two types of [object Msselection] and [object Selection]

Get [Object Msselection]: document.selection

Get [Object Selection]: document.getselection () and window.getselection ()

3. IE5.5~IE8 only [object Msselection] Type

Get way: document.selection

Note: Document.selection is a unique attribute of IE.

method Two: Through the Range object

 var  has = function (ParentNode, Sonnode) { 
if (parentnode = = = Sonnode) return true;
var r1 = Document.createrange (), R2 = Document.createrange (); R1.selectnode (parentnode); R2.selectnode (Sonnode); var startret = r1.compareboundarypoints (Range.start_to_start, R2); var endret = R1.compareboundarypoints ( Range.end_to_end, r2); var ret = Startret = =-1 & & endret = = = 1 return ret;};

Cons: Incompatible ie5.5~8 (supported by ie9+, FF, and Chrome)

1. Ie5.5~8 no document.createrange () method

About [Object Range], [object TextRange], and [object Controlrange] Types

The first thing to be clear is that [object Range] is standard, whereas [object TextRange] and [object Controlrange] are unique to ie.

(Details of "JS Magic Hall: Detailed range, TextRange and Controlrange type")

1. Creating [Object Range] objects with Document.createrange ()

2. Get the [object Range] Object by Window.getselection (). Getrangeat ({unsigned int32} index)

3. Get the [object TextRange] object through the Document.selection.createRange () or Document.selection.createRangeCollection () method and cannot be directly bound to a DOM fragment by the Selectnode method like the Range object content.

Method Three: Through the Contains method

var has = function (parentnode, sonnode) {  return  parentnode.contains (Sonnode);  };

Console.log (Has (ancestor, ancestor));//Returns True
Console.log (Has (ancestor, son));//Returns True
Console.log (Have (ancestor, other));//return False

Advantages : Simple and direct

cons : compatibility issues

Support--chrome, firefox9+, ie5+, opera9.64+ (estimated from 9.0+), safari5.1.7+

--FF not supported

Method Four: Through the Comparedocumentposition method

var has = function (parentnode, Sonnode) {
if (parentnode = = = Sonnode) return true;
var rawret = parentnode.comparedocumentposition (sonnode); var (+ ) ; return ret; };

Comparedocumentposition can be regarded as a big tool to compare the two node position relationship in the standard, not only can judge the relationship between grandchildren, but also can judge other relations OH

var ret = a.comparedocumentposition (B);

The return value of RET means the following:

Bits number Meaning
000000 0 Elements Consistent
000001 1 nodes in different documents (or one outside of the document)
000010 2 node B before node A
000100 4 node A before node B
001000 8 node B contains node A
010000 16 node A contains node B
100000 32 Private use of the browser

Method Five: Recursive traversal

 var  has = function (ParentNode, Sonnode) { 
if (parentnode = = = Sonnode) return true;
var P = Sonnode.parentnode; if (! return false Span style= "color: #000000;" >; else if (P!== ParentNode) { return has (ParentNode, p) ; else { return true ; }}

Pros : All browsers are common

cons : When the node level is deep, the efficiency is low.

Integrated programme I, from Masaki (http://m.cnblogs.com/57731/1583523.html?full=1):

//2013.1.24 by Masaki
function contains (Parentel, El, container) {//whether the first node has a second node//contains method support situation: Chrome+ firefox9+ ie5+, opera9.64+ (estimated from 9.0+), safari5.1.7+ if(Parentel = =el) { return true;
} if(!el | |!el.nodetype | | el.nodetype! =1) { return false; } if(parentel.contains) {returnParentel.contains (EL); } if(parentel.comparedocumentposition) {return!! (Parentel.comparedocumentposition (EL) & -); } varPrEl =El.parentnode; while(prEl && PrEl! =container) { if(PrEl = =Parentel)return true; PrEl=Prel.parentnode; } return false; }

Integrated programme two, from Sizzle (https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L688)

Note: The contains version of Sizzle is contains (Ancestor,ancestor) returns false.

//Element contains another//purposefully does not implement inclusive descendent//as in, a element does not contain itselfContains = Hascompare | | Rnative.test (docelem.contains)?function (A, b) {varAdown = A.nodetype = = =9?a.documentelement:a, Bup= b &&B.parentnode; returnA = = = Bup | | !! (bup && Bup.nodetype = = =1&&(Adown.contains?Adown.contains (BUP): A.comparedocumentposition&& a.comparedocumentposition (BUP) & -            )); }: Function (A, b) {if(b) { while((b =B.parentnode)) {if(b = = =a) {return true; }           }         }         return false; };

General Plan Three, my long, smelly version of ^_^

varrnative =/[^{]+\{\s*\[native code\]\s*\}/;varDocel =document.documentelement;varContains = Rnative.test (docel.contains) &&function (ancestor, descendant) {if(ancestor = = = descendant)return true; Ancestor= Ancestor.nodetype = = =9?Ancestor.documentElement:ancestor; returnAncestor.contains (descendant);} ||rnative.test (docel.comparedocumentposition)&&function (ancestor, descendant) {if(ancestor = = = descendant)return true; Ancestor= Ancestor.documentelement | |ancestor; return!! (Ancestor.comparedocumentposition (descendant) & -); } ||rnative.test (Document.createrange)&&function (ancestor, descendant) {if(ancestor = = = descendant)return true; varR1 = Document.createrange (), r2 =Document.createrange (); R1.selectnode (Ancestor.documentelement||ancestor); R2.selectnode (Descendant.documentelement||descendant);
  var Startret = r1.compareboundarypoints (range.start_to_start, r2);  var endret = r1.compareboundarypoints (range.end_to_end, R2);
var ret = Startret = = =-1 && endret = = = 1;
try{
R1.detach ();
R2.detach ();
}catch (e) {}

return ret;
} ||
function (ancestor, descendant) {
if (ancestor = = = descendant) return true;

var a = Ancestor.documentelement | | Ancestor
var b = (Descendant.documentelement | | descendant) [' ParentNode '];
while (!! b) {
  if (a = = B) return true;
b = B.parentnode;
}
return false;
};

Iii. Summary

Respect the original, reprint please specify from: http://www.cnblogs.com/fsjohnhuang/p/3931818.html ^_^ fat son John

JS Magic Hall: Determine node location relationship

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.