我正在寻找一个函数,它可以在祖先,兄弟和后代方面返回DOM中元素之间的“距离”。 例如,假设我有:
<div id="div1">
<div id="div5"></div>
</div>
<div id="div2">
<div id="div6">
<div id="div9"></div>
</div>
<div id="div7"></div>
</div>
<div id="div3"></div>
<div id="div4">
<div id="div8">
<div id="div10"></div>
</div>
</div>
然后我想要一个能够返回#div5
和#div10
之间距离的函数,如:
{
up: 1,
across: 3,
down: 2
}
从#div5
到#div10
,你必须上升一代,转发3个兄弟姐妹(到#div4
)然后再向下2代。
同样,#div9
到#div1
会返回:
{
up: 2,
across: -1,
down: 0
}
上升两代,然后回到一个兄弟。
我已经有了这样做的功能(我将在下面作为答案包括在内)所以我在这里包括它因为a)我认为其他人可能会发现它有用; b)也许其他人有更好的方法。
答案 0 :(得分:2)
好的,这就是我拥有的东西。我希望在代码评论中能够很好地解释它:
function DOMdistance(elem1,elem2) {
if (elem1 === elem2) {
return {
up: 0,
across: 0,
down: 0
};
}
var parents1 = [elem1],
parents2 = [elem2],
gens = 1,
sibs = 0,
sibElem;
// searches up the DOM from elem1 to the body, stopping and
// returning if it finds elem2 as a direct ancestor
while (elem1 !== document.body) {
elem1 = elem1.parentNode;
if (elem1 === elem2) {
return {
up: parents1.length,
across: 0,
down: 0
};
}
parents1.unshift(elem1);
}
// reset value of elem1 for use in the while loop that follows:
elem1 = parents1[parents1.length - 1];
// searches up the DOM from elem2 to the body, stopping and
// returning if it finds elem1 as a direct ancestor
while (elem2 !== document.body) {
elem2 = elem2.parentNode;
if (elem2 === elem1) {
return {
up: 0,
across: 0,
down: parents2.length
};
}
parents2.unshift(elem2);
}
// finds generation depth from body of first generation of ancestors
// of elem1 and elem2 that aren't common to both
while (parents1[gens] === parents2[gens]) {
gens++;
}
sibElem = parents1[gens];
// searches forward across siblings from the earliest non-common ancestor
// of elem1, looking for earliest non-common ancestor of elem2
while (sibElem) {
sibElem = sibElem.nextSibling;
if (sibElem && sibElem.tagName) {
sibs++;
if (sibElem === parents2[gens]) {
return {
up: parents1.length - gens - 1,
across: sibs,
down: parents2.length - gens - 1
};
}
}
}
sibs = 0;
sibElem = parents1[gens];
// searches backward across siblings from the earliest non-common ancestor
// of elem1, looking for earliest non-common ancestor of elem2
while (sibElem) {
sibElem = sibElem.previousSibling;
if (sibElem && sibElem.tagName) {
sibs--;
if (sibElem === parents2[gens]) {
return {
up: parents1.length - gens - 1,
across: sibs,
down: parents2.length - gens - 1
};
}
}
}
}
因此,例如,在问题中描述的DOM中获取#div5
到#div10
的“距离”将使用如下内容:
var divOne = document.getElementById('div5'),
divTwo = document.getElementById('div10'),
distance = DOMdistance(divOne, divTwo);
因此distance
将是:
{
up: 1,
across: 3,
down: 2
}