简体   繁体   中英

Javascript close a toggle using a button

I am trying to show and hide content using only javascript, html and css. I have been able to get button to show and hide information on the page but am unable to get the close button to hide the information.

 "use strict"; // /*Show Nutritional information results*/ const buttons = document.querySelectorAll(".contentButton"); for (const b of buttons) { b.addEventListener('click', ev => { ev.target.classList.toggle("on"); }) }
 .contentButton { background-color: #008CBA; color: white; text-align: center; text-decoration: none; font-size: 20px; width: 200px; height: 30px; border-radius: 7px; } .contentButton.on+div { display: block; } .content { display: none; position: relative; z-index: 1; left: 0; top: 0; bottom: 0; right: 0; width: 50%; height: 100px; background-color: #000000; width: 50%; margin: 10% auto; color: blue; }
 <h2>Item List</h2> <div class="Item1"> <button class="contentButton">toggle</button> <div class="content">loooaads of stuff goes here</div> <button class="close">Close</button> </div> <div class="Item2"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div> <div class="Item3"> <button class="contentButton">toggle</button> <div class="content">mooooreeee stuff goes here</div> <button class="close">Close</button> </div> <div class="Item4"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div> <div class="Item5"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div> <div class="Item1"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div>

Can someone please help so that the close button hides the content when it is open.

You can use:

const buttons = document.querySelectorAll(".contentButton");
const closebtns = document.querySelectorAll(".close");
  for (const b of buttons) {
    b.addEventListener('click', ev => {
      ev.target.classList.toggle("on");
    })
  }  
  for (const c of closebtns) {
    c.addEventListener('click', ev => {
      ev.target.closest("div").querySelector(".contentButton").classList.toggle("on");
    })
  } 

Explanation:

  • document.querySelectorAll(".close") get all close buttons and add click event listener to all of them.
  • ev.target.closest("div") get the closest div to the current clicked close button.
  • closest("div").querySelector(".contentButton") - find the contentButton inside the parent div and toggle the class on on that element.

I would move the on class up to be relative to the content parent.

div[class^="Item"].on div.content,
div[class^="Item"].on button.close {
  display: block;
}

div.content,
button.close {
  display: none;
}

Then all you need to do is get the target button's parent and toggle the class.

If you can, I would add an additional class to all the items that they can be identified easier in CSS.

div.expandable-content.on div.content {
  display: block;
}
<div class="expandable-content Item1">
  <button class="contentButton">toggle</button>
  <div class="content">loooaads of stuff goes here</div>
  <button class="close">Close</button>
</div>
<!-- ...etc -->

Example

 const queryAll = (selector) => Array.from(document.querySelectorAll(selector)) const showContent = (button, visible) => { button.parentElement.classList.toggle('on', visible) } queryAll(".contentButton").forEach(button => { button.addEventListener('click', e => { showContent(e.target, true) }) }) queryAll(".close").forEach(closeBtn => { closeBtn.addEventListener('click', e => { showContent(e.target, false) }) })
 .contentButton { background-color: #008CBA; color: white; text-align: center; text-decoration: none; font-size: 20px; width: 200px; height: 30px; border-radius: 7px; } div[class^="Item"].on div.content { display: block; } div[class^="Item"].on button.close { display: block; } .close { display: none; } .content { display: none; position: relative; z-index: 1; left: 0; top: 0; bottom: 0; right: 0; width: 50%; height: 100px; background-color: #000000; width: 50%; margin: 10% auto; color: blue; }
 <h2>Item List</h2> <div class="Item1"> <button class="contentButton">toggle</button> <div class="content">loooaads of stuff goes here</div> <button class="close">Close</button> </div> <div class="Item2"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div> <div class="Item3"> <button class="contentButton">toggle</button> <div class="content">mooooreeee stuff goes here</div> <button class="close">Close</button> </div> <div class="Item4"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div> <div class="Item5"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div> <div class="Item1"> <button class="contentButton">toggle</button> <div class="content">stuff goes here</div> <button class="close">Close</button> </div>


With the close button embedded, you need to get the content (parent) for the button, before you can get the wrapping div (grandparent).

 const queryAll = (selector) => Array.from(document.querySelectorAll(selector)) const showContent = (button, visible) => { button.parentElement.classList.toggle('on', visible) } queryAll(".contentButton").forEach(button => { button.addEventListener('click', e => { showContent(e.target, true) }) }) queryAll(".close").forEach(closeBtn => { closeBtn.addEventListener('click', e => { showContent(e.target.parentElement, false) }) })
 .contentButton { background-color: #008CBA; color: white; text-align: center; text-decoration: none; font-size: 20px; width: 200px; height: 30px; border-radius: 7px; } div[class^="Item"].on div.content { display: block; } div[class^="Item"].on button.close { display: block; } .close { display: none; } .content { display: none; position: relative; z-index: 1; left: 0; top: 0; bottom: 0; right: 0; width: 50%; height: 100px; background-color: #000000; width: 50%; margin: 10% auto; color: blue; }
 <h2>Item List</h2> <div class="Item1"> <button class="contentButton">toggle</button> <div class="content"> loooaads of stuff goes here <button class="close">Close</button> </div> </div> <div class="Item2"> <button class="contentButton">toggle</button> <div class="content"> stuff goes here <button class="close">Close</button> </div> </div> <div class="Item3"> <button class="contentButton">toggle</button> <div class="content"> mooooreeee stuff goes here <button class="close">Close</button> </div> </div> <div class="Item4"> <button class="contentButton">toggle</button> <div class="content"> stuff goes here <button class="close">Close</button> </div> </div> <div class="Item5"> <button class="contentButton">toggle</button> <div class="content"> stuff goes here <button class="close">Close</button> </div> </div> <div class="Item1"> <button class="contentButton">toggle</button> <div class="content"> stuff goes here <button class="close">Close</button> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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