从节点确定文档顺序

时间:2009-08-17 22:55:16

标签: javascript html dom

如果我在HTML文档中有两个节点,如何使用DOM方法在Javascript中以HTML文档顺序排出哪个节点?

例如,

function funstuff(a, b) {
    //a and b can be any node in the DOM (text, element, etc)
    if(b comes before a in document order) {
        var t = b; b = a; a = t;
    }
    // process the nodes between a and b. I can handle this part 
    // when I know that a comes before b.
}

3 个答案:

答案 0 :(得分:5)

Resig to the rescue

// Compare Position - MIT Licensed, John Resig
function comparePosition(a, b){
  return a.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 < b.sourceIndex && 4) +
            (a.sourceIndex > b.sourceIndex && 2) :
          1) +
      0 :
      0;
}

答案 1 :(得分:4)

您可以使用DOM函数compareDocumentPosition,它将根据两个节点的关系返回不同的数字:

DOCUMENT_POSITION_DISCONNECTED = 0x01;
DOCUMENT_POSITION_PRECEDING = 0x02;
DOCUMENT_POSITION_FOLLOWING = 0x04;
DOCUMENT_POSITION_CONTAINS = 0x08;
DOCUMENT_POSITION_CONTAINED_BY = 0x10;

结果可能是这些代码中不止一个的总和,因为答案是位掩码,但我无法想象这两种情况同时存在的情况。另请注意,“断开连接”的结果将返回,例如,已经创建但尚未添加到文档树的节点

答案 2 :(得分:1)

相当困难,我个人会想到每个树,直到我找到一个共同的ansester,然后检查哪个父节点(或实际节点,如果那个低)首先从firstChild开始并通过兄弟姐妹工作,如:

  function OrderCheck(node1, node2){

     var ar1 = [null, node1];
     var ar2 = [null, node2];

     for(var i = 1; ar1[i] != null; i++)
       ar1[i+1]=ar1[i].parentNode;
     for(var i = 1; ar2[i] != null; i++)
       ar2[i+1]=ar2[i].parentNode;
     ar1.reverse(); ar2.reverse(); // easier to work with.
     i = 0;
     while( ar1[i] === ar2[i] ){
       if(ar1[i] === null)
         return 0;
       else
         i++
     }

     if(ar1[i] === null)
       return 2;
     if(ar2[i] === null)
       return 1;

     if(i != 0){
       var n = ar1[i-1].firstChild;
       do{
         if(n === ar1[i])
           return 1;
         if(n === ar2[i])
           return 2;
       }while(n = n.nextSibling);
     }
        return -1;// Shouldn't happen.
  }

  var order = OrderCheck(document.body, document.body.previousSibling);
  if( order == 1){
         // element 1 first
  }else if(order == 2){
         // element 2 first
  }else{
         // there was an error.
  }

我只是编辑了这段代码,试图解决两个可能的问题,但我没有测试过这个新的编辑,所以如果有什么问题,我将不得不再试一次。 (再次编辑以修复“甚至不运行”的样式错误)。