问题描述
我想实现compareDocumentPosition。 Resig已经制作了。我已经把他的代码整理好了
I want to implement compareDocumentPosition. Resig has made a great start at doing just this. I've taken his code and neatened it up
function compareDocumentPosition(other) {
var ret = 0;
if (this.contains) {
if (this !== other && this.contains(other)) {
ret += 16;
}
if (this !== other && other.contains(this)) {
ret += 8;
}
if (this.sourceIndex >= 0 && other.sourceIndex >= 0) {
if (this.sourceIndex < other.sourceIndex) {
ret += 4;
}
if (this.sourceIndex > other.sourceIndex) {
ret += 2;
}
} else {
ret += 1;
}
}
return ret;
}
这适用于元素
但不适用于文本
或 DocumentFragment
。这是因为IE8在这些节点上没有给出 .sourceIndex
。 (它不会给 .contains
,但我已经解决了这个问题)
This works for Element
but does not for Text
or DocumentFragment
. This is because IE8 does not give .sourceIndex
on those nodes. (It doesn't give .contains
either but I've fixed that problem already)
我如何有效率写 + = 4
和 + = 2
位,对应和。
How do I efficiently write the +=4
and +=2
bit which correspond to DOCUMENT_POSITION_FOLLOWING and DOCUMENT_POSITION_PRECEDING.
额外费用这两个是由树顺序定义的,DOM4定义为
For extra reference those two are defined by tree-order which DOM4 defines as
如果A和B在同一棵树中,A在B之后,则对象A跟随对象B.订单。
An object A is following an object B if A and B are in the same tree and A comes after B in tree order.
树顺序是预购,深度优先遍历。
The tree order is preorder, depth-first traversal.
最现代的br owsers实现了这个(包括IE9)。所以你只需要在IE8中工作的东西(我不关心IE6 / 7,但如果它工作得很棒!)
Most modern browsers implement this (including IE9). So you only need something that works in IE8 (I don't care about IE6/7, but if it works awesome!)
推荐答案
function recursivelyWalk(nodes, cb) {
for (var i = 0, len = nodes.length; i < len; i++) {
var node = nodes[i];
var ret = cb(node);
if (ret) {
return ret;
}
if (node.childNodes && node.childNodes.length) {
var ret = recursivelyWalk(node.childNodes, cb);
if (ret) {
return ret;
}
}
}
}
function testNodeForComparePosition(node, other) {
if (node === other) {
return true;
}
}
function compareDocumentPosition(other) {
function identifyWhichIsFirst(node) {
if (node === other) {
return "other";
} else if (node === reference) {
return "reference";
}
}
var reference = this,
referenceTop = this,
otherTop = other;
if (this === other) {
return 0;
}
while (referenceTop.parentNode) {
referenceTop = referenceTop.parentNode;
}
while (otherTop.parentNode) {
otherTop = otherTop.parentNode;
}
if (referenceTop !== otherTop) {
return Node.DOCUMENT_POSITION_DISCONNECTED;
}
var children = reference.childNodes;
var ret = recursivelyWalk(
children,
testNodeForComparePosition.bind(null, other)
);
if (ret) {
return Node.DOCUMENT_POSITION_CONTAINED_BY +
Node.DOCUMENT_POSITION_FOLLOWING;
}
var children = other.childNodes;
var ret = recursivelyWalk(
children,
testNodeForComparePosition.bind(null, reference)
);
if (ret) {
return Node.DOCUMENT_POSITION_CONTAINS +
Node.DOCUMENT_POSITION_PRECEDING;
}
var ret = recursivelyWalk(
[referenceTop],
identifyWhichIsFirst
);
if (ret === "other") {
return Node.DOCUMENT_POSITION_PRECEDING;
} else {
return Node.DOCUMENT_POSITION_FOLLOWING;
}
}
我自己写的。我认为这个实现被窃听了,但这是我的其他一些代码中的一个错误。看起来很稳固。
I wrote it myself. I thought this implementation was bugged but it was a bug in some other code of mine. Seems pretty solid.
这篇关于跨浏览器比较文档位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!