在javascript中找到两个DOM节点的第一个共同父节点的最佳方法是什么?

rob*_*rke 1 javascript dom selection getselection

我的问题正是如此,但在上下文中我想检查选择对象,比较anchorNode和focusNode,如果它们不同,则找到第一个公共父元素.

var selected = window.getSelection();
var anchor = selection.anchorNode;
var focus = selection.focusNode;

if ( anchor != focus ) {
   // find common parent...
}
Run Code Online (Sandbox Code Playgroud)

小智 11

由于这个问题和接受的答案非常过时,我想建议使用更现代的 DOM API Range

function findFirstCommonAncestor(nodeA, nodeB) {
    let range = new Range();
    range.setStart(nodeA, 0);
    range.setEnd(nodeB, 0);
    // There's a compilication, if nodeA is positioned after
    // nodeB in the document, we created a collapsed range.
    // That means the start and end of the range are at the
    // same position. In that case `range.commonAncestorContainer`
    // would likely just be `nodeB.parentNode`.
    if(range.collapsed) {
        // The old switcheroo does the trick.
        range.setStart(nodeB, 0);
        range.setEnd(nodeA, 0);
    }
    return range.commonAncestorContainer;
}
Run Code Online (Sandbox Code Playgroud)


Als*_*nde 5

假设没有JS库,我会尝试这样的事情:

function findFirstCommonAncestor(nodeA, nodeB, ancestorsB) {
    var ancestorsB = ancestorsB || getAncestors(nodeB);
    if(ancestorsB.length == 0) return null;
    else if(ancestorsB.indexOf(nodeA) > -1) return nodeA;
    else if(nodeA == document) return null;
    else return findFirstCommonAncestor(nodeA.parentNode, nodeB, ancestorsB);
}
Run Code Online (Sandbox Code Playgroud)

使用此实用程序:

function getAncestors(node) {
    if(node != document) return [node].concat(getAncestors(node.parentNode));
    else return [node];
}

if(Array.prototype.indexOf === undefined) {
    Array.prototype.indexOf = function(element) {
        for(var i=0, l=this.length; i<l; i++) {
            if(this[i] == element) return i;
        }
        return -1;
    };
}
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话findFirstCommonAncestor(myElementA, myElementB).