William Jones
William Jones

Reputation: 1129

Why is the div hiding but not showing?

I am trying to make a program that, when a button is pressed, a function is called and everything is hidden except one div. But I don't understand why this isn't working. If there is some simple fix, I would be grateful, but I may be going about this problem completely wrong.

function myFunction() {
  var x = document.getElementById("div1");
  var y = document.getElementById("main");
  y.style.display = "none";
  x.style.display = "block";
};
#div1 {
  width:50px;
  height:50px;
  background-color: blue;
}

#div2 {
  width:50px;
  height:50px;
  background-color: red;
}

#div3 {
  width:50px;
  height:50px;
  background-color: green;
}
<html>
<body>
<div id="main">
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
  <button onclick="myFunction()">Show only Div 1</button>
</div>
</body>
</html>

I'm trying to do this without jQuery, but if that is the only way possible to achieve what I am trying to do, then I will use that.

Edit: Suppose I have lots of divs. Is there any quick way to hide all of them but one, without jQuery, without having to individually go through all the divs and hide them?

Upvotes: 0

Views: 87

Answers (5)

Asons
Asons

Reputation: 87191

You should really use a class instead, and addEventListener, as inline script is not recommended and neither are altering styles inline.

On button click, add a class to the main and then use its CSS rule to hide the chosen div, e.g. using the nth-child(n+2) or :not(:first-child)

Stack snippet

document.querySelector('button').addEventListener('click', function() {
  document.getElementById("main").classList.toggle('hideallbutdiv1');
})
#div1 {
  width:50px;
  height:50px;
  background-color: blue;
}

#div2 {
  width:50px;
  height:50px;
  background-color: red;
}

#div3 {
  width:50px;
  height:50px;
  background-color: green;
}

#main.hideallbutdiv1 div:nth-child(n+2) {  /*  or div:not(:first-child) */
  display: none;
}
<html>
<body>
<div id="main">
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
  <button>Show only Div 1</button>
</div>
</body>
</html>


Here is spiced version using a pseudo element to toggle the text on the button

document.querySelector('button').addEventListener('click', function() {
  document.getElementById("main").classList.toggle('hideallbutdiv1');
})
#div1 {
  width:50px;
  height:50px;
  background-color: blue;
}

#div2 {
  width:50px;
  height:50px;
  background-color: red;
}

#div3 {
  width:50px;
  height:50px;
  background-color: green;
}

button::before {
  content: attr(data-show)
}

#main.hideallbutdiv1 div:nth-child(n+2) {
  display: none;
}

#main.hideallbutdiv1 button::before {
  content: attr(data-hide)
}
<html>
<body>
<div id="main">
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
  <button data-show="Show only Div 1" data-hide="Show all"></button>
</div>
</body>
</html>

Upvotes: 2

Arthur Z.
Arthur Z.

Reputation: 193

In order to hide all the children of main except the div1, you have to hide all the siblings of div1 directly.

The function to get siblings would look like this:

function getSiblings(elem) {
        var siblings = [];
        var sibling = elem.parentNode.firstChild;
        var skipMe = elem;
        for ( ; sibling; sibling = sibling.nextSibling ) 
           if ( sibling.nodeType == 1 && sibling != skipMe )
              siblings.push( sibling );
        return siblings;
    }

Your button click handler:

function myFunction() {
      var x = document.getElementById("div1");
      var siblings = getSiblings(x);
      siblings.forEach(function(y){
        y.style.display = "none";
      });
    }

Here's the working example.

Upvotes: 1

SirPilan
SirPilan

Reputation: 4837

you are hiding main which contains all 3 divs.

function myFunction() {
  var x = document.getElementById("div1"); // <- you dont need this cause its visible initially
  var y = document.getElementById("div2");
  var z = document.getElementById("div3");
  
  x.style.display = "block"; // <- you dont need this cause its 
  y.style.display = "none";
  z.style.display = "none";
};
#div1 {
  width:50px;
  height:50px;
  background-color: blue;
}

#div2 {
  width:50px;
  height:50px;
  background-color: red;
}

#div3 {
  width:50px;
  height:50px;
  background-color: green;
}
<html>
<body>
<div id="main">
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
  <button onclick="myFunction()">Show only Div 1</button>
</div>
</body>
</html>

Upvotes: 0

HenryDev
HenryDev

Reputation: 4953

There's no need to hide the container. Simply hide the div you are targetting:

function myFunction() {
  var x = document.getElementById("div1");
  var y = document.getElementById("div2"); //  change it to div2 NOT main
  y.style.display = "none";
  x.style.display = "block";
};

Upvotes: 1

SystemGlitch
SystemGlitch

Reputation: 2262

Don't hide the container, or it will hide all its children.

function myFunction() {
  var x = document.getElementById("div1");
  var y = document.getElementById("div2");
  y.style.display = "none";
  x.style.display = "block";
};
#div1 {
  width:50px;
  height:50px;
  background-color: blue;
}

#div2 {
  width:50px;
  height:50px;
  background-color: red;
}
<html>
<body>
<div id="main">
  <div id="div1"></div>
  <div id="div2"></div>
  <button onclick="myFunction()">Show only Div 1</button>
</div>
</body>
</html>

Edit: hide your button too using the same method, if you really want only div1.

Upvotes: 0

Related Questions