javascriptdomselectiongetselection

What's the best way to find the first common parent of two DOM nodes in javascript?


My question is exactly that but in context I want to examine the selection object, compare the anchorNode and focusNode and if they are different then find the first common parent element.

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

if ( anchor != focus ) {
   // find common parent...
}

Solution

  • I would try something like this, assuming no JS library:

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

    using this utilities:

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

    Then you can call findFirstCommonAncestor(myElementA, myElementB).