当父有兄弟姐妹时,如何获取元素的父节点?

时间:2012-10-12 17:37:48

标签: 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>

正如您所看到的,img - elment有两个封闭的div。我希望这两个封闭的div中的第一个被认为是img - elment的“真正的”父级(我需要找到的),因为它之前有一个兄弟div所以搜索结束,兄弟div和外围div被忽略。

在没有兄弟姐妹的情况下,外部div必须屈服;如果元素未被包含,则必须产生元素本身。

我只想知道如何通过JavaScript解释该元素。

3 个答案:

答案 0 :(得分:16)

所以听起来你想要第一个拥有兄弟姐妹元素的祖先。如果是这样,你可以这样做:

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));

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

万一你好奇,以下是使用user1689607's answer实现jQuery的方法。

function getAncestorWithSiblings(element) {
  var ancestor = element.parent();
  while (ancestor && ancestor.siblings().length === 0) {
    ancestor = ancestor.parent();
  }
  return ancestor;
}

将此库用于您的目的是否有意义取决于我们没有的大量背景。正如其他人正确指出的那样,你不需要jQuery来解决这个问题,它可能是一个不必要的重量级解决方案。也就是说,它可以是一个非常有用的库,如果你没有意识到它或者还没有对它进行过研究,它肯定值得你考虑。