简体   繁体   中英

Hide/Show div and then hide all div

I am trying to make a "meet the staff" section that has hidden bios that display on click. Right now the div displays as it should, but only disappears when the original button is clicked again. I am needing some additional javascript to hide any opened divs when a different (or same) button is clicked. I don't know enough javascript to know what to try in order to make this happen. Thanks in advance!

HTML

<div id="lastname" class="toggle-div" style="display: none;">
     <div><p>bio</p>
     </div>
</div>
        
<button class="bio-button" onclick="myBiof()">Click for Bio</button>

Javascript

<script>
function myBiof() {
  var y = document.getElementById("lastname");
  if (y.style.display === "block") {
    y.style.display = "none";
  } else {
    y.style.display = "block";
  }
}

</script>

You will need to add some attributes to your HTML to keep track of which item is active, what item a button controls and which ones should be hidden from screen readers. aria-controls aria-expanded and aria-hidden do just that. Once a button is clicked... if it is currently open, just close it (remove active) and toggle the appropriate attributes. If it is not open, close all of them (remove active), open the one you clicked on (add active) and toggle the appropriate attributes. Here is a simple example:

 const buttons = document.querySelectorAll("button"); const people = document.querySelectorAll(".person"); const handleClick = (event) => { const clickedBtn = event.target; if (clickedBtn.getAttribute("aria-expanded") === "true") { let personId = clickedBtn.getAttribute("aria-controls"); let person = document.getElementById(personId); person.classList.remove("active"); person.setAttribute("aria-hidden", "true"); clickedBtn.setAttribute("aria-expanded", "false"); } else if (clickedBtn.getAttribute("aria-expanded") === "false") { people.forEach(person => { person.classList.remove("active") person.setAttribute("aria-hidden", "true"); }); buttons.forEach(button => button.setAttribute("aria-expanded", "false")); let personId = clickedBtn.getAttribute("aria-controls"); let person = document.getElementById(personId); person.classList.add("active"); person.setAttribute("aria-hidden", "false"); clickedBtn.setAttribute("aria-expanded", "true"); } } buttons.forEach(button => button.addEventListener("click", handleClick));
 button { display: block; background: transparent; border: none; border-bottom: 1px solid #000; width: 100%; height: 2rem; }.person-container { width: 400px; margin: 0 auto; }.person { display: none; border-left: 1px solid #000; border-right: 1px solid #000; border-bottom: 1px solid #000; padding: 1rem; }.person h2 { margin-top: 0px; }.person p { margin-bottom: 0px; }.active { display: block; }
 <div class="person-container"> <button aria-controls="person-one" aria-expanded="false">Show Person One</button> <div id="person-one" aria-hidden="true" class="person"> <h2>Name One</h2> <p>Person One Bio</p> </div> <button aria-controls="person-two" aria-expanded="false">Show Person Two</button> <div id="person-two" aria-hidden="true" class="person"> <h2>Name Two</h2> <p>Person Two Bio</p> </div> <button aria-controls="person-three" aria-expanded="false">Show Person Three</button> <div id="person-three" aria-hidden="true" class="person"> <h2>Name Three</h2> <p>Person Three Bio</p> </div> </div>

 /* Function to add all the events to the buttons. Checking if divs are hidden or not with [data-hidden] attribute. This HMTML attributes can be named however you want but starting with data- Note that this code will only work if every button is placed in the HTML after the bio div */ function addEventsAndListenToThem() { const buttons = document.querySelectorAll('.bio-button') buttons.forEach(btn => { btn.onclick = (e) => { const target = e.target.previousElementSibling // If element is hided, show it changing // attribute data-hidden value to false target.getAttribute('data-hidden') === 'true'? target.setAttribute('data-hidden', 'false'): target.setAttribute('data-hidden', 'true') } }) const hide_or_show_all = document.querySelector('.bio-button-all') // Var to check wether.bio-button-all // has been pressed or not var showing = false hide_or_show_all.onclick = () => { // Get al divs with data-hidden property const all_bios = document.querySelectorAll('div[data-hidden]') showing === false? ( () => { // Show all divs all_bios.forEach(bio => bio.setAttribute('data-hidden', 'false')) showing = true } )(): ( // Hide all divs () => { all_bios.forEach(bio => bio.setAttribute('data-hidden', 'true')) showing = false } )() } } addEventsAndListenToThem()
 /* Display none only to [data-hidden="true"] elements */ [data-hidden="true"] { display: none; }.bio-button, .bio-button-all { display: block; margin: 10px 0px; }
 <div id="lastname" class="toggle-div" data-hidden='true'> <div> <p>First bio</p> </div> </div> <button class="bio-button">Click for first Bio</button> <div id="lastname" class="toggle-div" data-hidden='true'> <div> <p>Second bio</p> </div> </div> <button class="bio-button">Click for second Bio</button> <div id="lastname" class="toggle-div" data-hidden='true'> <div> <p>Third bio</p> </div> </div> <button class="bio-button">Click for third Bio</button> <button class="bio-button-all">Show/Hide all</button>

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