skip to Main Content

Very new to JS so bear with me – I’m trying to make a show/hide section on a page. It’s working – but it needs to be clicked twice to work. I’ve looked at event handling and tried a couple examples I found on here but it’s not working.

function myFunction() {
  var x = document.getElementById("topsection");
  var computedStyle = window.getComputedStyle(x);
  if (x.style.display === "none") {
    x.style.display = "block";
  } else {
    x.style.display = "none";
  }
}
#topsection {
      width: 100%;
      padding: 50px 0;
      text-align: center;
      background-color: lightblue;
      margin-top: 20px;
      display: none;
}
<div id="topsection">
        This is a DIV element.
        </div>

<div id="section3">
    <button class="togglebutton" onclick="myFunction()">
        <img src="image.png" alt="buttonpng";>
    </button>
</div>

Any help would be appreciated!

3

Answers


  1. In the code, style.display property returns an empty string if the inline style is not set. in your code, when you first click x.style.display is an empty string. To fix it, you can use window.getComputedStyle instead of style.display.

    function myFunction() {
      var x = document.getElementById("topsection");
      var computedStyle = window.getComputedStyle(x);
    
      if (computedStyle.display === "none") {
        x.style.display = "block";
      } else {
        x.style.display = "none";
      }
    }
    <div id="topsection">
      This is a DIV element.
    </div>
    
    <div id="section3">
      <button class="togglebutton" onclick="myFunction()">
        <img src="image.png" alt="buttonpng" />
      </button>
    </div>
    Login or Signup to reply.
  2. The problem is in this line if (x.style.display === "none") {

    x.style.display is undefined the first time you run the code not a string –> "none"

    And so, if you change that conditional statement for if(!x.style.display) or if(x.style.display == undefined) it will work with just one click.

    Why is it working with two clicks?

    It is because the first time you run the code the if statement is not met and so, the else {} is executed defining that specific style to "none".

    And so you get what happends the second time you click. Right?

    Second issue

    Replace your else { x.style.display = "none"} for else {x.style.display = null} so that you undefine the style prop

    You can also achieve the same thing by using: x.style.removeProperty('display')

    Login or Signup to reply.
  3. Mitesh Dudhat has the correct answer to fix your immediate problem but there is another solution.

    If you swap out your id for a class and use a separate class set to display: block you can use classList to toggle that class on/off.

    The reason for swapping out the id for a class is due to ids ranking higher in specificity in the CSS cascade – using a class means that you wouldn’t need to add an !important property to the new class rule.

    Note: in this example I’ve removed the inline JavaScript and used querySelector to cache the DOM elements, and addEventListener to add a listener to the button.

    const section = document.querySelector('.topsection');
    const button = document.querySelector('.togglebutton');
    
    button.addEventListener('click', handleClick);
    
    function handleClick() {
      section.classList.toggle('show');
    }
    .topsection {
      width: 100%;
      padding: 50px 0;
      text-align: center;
      background-color: lightblue;
      margin-top: 20px;
      display: none;
    }
    
    .show {
      display: block !important;
    }
    <div class="topsection">
      This is a DIV element.
    </div>
    
    <div id="section3">
      <button class="togglebutton">
        Toggle section    
      </button>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search