欢迎来到福编程网,本站提供各种互联网专业知识!

javascript比较文档位置

发布时间:2008-04-08 作者: 来源:转载
一个很棒的blog文章,是PPK两年前写的,文章中解释了contains()和compareDocumentPosition()方法运行在他们各自的浏览器上。从那起,我已经对这些方法做了大量的研究,并且已经在很多场合使用他们。在很多任务中,他们被证明是非常有用的(特别关于结构的抽象
1、DOMElement.contains(DOMNode)

这个方法起先用在IE,用来确定DOMNode是否包含在另一个DOMElement中。

当尝试优化CSS选择器遍历(像:“#id1#id2”),这个方法很有用。你可以通过getElementById得到元素,然后使用.contains()确定#id1实际上是否包含#id2。

注意点:如果DOMNode和DOMElement相一致,.contains()将返回true,虽然,一个元素不能包含自己。

这里有一个简单的执行包装,可以运行在:InternetExplorer,Firefox,Opera,andSafari。


functioncontains(a,b){
returna.contains?a!=b&&a.contains(b):!!(a.compareDocumentPosition(arg)&16);
}
2、NodeA.compareDocumentPosition(NodeB)

这个方法是DOMLevel3specification的一部分,允许你确定2个DOMNode之间的相互位置。这个方法比.contains()强大。这个方法的一个可能应用是排序DOMNode成一个详细精确的顺序。

使用这个方法你可以确定关于一个元素位置的一连串的信息。所有的这些信息将返回一个比特码(Bit,比特,亦称二进制位)。

对于那些,人们知之甚少。比特码是将多重数据存储为一个简单的数字(译者注:0或1)。你最终打开/关闭个别数目(译者注:打开/关闭对应0/1),将给你一个最终的结果。

这里是从NodeA.compareDocumentPosition(NodeB)返回的结果,包含你可以得到的信息。

BitsNumberMeaning
0000000元素一致
0000011节点在不同的文档(或者一个在文档之外)
0000102节点B在节点A之前
0001004节点A在节点B之前
0010008节点B包含节点A
01000016节点A包含节点B
10000032浏览器的私有使用

现在,这意味着一个可能的结果类似于:






一旦一个节点A包含另一个节点B,包含B(+16)且在B之前(+4),则最后的结果是数字20。如果你查看比特发生的变化,将增加你的理解。

000100(4)+010000(16)=010100(20)

这个,毫无疑问,有助于理解单个最混乱的DOMAPI方法。当然,他的价值当之无愧的。

现在,DOMNode.compareDocumentPosition在Firefox和Opera中是可用的。然而,有一些技巧,我们可以用来在IE中执行他。


//ComparePosition-MITLicensed,JohnResig
functioncomparePosition(a,b){
returna.compareDocumentPosition?
a.compareDocumentPosition(b):
a.contains?
(a!=b&&a.contains(b)&&16)+
(a!=b&&b.contains(a)&&8)+
(a.sourceIndex>=0&&b.sourceIndex>=0?
(a.sourceIndex(a.sourceIndex>b.sourceIndex&&2):
1):
0;
}
IE提供给我们一些可以使用的方法和属性。开始,使用.contains()方法(如我们前面所讨论的),以便给我们包含(+16)或者被包含(+8)的结果。IE还有一个.sourceIndex属性在所有的DOMElement对应着元素在文档中的位置,例如:document.documentElement.sourceIndex==0。因为我们有这个信息,我们可以完成两个compareDocumentPosition难题:在前面(+2)和在后面(+4)。另外,如果一个元素不在当前的文档,.sourceIndex将等于-1,这个给我们另外一个回答(+1)。最后,通过这个过程的推断,我们可以确定如果一个元素等于他本身,返回一个空的比特码(+0)。

这个函数可以在InternetExplorer、Firefox和Opera中运行。但在Safari中却有残缺功能(因为他只有contains()方法,而没有.sourceIndex属性。我们只能得到包含(+16),被包含(+8),其他的所有结果都将返回(+1)代表一个断开)。

PPK提供了一个关于通过创建一个getElementsByTagNames方法使新功能可以被使用的很棒的例子。让我们改编他到我们的新方法中:


//OriginalbyPPKquirksmode.org
functiongetElementsByTagNames(list,elem){
elem=elem||document;

vartagNames=list.split(','),results=[];

for(vari=0;ivartags=elem.getElementsByTagName(tagNames[i]);
for(varj=0;jresults.push(tags[j]);
}

returnresults.sort(function(a,b){
return3-(comparePosition(a,b)&6);
});
}
我们现在可以使用他来按次序构建一个站点的目录:


getElementsByTagNames("h1,h2,h3");
虽然Firefox和Opera都采取了一些主动落实这一方法。我依然期待看到更多的浏览器进入,以帮助向前推动。

相关推荐