Jump to content

W3.CSS Accordions


leitzy
 Share

Recommended Posts

I want multiple accordions on the website and that only one is open at a time.

my code looks like this:

HTML:

<button onclick="openDropdown('drop1')" class="w3-button w3-block w3-black w3-left-align">Category 1</button>
<div id="drop1" class="category w3-hide w3-animate-top">
    <a href="#" class="w3-button w3-block w3-left-align">Link 1</a>
    <a href="#" class="w3-button w3-block w3-left-align">Link 2</a>
    <a href="#" class="w3-button w3-block w3-left-align">Link 3</a>
</div>
<button onclick="openDropdown('drop2')" class="w3-button w3-block w3-black w3-left-align">Category 2</button>
<div id="drop2" class="category w3-hide w3-animate-top">
    <a href="#" class="w3-button w3-block w3-left-align">Link 4</a>
    <a href="#" class="w3-button w3-block w3-left-align">Link 5</a>
    <a href="#" class="w3-button w3-block w3-left-align">Link 6</a>
</div>

JS:

 

function openDropdown(element) {
    categories.forEach(category => {
        if(category.id !== element && category.className.indexOf("w3-show") !== -1){
            category.className= category.className.replace(" w3-show", "")
        }
    })
    let target = document.getElementById(element)
    if (target.className.indexOf("w3-show") !== -1) {
        target.className = target.className.replace(" w3-show", "")
    } else {
        target.className += " w3-show"
    }
}

categories is a list of all elements with the category class attached. 

The problem is that the website is scrolling up if drop1 is open and i try to open drop2.

Link to comment
Share on other sites

Is this what you want or do you want drop-down lists to be separated?

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/><title> Accordion Panels </title><!-- From: https://jsfiddle.net/1rsb7gmo/5/ --><style> #container { width: 50%; } .accordion {   background-color: #eee;  color: #444;   cursor: pointer;         padding: 1em;   width: 100%;   border: none;   text-align: left;   outline: none;   font-size: 1em; } .accordion:hover { background-color: lime; } .accordion.open { background-color: lime; } .panel {   padding: 10px;   display: none;   background-color: wheat;   overflow: hidden; } .panel.open { display: block; }</style></head><body><h1> Accordion Panels </h1><div id="container">    <button class="accordion">Section 1</button>    <div class="panel">      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,          sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.          Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris          nisi ut aliquip ex ea commodo consequat.</p>    </div>    <button class="accordion">Section 2</button>    <div class="panel">      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,          sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.          Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris          nisi ut aliquip ex ea commodo consequat.</p>    </div>    <button class="accordion">Section 3</button>    <div class="panel">      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,          sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.          Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris          nisi ut aliquip ex ea commodo consequat.</p>    </div></div><script>  const acc = document.querySelectorAll('.accordion');  acc.forEach(    function(elem) {      elem.addEventListener('click', function(evt) {        acc.forEach(function(elem) {    if (elem != evt.target) { // optional display          elem.nextElementSibling.classList.remove("open");          elem.classList.remove("open");    }        });        var panel = evt.target.nextElementSibling;        var accordion = evt.target;        panel.classList.toggle('open');        accordion.classList.toggle('open');      }, true);    }  );</script></body></html>

 

Edited by JMRKER
Can't figure out how to show code that is NOT on one line!
Link to comment
Share on other sites

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/>
<title> Accordion Panels </title>
<!-- From: https://jsfiddle.net/1rsb7gmo/5/ -->
<style>
 #container { width: 50%; }
 .accordion {
   background-color: #eee;  color: #444;
   cursor: pointer;         padding: 1em;
   width: 100%;
   border: none;
   text-align: left;
   outline: none;
   font-size: 1em;
 }
 .accordion:hover { background-color: lime; }
 .accordion.open { background-color: lime; }
 .panel {
   padding: 10px;
   display: none;
   background-color: wheat;
   overflow: hidden;
 }
 .panel.open { display: block; }
</style>

</head>
<body>
<h1> Accordion Panels </h1>
<div id="container">
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
         sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
         Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
         nisi ut aliquip ex ea commodo consequat.</p>
    </div>

    <button class="accordion">Section 2</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
         sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
         Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
         nisi ut aliquip ex ea commodo consequat.</p>
    </div>

    <button class="accordion">Section 3</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
         sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
         Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
         nisi ut aliquip ex ea commodo consequat.</p>
    </div>
</div>

<script>
  const acc = document.querySelectorAll('.accordion');

  acc.forEach(
    function(elem) {
      elem.addEventListener('click', function(evt) {
        acc.forEach(function(elem) {
    if (elem != evt.target) { // optional display
          elem.nextElementSibling.classList.remove("open");
          elem.classList.remove("open");
    }
        });
        var panel = evt.target.nextElementSibling;
        var accordion = evt.target;
        panel.classList.toggle('open');
        accordion.classList.toggle('open');
      }, true);
    }
  );
</script>

</body>
</html>

OK, figured it out.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...