Javascript 获取从一个节点到另一个节点的DOM路径

Javascript 获取从一个节点到另一个节点的DOM路径,javascript,dom,path,Javascript,Dom,Path,我需要一个方法,将两个节点(node1和node2)作为参数,返回从node1到node2的最小路径。 理想情况下,它返回一个节点数组,但目前它可以返回一个字符串。例如: P / \ #text U / \ B I | | #text #text function foo(node1, node2) { ... } 当我以这种方式运行它时,例如在节点p(roo

我需要一个方法,将两个节点(
node1
node2
)作为参数,返回从
node1
node2
的最小路径。 理想情况下,它返回一个节点数组,但目前它可以返回一个字符串。例如:

        P
      /   \
  #text    U
         /   \
        B     I
        |     |
     #text   #text

function foo(node1, node2) {
    ...
}
当我以这种方式运行它时,例如在节点
p
(root)和
B

var res = foo(P, B);
console.log(res);
我获得:

res = Array[3] {
    0: P (class=..., id=...)
    1: U (class=..., id=...)
    2: B (class=..., id=...)
}
或者,以字符串的形式:

res = "P(class=..., id=...) > U(class=..., id=...) > B(class=..., id=...)";
如果节点具有属性(例如
id
class
),则返回这些属性(如示例所示)。 我搜索了做类似事情的internet方法,但只找到了返回整个文档完整路径的方法,而不是两个节点之间的方法。 例如,我尝试了这个方法,但它不适用于我,因为它返回单个节点的完整路径

function getDomPath(el) {
  var stack = [];
  while ( el.parentNode != null ) {
    console.log(el.nodeName);
    var sibCount = 0;
    var sibIndex = 0;
    for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
      var sib = el.parentNode.childNodes[i];
      if ( sib.nodeName == el.nodeName ) {
        if ( sib === el ) {
          sibIndex = sibCount;
        }
        sibCount++;
      }
    }
    if ( el.hasAttribute('id') && el.id != '' ) {
      stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
    } else if ( sibCount > 1 ) {
      stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');
    } else {
      stack.unshift(el.nodeName.toLowerCase());
    }
    el = el.parentNode;
  }

  return stack.slice(1); // removes the html element
}
函数getDomPath(el){ var堆栈=[]; while(el.parentNode!=null){ 控制台日志(el.nodeName); var-sibCount=0; var-sibIndex=0; 对于(var i=0;i1){ stack.unshift(el.nodeName.toLowerCase()+':eq(“+sibIndex+”); }否则{ stack.unshift(el.nodeName.toLowerCase()); } el=el.parentNode; } return stack.slice(1);//删除html元素 } 另外,我会使用纯JavaScript,而不是jQuery。 我不知道如何做我需要的,a你的帮助将不胜感激

谢谢


<!DOCTYPE html>

<html>
<script>

window.onload = function() {
    console.log(min_path(
        document.getElementById("4"),
        document.getElementById("9")
    ));
};

function min_path(node1, node2) {
    if(node1 === node2) {
        return node1;
    }

    var node_1_ancestors = get_ancestors(node1);
    var node_2_ancestors = get_ancestors(node2);

    var divergent_index = 0;
    while(node_1_ancestors[divergent_index] === node_2_ancestors[divergent_index]) {
        divergent_index++;
    }

    var path = [];
    for(var i = node_1_ancestors.length - 1; i >= divergent_index - 1; i--) {
        path.push(node_1_ancestors[i]);
    }
    for(var i = divergent_index; i < node_2_ancestors.length; i++) {
        path.push(node_2_ancestors[i]);
    }

    return path;
}

function get_ancestors(node) {
    var ancestors = [node];
    while(ancestors[0] !== null) {
        ancestors.unshift(ancestors[0].parentElement);
    }
    return ancestors;
}

</script>
</head>
<body>
<div id="0">
    <div id="1">
        <div id="2">
            <span id="3"></span>
            <span id="4">node1</span>
        </div>
        <div id="5">
            <p id="6"></p>
            <span id="7">
                <div id="8">
                    <div id="9">node2</div>
                    <div id="10"></div>
                </div>
            </span>
        </div>  
    </div>
    <div id="11"></div>
</div>
</body>
</html>
window.onload=函数(){ console.log(最小路径( 文件.getElementById(“4”), 文件getElementById(“9”) )); }; 功能最小路径(节点1、节点2){ 如果(节点1==节点2){ 返回节点1; } var node_1_祖先=获取_祖先(node1); var node_2_祖先=获取_祖先(node2); var发散指数=0; 而(节点1\u祖先[发散\u索引]==节点2\u祖先[发散\u索引]){ 发散指数++; } var路径=[]; 对于(var i=节点长度-1;i>=发散指数-1;i--){ push(node_1_祖先[i]); } 对于(var i=发散指数;i

节点2

编辑:当节点相等时,它将进入无限循环,因此我添加了一个检查。

确保您看到我的编辑。