Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: hide everything in a container, except one node

I have a HTML container with some contents, including texts nodes and other tags:

<div id="container">
    A text outside any tag<br/>
    <input type="button" id="iii" value="xxx"/>
    Another text<br/>
    <a href="#">A link</a>
</div>

I want to use jQuery to hide everything in that container except the input tag.

// Hide all the node
$("#container").contents().hide();

// First try to hide texts
$("#container").contents().filter(":text").hide();
// Second try
$("#container").contents().filter(function() {
    return this.nodeType === 3;
}).hide();

// Show the desired element
$("#container #iii").show();

The link "A link" is removed, but the texts before and after the input still remains.

What is the right way to hide a text that is a direct child of a DOM element?

You can play with that example on jsfiddle

like image 712
Antwane Avatar asked Oct 28 '15 18:10

Antwane


2 Answers

Your .hide() will not work on the textnodes, because a style (in this case display:none;) always needs to be applied to a tag. It can't be applied to a node itself.

However, you can manipulate the HTML with Javascript to manually add spans around these textnodes:

// Get all the nodes in the container and loop over them
var allNodes = document.getElementById("container").childNodes;
for (i = 0; i < allNodes.length; i++) {
    var item = allNodes[i];

    if(item.tagName){
        // It already has a proper tag, so just hide it with a class
        $(item).addClass("hidden");
    }else{
        // Add a span around it
        $(item).wrap("<span class='hidden'>");
    }
}

$("#container #iii").removeClass("hidden");

JSFiddle

Then if you want to unhide the div contents later, you can simply remove the class, and leave the spans there (they won't hurt anyone).

$("#container .hidden").removeClass("hidden");
like image 119
Praxis Ashelin Avatar answered Nov 11 '22 17:11

Praxis Ashelin


The reason is I don't have control on the generation of this html. It's generated by a framework I am not authorized to modify

Try setting #container , #container *:not(#iii) css color property to transparent

$("#container, #container *:not(#iii)").css("color", "transparent")
#container {
    border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
    A text outside any tag<br/>
    <input type="button" id="iii" value="xxx"/>
    Another text<br/>
    <a href="#">A link</a>
</div>

jsfiddle https://jsfiddle.net/h7yuq8b6/10/


Are you authorised to modify the html through javascript?


yes it could be a solution

Alternatively, if html can be modified , could utilize .clone() to store original element as jQuery object, including all html content within element. Use .each() to iterate child nodes of original element, if node has "style" property call .hide() on child node , else set #text node .nodeValue to empty string.

Could reset html to original using clone of original element

// save orginal `html`
var clone = $("#container").clone(); 

$("#container").contents().filter(function() {
  return this.nodeType === 3 || this.id !== "iii"
}).each(function() {
  if ("style" in this) {
    $(this).hide()
  } else {
    this.nodeValue = ""
  }
})
#container {
    border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
    A text outside any tag<br/>
    <input type="button" id="iii" value="xxx"/>
    Another text<br/>
    <a href="#">A link</a>
</div>
like image 25
guest271314 Avatar answered Nov 11 '22 17:11

guest271314