繁体   English   中英

JS:隐藏除了一个(由id)以及它的所有降序子元素及其父元素之外的所有元素

[英]JS: Hide all elements except of one (by id) (and all of its descending child elements and its parents)

我尝试选择页面上的所有元素,除了#content_container及其所有后代子元素及其所有父元素。 后来我想隐藏所有选中的元素。

但是我已经失败了:

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

浏览器控制台(chrome)返回:无法在'Document'上执行'querySelectorAll':'body *:not(#content_container *)'不是有效的选择器。

"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>

我可以看到这样做的唯一方法是获取主题节点,然后将其所有兄弟姐妹添加到“不显示”集合,然后上升其父节点收集并添加所有兄弟姐妹,停在身体。

以下仅添加兄弟姐妹和父级兄弟,而不是节点本身或其直接祖先,一旦处理了正文子节点就停止。 它也只收集元素节点并忽略所有其他节点,因此空的#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> 

然后选择隐藏<body>内的所有内容,除了#content_container ,它的子#content_container及其父#content_container

class="hide"被添加到HTML中纯粹用于指示哪些元素被隐藏,但在编程上没有用处。

它的工作原理是将class="hidden"应用于<body>每个元素,除非它是#content_container或它包含#content_container
然后, !important CSS规则会强制#content_container的子项保持visible

为了演示,我在隐藏发生之前添加了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> 

比以前的解决方案更有效和更简单的替代方法是隐藏<body> (以及页面上的所有其他内容),同时强制#content_container及其子项的可见性。

这是一种更直接的途径,应用更快,如果需要更容易逆转; 我的第一个解决方案设置了很多冗余类。

 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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM