兄弟ノードを選択する方法はありますか?


104

パフォーマンス上の理由から、選択したノードの兄弟ノードのみを選択する方法を見つけようとしています。

例えば、

<div id="outer">
  <div id="inner1"></div>
  <div id="inner2"></div>
  <div id="inner3"></div>
  <div id="inner4"></div>
</div>

inner1ノードを選択した場合、その兄弟inner2-4ノードにアクセスする方法はありますか?

回答:


141

ええと...確かに...親にアクセスし、次に子供にアクセスします。

 node.parentNode.childNodes[]

または... jQueryを使用:

$('#innerId').siblings()

編集:いつものようにクレタスは刺激的です。さらに掘りました。これは基本的にjQueryが兄弟を取得する方法です。

function getChildren(n, skipMe){
    var r = [];
    for ( ; n; n = n.nextSibling ) 
       if ( n.nodeType == 1 && n != skipMe)
          r.push( n );        
    return r;
};

function getSiblings(n) {
    return getChildren(n.parentNode.firstChild, n);
}

23
jquery.siblings()は現在のノードを結果セットから除外することに注意してください。
cletus 2009年

3
これは非常に優れた機能です。
cgp 2009年

1
実際、jqueryのnode.parentNode.childNodes []に相当するものは、実際には$(node).siblings()ではなく$(node).parent()。children()です。これは素晴らしい機能ですが、迷惑なこともあります。それはあなたが望むものに依存します。
cletus 2009年

1
ELEMENT_NODEノードをnode.parentNode.childNodesでチェックしたいので、空白のテキストノードも表示されます。
seanmonstar 2009年

何も、私はそれが
間抜け

100
var sibling = node.nextSibling;

これにより、直後の兄弟が返されるか、nullが使用可能になった兄弟がなくなります。同様に、を使用できますpreviousSibling

[編集]div考え直してみると、これは次のタグを与えず、ノードの後の空白を与えます。より良いようです

var sibling = node.nextElementSibling;

も存在しpreviousElementSiblingます。


1
next / previousElementSiblingはIE8ではサポートされていません
Vadim


14

クイック:

var siblings = n => [...n.parentElement.children].filter(c=>c!=n)

https://codepen.io/anon/pen/LLoyrP?editors=1011

親の子を配列として取得し、この要素を除外します。

編集:

そして、テキストノードを除外するにはpmrotuleに感謝):

var siblings = n => [...n.parentElement.children].filter(c=>c.nodeType == 1 && c!=n)

2
素晴らしい解決策。しかし、nodeTypeをチェックしてテキストノードを破棄します[ ...n.parentNode.children ].filter(c => c.nodeType == 1 && c != n)
pmrotule '12

タイプスクリプト用にこれをどのように変更しますか?
Nic Sc​​ozzaro

10

2017年から:
正解:element.nextElementSibling正しい要素の兄弟を取得するため。また、あなたはelement.previousElementSibling前のもののために持っています

ここからは、次のすべての歯擦音を得るために非常に簡単です

var n = element, ret = [];
while (n = n.nextElementSibling){
  ret.push(n)
}
return ret;

nextまたはだけでなく、すべての兄弟を返す必要がありpreviousます。この場合、逆方向または順方向に正確に指定してもあまり役に立ちません。
dvlden 2017

4
何故なの。次と前を撮れば、全体像をつかむことができます。その答えは、物事を行うための新しい方法を示すことになります。読者に何かを貢献する。親になり、各要素に行き、誰もができる現在の要素をフィルターに
かける

6

jQueryで「兄弟」メソッドをチェックしましたか?

    sibling: function( n, elem ) {
        var r = [];

        for ( ; n; n = n.nextSibling ) {
            if ( n.nodeType === 1 && n !== elem ) {
                r.push( n );
            }
        }

        return r;
    }

n.nodeType == 1要素がhtmlノードであるかどうかを確認し、n!==現在の要素を除外します。

同じ関数を使用できると思います。そのコードはすべてバニラのJavaScriptのようです。


6

それを行うにはいくつかの方法があります。

次のいずれかの方法で対処できます。

// METHOD A (ARRAY.FILTER, STRING.INDEXOF)
var siblings = function(node, children) {
    siblingList = children.filter(function(val) {
        return [node].indexOf(val) != -1;
    });
    return siblingList;
}

// METHOD B (FOR LOOP, IF STATEMENT, ARRAY.PUSH)
var siblings = function(node, children) {
    var siblingList = [];
    for (var n = children.length - 1; n >= 0; n--) {
        if (children[n] != node) {
            siblingList.push(children[n]);
        }  
    }
    return siblingList;
}

// METHOD C (STRING.INDEXOF, ARRAY.SPLICE)
var siblings = function(node, children) {
   siblingList = children;
   index = siblingList.indexOf(node);
   if(index != -1) {
       siblingList.splice(index, 1);
   }
   return siblingList;
}

参考:jQueryコードベースは、グレードAのJavascriptを監視するための優れたリソースです。

ここに、非常に合理化された方法でjQueryコードベースを明らかにする優れたツールがあります。 http://james.padolsey.com/jquery/


3

これは、前、次、およびすべての兄弟(両側)を取得する方法です。

function prevSiblings(target) {
   var siblings = [], n = target;
   while(n = n.previousElementSibling) siblings.push(n);
   return siblings;
}

function nextSiblings(target) {
   var siblings = [], n = target;
   while(n = n.nextElementSibling) siblings.push(n);
   return siblings;
}

function siblings(target) {
    var prev = prevSiblings(target) || [],
        next = nexSiblings(target) || [];
    return prev.concat(next);
}

2

document.querySelectorAll()ループと反復を使用する

function sibblingOf(children,targetChild){
  var children = document.querySelectorAll(children);
  for(var i=0; i< children.length; i++){
    children[i].addEventListener("click", function(){
      for(var y=0; y<children.length;y++){children[y].classList.remove("target")}
      this.classList.add("target")
    }, false)
  }
}

sibblingOf("#outer >div","#inner2");
#outer >div:not(.target){color:red}
<div id="outer">
      <div id="inner1">Div 1 </div>
      <div id="inner2">Div 2 </div>
      <div id="inner3">Div 3 </div>
      <div id="inner4">Div 4 </div>
 </div>


1

jQuery

$el.siblings();

ネイティブ-最新、Edge13 +

[...el.parentNode.children].filter((child) =>
  child !== el
);

ネイティブ(代替)-最新、Edge13 +

Array.from(el.parentNode.children).filter((child) =>
  child !== el
);

ネイティブ-IE10 +

Array.prototype.filter.call(el.parentNode.children, (child) =>
  child !== el
);


0

1)選択したクラスをターゲット要素に追加
2)ターゲット要素を除く親要素のすべての子を検索
3)ターゲット要素からクラスを削除

 <div id = "outer">
            <div class="item" id="inner1">Div 1 </div>
            <div class="item" id="inner2">Div 2 </div>
            <div class="item" id="inner3">Div 3 </div>
            <div class="item" id="inner4">Div 4 </div>
           </div>



function getSiblings(target) {
    target.classList.add('selected');
    let siblings = document.querySelecttorAll('#outer .item:not(.currentlySelected)')
    target.classList.remove('selected'); 
return siblings
    }

-1

次の関数は、指定された要素のすべての兄弟を含む配列を返します。

function getSiblings(elem) {
    return [...elem.parentNode.children].filter(item => item !== elem);
}

選択された要素はgetSiblings()唯一のパラメーターであるため、関数に渡すだけです。


-2
x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.