Javascript 当父节点有同级节点时,如何获取元素的父节点?

Javascript 当父节点有同级节点时,如何获取元素的父节点?,javascript,dom,parent,siblings,dom-traversal,Javascript,Dom,Parent,Siblings,Dom Traversal,请看下面的片段: <div> <div></div> <div><!-- my target node --> <div><!-- not my target node --> <img /><!-- my source node --> </div> </div> </div&g

请看下面的片段:

<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 {
    var parent = img.parentNode;
} while (parent && !prevElement(parent) && !nextElement(parent));
或者更恰当地写为
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;
}
然后使用如下函数:

var parent = img.parentNode;

while (parent && !parent.previousElementSibling && !parent.nextElementSibling) {
    parent = parent.parentNode;
}
do {
    var parent = img.parentNode;
} while (parent && !prevElement(parent) && !nextElement(parent));

如果您不知道父元素上有多少层,那么很难单独使用
element.getParent
之类的方法来选择它。但是,您可以遍历父节点,直到您正在查看的节点具有兄弟节点并且是
主体
元素的子节点。假设您的
img
标记由
imgNode
引用

function getParentWithSiblings(imgNode) {
    for( ; n; n = imgNode.parentNode) {
        if (n.nextSibling && n.parentNode.tagName == 'body') {
            return n;
       }
    }
}

在上面的代码中,我们逐步迭代映像节点的父节点。在每次迭代中,我们检查当前节点(img节点的某个父节点)是否有兄弟节点,是否是
body
标记的子节点


为您的目的使用此库是否有意义取决于我们没有的大量上下文。正如其他人正确地指出的那样,您不需要jQuery来解决这个问题,而且它可能是一个不必要的重量级解决方案。这就是说,它可能是一个非常有用的库,如果您没有意识到它,或者还没有研究过它,那么它肯定值得您考虑。

element.parentNode
?dom元素只有一个父元素。获取img节点,您可以使用
.parentNode
轻松获取其父节点。事实上,您可以使用.parentNode沿着节点分支一直到树的根。如果您对DOM结构有疑问,请格式化您的HTML,使结构易于识别。非常感谢。我需要找到有兄弟(或有身体作为父母)的父母。因此,img的两个封闭div中的第一个适合我,因为第二个(内部div)没有兄弟,因此它对我没有用处。
n.parentNode.tagName==“body”
:为什么要求所需元素的父元素为
body
?不能仅依靠
.nextSibling
来搜索同级元素。在任何包含空白格式(制表符和换行符)的元素的任一侧都会有文本节点,
.nextSibling
将包含这些节点。我不知道JS会将空白视为额外的文本节点。谢谢1) “祖先耗尽”是否意味着如果没有兄弟姐妹,最终身体元素可以产生?2) 你(对另一个答案)关于可能的空白格式的评论与我的问题有关吗?@P5music:1)是的,可能。可以向特定节点名称添加约束。2) 这与他提供的解决方案有关。空白格式构成一个文本节点。如果我使用了
nextSibling
而不是
nextElementSibling
,那么该空白文本节点将被视为同级。谢谢。我知道jQuery非常受欢迎,但这个问题似乎不需要它,所以为什么要使用它呢?