2017-07-03 5 views
1

#content_containerを除くすべての要素を選択しようとしています。 。後で、選択した要素をすべて非表示にしたい。JS:1つを除くすべての要素を非表示にする(idで)(降順の子要素とその親をすべて)

私はすでにこれで失敗しかし:ではありません: 'は(#content_container *)ボディ*:' を返します

var elems = document.querySelectorAll("body *:not(#content_container *)"); 

ブラウザのコンソール(クローム):失敗を実行するには 'querySelectorAll' 'ドキュメント' 上有効なセレクタ。

"body *:not(#content_container)"はエラーを返しません。

これはどのように達成できますか? 注:jQueryを使用できません。

編集: 例がほしいと思う人もいます。目的は#content_containerとそのコンテンツをサイトに表示しておくことですが、他のすべてのコンテンツは非表示にします。

<body> 
<div class="hide"> 
    <div class="hide"> 

    </div> 
</div> 
<div> 
    <div> 
     <div class="hide"> 
      <div class="hide"> 

      </div> 
     </div> 
     <div id="content_container"> 
      <p> ------- content_container div ------- </p> 
      <div> 
        <div> 
          <div> 

          </div> 
        </div> 
      </div> 
      <div> 

      </div>  
     </div> 
    </div> 
    <div class="hide"> 

    </div> 
</div> 
<div class="hide"> 
    <div class="hide"> 
     <div class="hide"> 
      <div class="hide"> 

      </div> 
     </div> 
    </div> 
</div> 
<div class="hide"> 
    <div class="hide"> 

    </div> 
</div> 

+0

私は自分のブラウザのコンソールにそのクエリを実行したのだが、エラー –

+1

@JVLobo戻らない - クロームコンソールで実行します。エラーを返します。 –

+1

私はSafariでそれをやった...変な! –

答えて

2

私はこれを行うには見ることができる唯一の方法は、対象のノードを取得することです、それはその親ノードを上がる、その後、コレクションを「表示しない」に兄弟だすべてを追加あなたが行くにつれてすべての兄弟を集めて追加し、体のところで止める。

次の例では、ノード自体または直下の祖先ではなく、兄弟と親兄弟だけが追加され、ボディの子ノードが処理されると停止します。また、要素ノードだけを収集し、他のノードノードもすべて無視するので、空の#textノードの兄弟はそこに残りますが、レイアウトには影響しません。削除したい場合は、削除してください。

「アイテムを隠す」ボタンをクリックします。

function hideStuff(){ 
 
    var el = document.querySelector('#content_container'); 
 
    var node, nodes = []; 
 
    
 
    do { 
 
    var parent = el.parentNode; 
 
    
 
    // Collect element children 
 
    for (var i=0, iLen=parent.childNodes.length; i<iLen; i++) { 
 
     node = parent.childNodes[i]; 
 

 
     // Collect only sibling nodes that are elements and not the current element 
 
     if (node.nodeType == 1 && node != el) { 
 
     nodes.push(node); 
 
     } 
 
    } 
 

 
    // Go up to parent 
 
    el = parent; 
 

 
    // Stop when processed the body's child nodes 
 
    } while (el.tagName.toLowerCase() != 'body'); 
 

 
    // Hide the collected nodes 
 
    nodes.forEach(function(node){ 
 
    node.style.display = 'none'; 
 
    }); 
 
}
<body> 
 
    <div class="hide">hide 
 
    <div class="hide">hide 
 
     
 
    </div> 
 
    </div> 
 
    <div> 
 
    <div> 
 
     <div class="hide">hide 
 
     <div class="hide">hide 
 
      
 
     </div> 
 
     </div> 
 
     <div id="content_container"> 
 
     <p> ------- content_container div ------- </p> 
 
     <button onclick="hideStuff()">Hide stuff</button> 
 
     <div>don't hide 
 
      <div>don't hide 
 
      <div>don't hide 
 
       
 
      </div> 
 
      </div> 
 
     </div> 
 
     <div>don't hide 
 
      
 
     </div> 
 
     </div> 
 
    </div> 
 
    <div class="hide">hide 
 
     
 
    </div> 
 
    </div> 
 
    <div class="hide">hide 
 
    <div class="hide">hide 
 
     <div class="hide">hide 
 
     <div class="hide">hide 
 
      
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 
    <div class="hide">hide 
 
    <div class="hide">hide 
 
     
 
    </div> 
 
    </div> 
 
</body>

+0

