请看下面的代码:
<div>
<div></div>
<div><!-- my target node -->
<div><!-- not my target node -->
<img /><!-- my source node -->
</div>
</div>
</div>
正如你所看到的,img
-elment有两个封闭的div
s。我希望那两个封闭的div
s中的第一个被认为是img
-elment的“真正的”父母(我需要找到的那个),因为它之前有一个兄弟div
,所以搜索结束,兄弟div
和外围的div
被忽略了。
在没有兄弟姐妹的情况下,外部的div
必须得到;在元素未被封闭的情况下,元素本身必须被生成。
我只是想知道如何通过JavaScript解释该元素。
所以听起来你想要第一个拥有兄弟姐妹元素的祖先。如果是这样,你可以这样做:
var parent = img.parentNode;
while (parent && !parent.previousElementSibling && !parent.nextElementSibling) {
parent = parent.parentNode;
}
或者更恰当地写为do-while
循环:
do {
var parent = img.parentNode;
} while (parent && !parent.previousElementSibling && !parent.nextElementSibling);
因此,循环将在找到具有至少一个兄弟元素的循环时,或者当它用完祖先时结束。
如果您知道兄弟姐妹是在父母之前还是之后,您可以只测试一个或另一个。
另请注意,如果您支持旧版浏览器,则需要填充***ElementSibling
属性的垫片。
你可以创建一个可以执行此操作的函数:
function prevElement(el) {
while ((el = el.previousSibling) && el.nodeType !== 1) {
// nothing needed here
}
return el;
}
function nextElement(el) {
while ((el = el.nextSibling) && el.nodeType !== 1) {
// nothing needed here
}
return el;
}
然后使用这样的函数:
do {
var parent = img.parentNode;
} while (parent && !prevElement(parent) && !nextElement(parent));
如果您不知道父元素的级别是多少,则很难使用像element.getParent
这样的方法来选择它。但是,您可以遍历父节点,直到您正在查看的节点具有兄弟节点并且是body
元素的子节点。让我们假设您的img
标签由imgNode
引用。
function getParentWithSiblings(imgNode) {
for( ; n; n = imgNode.parentNode) {
if (n.nextSibling && n.parentNode.tagName == 'body') {
return n;
}
}
}
在上面的代码中,我们逐步遍历图像节点的父节点。在每次迭代中,我们检查当前节点(img
节点的某个父节点)是否具有兄弟节点并且是body
标签的子节点。
万一你好奇,这里是你如何使用user1689607's answer实现jQuery。
function getAncestorWithSiblings(element) {
var ancestor = element.parent();
while (ancestor && ancestor.siblings().length === 0) {
ancestor = ancestor.parent();
}
return ancestor;
}
将库用于您的目的是否有意义取决于我们没有的大量背景。正如其他人正确指出的那样,你不需要jQuery来解决这个问题,它可能是一个不必要的重量级解决方案。也就是说,它可以是一个非常有用的库,如果您没有意识到它或者还没有对它进行过调查,它肯定值得您考虑。