Home > Back-end >  Javascript toggle button: change action sequence from show/hide to hide/show
Javascript toggle button: change action sequence from show/hide to hide/show

Time:02-20

I have the following script, that I found at w3schools,

<script>
var coll = document.getElementsByClassName("collapsible");
var i;

for (i = 0; i < coll.length; i  ) {
  coll[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var content = this.nextElementSibling;
    if (content.style.display === "block") {
      content.style.display = "none";
    } else {
      content.style.display = "block";
    }
  });
}
</script>

in order to make a toggle button for a text box. The problem is the script initially shows the text box and then hides it. I want to first hide and then show. Otherwise the initial first click doesn't do anything, so users will think, the button is broken.

To explain more, I use it with

    <button type="button" >Toggle document map</button>
    <div >
    <p>bla..bla</p>
    </div>

and following css.

  .active, .collapsible:hover {
    background-color: #8511ae;
    color: white; font-weight: bold; text-decoration: underline;
}
  .collapsible {
    background-color: #faf9d8;
    color: #4e3fe3; font-style: italic; font-weight: bold;
    font-family: verdana, sans-serif;
    cursor: pointer;
    padding: 5px;
    width: 35%;
    float: left
    border: 0px solid #8511ae;
    text-align: center;
    outline: none;
    font-size: 15px;
    margin-top: 2%;
    margin-bottom: 0%;
    margin-left: 2%;
    margin-right: 24%;
}
  .content {
    width: 35%;
    float: left;
    padding: 0px;
    border: 0px solid #8511ae;
    margin-top: 0%;
    margin-bottom: 0%;
    margin-left: 2%;
    margin-right: 3%;
    background-color: #faf9d8;
}

The initial content css from w3schools, also includes

  display: none;
  overflow: hidden;

but since I want the text box to initially being visible when visiting the page, I left the above 2 items, out of the content css.

But now, as aforementioned, I have to click the toggle button twice (only the first time I do this) to hide the text box.

How can I modify the above javascript so that the first click hides instead of trying to make visible?

I tried some changes on my own but I just broke the script. This is the first website I ever made, and any help will be greatly appreciated.

CodePudding user response:

Just use:

if (content.style.display === "none") {
  content.style.display = "block";
} else {
  content.style.display = "none";
}

instead of:

if (content.style.display === "block") {
  content.style.display = "none";
} else {
  content.style.display = "block";
}

This is your code:

var coll = document.getElementsByClassName("collapsible");
var i;

for (i = 0; i < coll.length; i  ) {
  coll[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var content = this.nextElementSibling;
    if (content.style.display === "none") {
      content.style.display = "block";
    } else {
      content.style.display = "none";
    }
  });
}
.active, .collapsible:hover {
    background-color: #8511ae;
    color: white; font-weight: bold; text-decoration: underline;
}
  .collapsible {
    background-color: #faf9d8;
    color: #4e3fe3; font-style: italic; font-weight: bold;
    font-family: verdana, sans-serif;
    cursor: pointer;
    padding: 5px;
    width: 35%;
    float: left
    border: 0px solid #8511ae;
    text-align: center;
    outline: none;
    font-size: 15px;
    margin-top: 2%;
    margin-bottom: 0%;
    margin-left: 2%;
    margin-right: 24%;
}
  .content {
    width: 35%;
    float: left;
    padding: 0px;
    border: 0px solid #8511ae;
    margin-top: 0%;
    margin-bottom: 0%;
    margin-left: 2%;
    margin-right: 3%;
    background-color: #faf9d8;
}
<button type="button" >Toggle document map</button>
    <div >
    <p>bla..bla</p>
    </div>

CodePudding user response:

The style read-only property returns the inline style of an element in the form of a CSSStyleDeclaration

From HTMLElement.style documentation

Meaning when you use content.style.display (to either read or set its value) what you're acting on is the style that's written inline.

Since <div > doesn't have the inline style when the page first loads, your test if (content.style.display === "block") evaluates to false. It works the second time because your first click applied the block inline style with content.style.display = "block".

One way to fix it is then to simply manually add the inline styling to your content element like so:

<div style="display:block;">...

so that your code can evaluate to true the first time you click the button.

Like other have said though, if you want to not use inline styles, you can use classList instead.

  • Related