これはすばらしい答えです。 JQuery! – gaborous

1

これは#content_container、その子とその親以外<body>内のすべてを隠し、次に選択します。

class="hide"純粋を隠されますが、プログラム的に有用ではありませんされる要素を示すために、HTMLに追加されます。

それは#content_containerですか、それは#content_containerが含まれていない限り、それは、<body>内のすべての要素にclass="hidden"を適用することで動作します。
!important CSSルールでは、のままになるように、子どもたちに#content_containerを強制します。

デモンストレーションのため、私は隠れが発生する前に1秒の遅延を追加しました。

setTimeout(() => { // for demo 
 

 
    document.querySelectorAll("body *:not(#content_container)") 
 
    .forEach((v) => { 
 
     if (!v.querySelector("#content_container")) { 
 
     v.classList.add("hidden"); 
 
     } 
 
    }); 
 

 
}, 1000);
body { 
 
    padding: .5rem; 
 
    background: lightgrey; 
 
} 
 
div { 
 
    padding: inherit; 
 
    border: 1px solid black; 
 
    background: lightblue; 
 
} 
 
#content_container { 
 
    background: lightgreen; 
 
    visibility: visible !important; 
 
} 
 

 
/* to hide the children, remove this rule */ 
 
#content_container * { 
 
    visibility: visible !important; 
 
} 
 

 
.hidden { 
 
    visibility: hidden; 
 
}
<body> 
 
    <div> 
 
    <div class="hide"> 
 
     <div class="hide"> 
 
     <div class="hide"> 
 
      <div class="hide"></div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    <div> 
 
     <div> 
 
     <div id="content_container"> 
 
      <div> 
 
      <div> 
 
       <div></div> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     <div class="hide"> 
 
      <div class="hide"> 
 
      <div class="hide"> 
 
       <div class="hide"></div> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</body>
このソリューション

#content_containerの両親のvisibility維持しません。

#content_containerさんの子供も隠す必要がある場合は、わずかな変更でCSSが修正されます。
私は子供たちに見えるようにするCSSを強調しました。以前のソリューションへ

setTimeout(() => { // for demo 
 

 
    document.querySelectorAll("body *:not(#content_container)") 
 
    .forEach((v) => { v.classList.add("hidden"); }); 
 

 
}, 1000);
body { 
 
    padding: .5rem; 
 
    background: lightgrey; 
 
} 
 
div { 
 
    padding: inherit; 
 
    border: 1px solid black; 
 
    background: lightblue; 
 
} 
 
#content_container { 
 
    background: lightgreen; 
 
    visibility: visible !important; 
 
} 
 

 
/* to hide the children, remove this rule */ 
 
#content_container * { 
 
    visibility: visible !important; 
 
} 
 

 
.hidden { 
 
    visibility: hidden; 
 
}
<body> 
 
    <div> 
 
    <div class="hide"> 
 
     <div class="hide"> 
 
     <div class="hide"> 
 
      <div class="hide"></div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    <div> 
 
     <div> 
 
     <div id="content_container"> 
 
      <div> 
 
      <div> 
 
       <div></div> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     <div class="hide"> 
 
      <div class="hide"> 
 
      <div class="hide"> 
 
       <div class="hide"></div> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</body>

Aはるかに効率的かつシンプルな代替は#content_containerとその子の可視性を強制しながら<body>(ページ上の他のため、すべてのものを)隠すことです。

これは、より直接的なルートで、適用が速く、必要に応じて簡単に逆転することができます。私の最初のソリューションは多くの冗長クラスを設定します。

setTimeout(() => { // for demo 
 

 
    document.querySelector("body").classList.add("hidden"); 
 

 
}, 1000);
body { 
 
    padding: .5rem; 
 
    background: lightgrey; 
 
} 
 
div { 
 
    padding: inherit; 
 
    border: 1px solid black; 
 
    background: lightblue; 
 
} 
 
#content_container { 
 
    background: lightgreen; 
 
    visibility: visible !important; 
 
} 
 
.hidden { 
 
    visibility: hidden; 
 
}
<body> 
 
    <div> 
 
    <div class="hide"> 
 
     <div class="hide"> 
 
     <div class="hide"> 
 
      <div class="hide"></div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    <div> 
 
     <div> 
 
     <div id="content_container"> 
 
      <div> 
 
      <div> 
 
       <div></div> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     <div class="hide"> 
 
      <div class="hide"> 
 
      <div class="hide"> 
 
       <div class="hide"></div> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</body>

関連する問題