Javascript 跨浏览器比较文档位置
我想实现ComparedDocumentPosition。雷西格做了一个决定。我已经把他的密码整理好了Javascript 跨浏览器比较文档位置,javascript,internet-explorer-8,shim,dom4,Javascript,Internet Explorer 8,Shim,Dom4,我想实现ComparedDocumentPosition。雷西格做了一个决定。我已经把他的密码整理好了 function compareDocumentPosition(other) { var ret = 0; if (this.contains) { if (this !== other && this.contains(other)) { ret += 16; } if (this !=
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;
}
功能比较文档位置(其他){
var-ret=0;
if(this.contains){
if(this!==other&&this.contains(other)){
ret+=16;
}
如果(this!==other&&other.contains(this)){
ret+=8;
}
如果(this.sourceIndex>=0&&other.sourceIndex>=0){
if(this.sourceIndexother.sourceIndex){
ret+=2;
}
}否则{
ret+=1;
}
}
返回ret;
}
这适用于元素
,但不适用于文本
或文档片段
。这是因为IE8没有在这些节点上提供.sourceIndex
。(它也不提供。contains
,但我已经解决了这个问题)
如何有效地编写与and相对应的+=4
和+=2
位
作为额外参考,这两个由DOM4定义为的树顺序定义
如果A和B在同一棵树中,且A按树的顺序排在B之前,则对象A在对象B之前
如果A和B在同一棵树中,且A按树的顺序排在B之后,则对象A在对象B之后
树的顺序是预顺序,深度优先遍历
大多数现代浏览器都实现了这一点(包括IE9)。因此,您只需要在IE8中工作的东西(我不关心IE6/7,但如果它工作得很好的话!)函数recursivelyWalk(nodes,cb){
对于(var i=0,len=nodes.length;i
我自己写的。我认为这个实现有缺陷,但这是我的其他代码中的一个缺陷。看起来很可靠。雷诺斯的答案是最好的开始,但不是开箱即用<代码>节点。*无法找到,并且IE8中没有
.bind
以下是可在Internet Explorer 8中使用的代码:
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;
}
}
var DOCUMENT_POSITION_DISCONNECTED = 1;
var DOCUMENT_POSITION_PRECEDING = 2;
var DOCUMENT_POSITION_FOLLOWING = 4;
var DOCUMENT_POSITION_CONTAINS = 8;
var DOCUMENT_POSITION_CONTAINED_BY = 16;
function compareDocumentPosition(thisNode, other) {
function identifyWhichIsFirst(node) {
if (node === other) {
return "other";
} else if (node === reference) {
return "reference";
}
}
var reference = thisNode,
referenceTop = thisNode,
otherTop = other;
if (this === other) {
return 0;
}
while (referenceTop.parentNode) {
referenceTop = referenceTop.parentNode;
}
while (otherTop.parentNode) {
otherTop = otherTop.parentNode;
}
if (referenceTop !== otherTop) {
return DOCUMENT_POSITION_DISCONNECTED;
}
var children = reference.childNodes;
var ret = recursivelyWalk(
children,
function(p) {
(function() {
var localOther = other;
return testNodeForComparePosition(localOther, p);
})();
}
);
if (ret) {
return DOCUMENT_POSITION_CONTAINED_BY +
DOCUMENT_POSITION_FOLLOWING;
}
var children = other.childNodes;
var ret = recursivelyWalk(
children,
function(p) {
(function() {
var localOther = reference;
return testNodeForComparePosition(localOther, p);
})();
}
);
if (ret) {
return DOCUMENT_POSITION_CONTAINS +
DOCUMENT_POSITION_PRECEDING;
}
var ret = recursivelyWalk(
[referenceTop],
identifyWhichIsFirst
);
if (ret === "other") {
return DOCUMENT_POSITION_PRECEDING;
} else {
return DOCUMENT_POSITION_FOLLOWING;
}
}
(这就像调用
sourceElement.compareDocumentPosition(elementToTest)
)哦,雷诺斯,你太棒了。谢谢你回答我的问题question@TimDown我睡得不够。
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;
}
}
var DOCUMENT_POSITION_DISCONNECTED = 1;
var DOCUMENT_POSITION_PRECEDING = 2;
var DOCUMENT_POSITION_FOLLOWING = 4;
var DOCUMENT_POSITION_CONTAINS = 8;
var DOCUMENT_POSITION_CONTAINED_BY = 16;
function compareDocumentPosition(thisNode, other) {
function identifyWhichIsFirst(node) {
if (node === other) {
return "other";
} else if (node === reference) {
return "reference";
}
}
var reference = thisNode,
referenceTop = thisNode,
otherTop = other;
if (this === other) {
return 0;
}
while (referenceTop.parentNode) {
referenceTop = referenceTop.parentNode;
}
while (otherTop.parentNode) {
otherTop = otherTop.parentNode;
}
if (referenceTop !== otherTop) {
return DOCUMENT_POSITION_DISCONNECTED;
}
var children = reference.childNodes;
var ret = recursivelyWalk(
children,
function(p) {
(function() {
var localOther = other;
return testNodeForComparePosition(localOther, p);
})();
}
);
if (ret) {
return DOCUMENT_POSITION_CONTAINED_BY +
DOCUMENT_POSITION_FOLLOWING;
}
var children = other.childNodes;
var ret = recursivelyWalk(
children,
function(p) {
(function() {
var localOther = reference;
return testNodeForComparePosition(localOther, p);
})();
}
);
if (ret) {
return DOCUMENT_POSITION_CONTAINS +
DOCUMENT_POSITION_PRECEDING;
}
var ret = recursivelyWalk(
[referenceTop],
identifyWhichIsFirst
);
if (ret === "other") {
return DOCUMENT_POSITION_PRECEDING;
} else {
return DOCUMENT_POSITION_FOLLOWING;
}
}
compareDocumentPosition(sourceElement, elementToTest)