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...
}
Since this question and accepted answer are very dated, I'd like to suggest using a more modern 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;
}
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With