获取从一个节点到另一个节点的 DOM 路径
Get DOM path from a node to another
我需要一种方法,该方法作为参数两个节点(node1
和node2
(,返回从node1
node2
的最小路径。理想情况下,它返回一个节点数组,但目前对字符串是可以的。所以例如:
P
/ '
#text U
/ '
B I
| |
#text #text
function foo(node1, node2) {
...
}
当我以这种方式运行时,例如在节点P
(根(和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
(,则甚至返回这些属性(如示例中所示(。我搜索了做类似事情的互联网方法,但我只找到了返回整个文档的完整路径而不是两个节点之间的方法。例如,我试过这种方法对我不起作用,因为它返回单个节点的完整路径。
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
}
另一件事,我会使用纯JavaScript,而不是jQuery。我不知道如何做我需要的,您的帮助将不胜感激。
谢谢
<!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>
编辑:当节点相等时,它会进入无限循环,所以我为此添加了一个检查。
相关文章:
- 将节点数据分配给另一个变量jstree
- 文件的节点自动化移动到另一个文件夹中
- 如果某个值在另一个节点中,我如何每秒自动单击一个链接
- XPath以基于另一个节点按位置选择节点's的位置
- 如何根据另一个节点中的数据对 Firebase 阵列进行排序
- 节点 js 从客户端和另一个节点模块调用相同的延迟函数
- 节点js可以计算两个输入字段的值并更新另一个字段吗?
- 节点群集未将任务分派给另一个可用的工作线程
- JQuery函数绑定到身体节点的点击事件,另一个点击事件立即执行
- 节点.js - 从另一个函数/对象发出事件
- 在节点 JS 中将值从一个对象更新到另一个对象
- 使用 node.js 启动另一个节点应用程序
- 如何在我的节点中包含另一个参数.js Web 服务
- 使用 Vim 作为 Javascript 沙箱:如何将缓冲区写入节点并在另一个缓冲区中读取结果
- 获取父节点p,即使其中有另一个标记
- 如何使用XPATH检索具有一个或另一个值的节点
- 如何将svg节点从一个组移动到另一个组
- 将父节点更改为另一个
- 在使用d3js单击另一个节点时添加节点
- 递归地获取另一个标记中的所有标记节点