1

私の質問はまさにそれですが、コンテキストで選択オブジェクトを調べ、anchorNodeとfocusNodeを比較し、それらが異なる場合は、最初の共通の親要素を見つけます。

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

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

5 に答える 5

7

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)

于 2010-03-16T11:15:33.183 に答える
2

この方法はかなり簡単です。

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()

于 2010-03-16T11:12:20.040 に答える
1

//ライブラリや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;
 }
}
于 2010-03-16T16:35:33.213 に答える
1

この質問と受け入れられた回答は非常に古いため、より最新のDOMAPIであるRangeを使用することをお勧めします。

function findFirstCommonAncestor(nodeA, nodeB) {
    let range = new Range();
    range.setStartBefore(nodeA);
    range.setEndAfter(nodeB);
    // 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.setStartBefore(nodeB);
        range.setEndAfter(nodeA);
    }
    return range.commonAncestorContainer;
}
于 2021-07-29T22:28:12.853 に答える
0

そのためのDOMAPIがかなりあります:compareDocumentPosition

これがその方法です:

    /**
     * Returns closest parent element for both nodes.
     */
    function getCommonParent(one, two){
        let parent = one.parentElement;
        if(one === two) { //both nodes are the same node.
            return parent;
        }
        const contained = Node.DOCUMENT_POSITION_CONTAINED_BY;
        let docpos = parent.compareDocumentPosition(two);

        while(parent && !(docpos & contained)) {
            parent = parent.parentElement;
            docpos = parent.compareDocumentPosition(two);
        }
        return parent;
    }
于 2021-08-05T15:41:50.980 に答える