Каков наилучший способ найти первого общего родителя двух узлов DOM в JavaScript? - PullRequest
1 голос
/ 16 марта 2010

Мой вопрос именно такой, но в контексте я хочу изучить объект выбора, сравнить anchorNode и focusNode и, если они отличаются, найти первый общий родительский элемент.

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

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

Ответы [ 3 ]

5 голосов
/ 16 марта 2010

Я бы попробовал что-то подобное, предполагая, что нет библиотеки 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);
}

с помощью этой утилиты:

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

Тогда вы можете позвонить findFirstCommonAncestor(myElementA, myElementB).

2 голосов
/ 16 марта 2010

Этот способ довольно прост:

var fp = $(focus).parents();
var ap = $(anchor).parents();
for (var i=0; i<ap.length; i++) {
  if (fp.index(ap[i]) != -1) {
    // common parent
  }
}

Переберите parents() одного элемента и посмотрите, содержатся ли они в parents() другого, используя index(), пока не найдете совпадение (или нет ).

1 голос
/ 16 марта 2010

// Кажется, это должно быть довольно просто, даже без библиотеки или indexOf

document.commonParent= function(a, b){
 var pa= [], L;
 while(a){
  pa[pa.length]=a;
  a= a.parentNode;
 }
 L=pa.length;
 while(b){  
  for(var i=0; i<L; i++){
   if(pa[i]==b) return b;
  }
  b= b.parentNode;
 }
}
...