Users selects two or more elements in a HTML page. What i want to accomplish is to find those elements' common ancestors (so body node would be the common ancestor if none found before) ?
P.S: It can be achieved with XPath but it is not a preferable option for me. Also it may be found with css selector parsing but i think it is a dirty method (?)
Thank you.
In ontologies, the lowest common ancestor is also known as the least common ancestor. In a tree data structure where each node points to its parent, the lowest common ancestor can be easily determined by finding the first intersection of the paths from v and w to the root.
Approach: For Binary search tree, while traversing the tree from top to bottom the first node which lies in between the two numbers n1 and n2 is the LCA of the nodes, i.e. the first node n with the lowest depth which lies in between n1 and n2 (n1<=n<=n2) n1 < n2.
A simple solution would be to store the path from root to x and the path from the root to y in two auxiliary arrays. Then traverse both arrays simultaneously till the values in the arrays match. The last matched value will be the LCA. If the end of one array is reached, then the last seen value is LCA.
Here's a pure JavaScript version that is a little more efficient.
function parents(node) { var nodes = [node] for (; node; node = node.parentNode) { nodes.unshift(node) } return nodes } function commonAncestor(node1, node2) { var parents1 = parents(node1) var parents2 = parents(node2) if (parents1[0] != parents2[0]) throw "No common ancestor!" for (var i = 0; i < parents1.length; i++) { if (parents1[i] != parents2[i]) return parents1[i - 1] } }
The solutions involving manually going through the ancestor elements are far more complicated than necessary. You don't need to do the loops manually. Get all the ancestor elements of one element with parents()
, reduce it to the ones that contain the second element with has()
, then get the first ancestor with first()
.
var a = $('#a'), b = $('#b'), closestCommonAncestor = a.parents().has(b).first();
jsFiddle example
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