Hide the accordion panel that is not actively being viewed as another one opens

Looking for a way to collapse an accordion panel when another one opens using vanilla JavaScript? Specifically, the solution needs to work in IE11. I am a JavaScript beginner and would greatly appreciate any help or guidance you can offer. Thank you.

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
  });
}
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #f8f8f8;
}

.accordion:after {
  content: '\002B';
  color: #777;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

.active:after {
  content: "\2212";
}

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<button class="accordion">Panel 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">Panel 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><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">Panel 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>

Answer №1

Save the currently expanded panel in a variable.

Alternatively, you can locate the expanded panel and implement the necessary logic to collapse it.

var acc = document.getElementsByClassName("accordion");
var i;
var prevExpandedPanel = null;
for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    if (prevExpandedPanel && this !== prevExpandedPanel) {  
      prevExpandedPanel.classList.toggle("active");
      prevExpandedPanel.nextElementSibling.style.maxHeight = null;
    }
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
    prevExpandedPanel = this.classList.contains('active') ? this : null;
  });
}
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #f8f8f8;
}

.accordion:after {
  content: '\002B';
  color: #777;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

.active:after {
  content: "\2212";
}

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<button class="accordion">Panel 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">Panel 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><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">Panel 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

populating a HTML image tag 'src' attribute with data extracted from API javascript code

Hey there! I'm currently working on integrating an image element from the openweatherAPI that corresponds to the weather icon retrieved from the JSON data when a user inputs a city. This means displaying images like scattered clouds or clear skies bas ...

What to do when faced with an NPM issue: Resolving the error "Unable to assign properties to null (setting 'parent')"

The issue arises in NPM when working within a monorepo that utilizes the NPM workspaces feature. Within my monorepo, I have five packages: a, b, c, d, and e. Additionally, I have a package located in a separate repository that is not part of the workspace, ...

Turning On and Off Hover Effects in AngularJS

I am looking to implement a feature that enables and disables the hover state on an element based on certain conditions. As a newcomer to Angular, I am unsure of how to approach this and haven't been able to find a solution online. Here is a sample o ...

Converting a Javascript string to 'Title Case' does not yield any results

I'm having trouble identifying the bug in this code as it's not generating any output: function convertToTitleCase (inputString) { var wordArray = inputString.split(' '); var outputArray = []; for (var j = 0; j ...

Steps to hide a div after it has been displayed once during a user's session

After a successful login, I have a div that displays a success message and then hides after 4 seconds using the following JavaScript code: document.getElementById('success').style.display = 'none'; }, 4000); While this functionality wo ...

Is has-danger feature no longer supported in the latest version of Bootstrap v4 beta?

The Bootstrap migration guide mentions: The .has-error class has been renamed to .has-danger. However, I have found that this change does not seem to take effect. The border and text are not colored as expected. For instance: <div class="form-grou ...

What might be causing the status problem to not display correctly?

My toggle feature to switch between no issue and issue is not displaying the status correctly. Despite trying to troubleshoot, I can't figure out why the issue section is not showing up. <!DOCTYPE html> <html> <script src="https://aj ...

Using the power of Javascript's jQuery library: the fantastic ".on()" Event Handler

I'm encountering an issue with the Jquery Event Handler ".on()". On my home page, I have a Favorite button on each post. If the post has not been favorited: li appears inactive Event 1 is triggered If the post has been favorited: li appears act ...

Implementing one-to-many relationships using Knex.js and Bookshelf.js in an ExpressJS/Postgres environment

When a user registers, I want to create a record on two tables simultaneously. user.js const db = require('../database'); const User = db.Model.extend({ tableName: 'login_user', hasSecurePassword: true, hasTimestamps: true, t ...

Generate a text input field within a dropdown menu

Below is an example of my basic HTML code for a drop-down list: <span id="Div_List"> <label for="Gender">For:</label> <select name="Gender" id="Sex"> <option value="1">1000mtr</option> <option val ...

Adjusting the width of the body container in a 2-column layout with menu padding is causing gaps to appear on the right side of

I'm having trouble getting my body div to fill the width of the page and align with the right side of my sidebar. Whenever I add padding to the sidebar, it creates blank space on the right that I can't seem to get rid of. Here is the code I am us ...

Creating a nested tree structure array from a flat array in Node.js

I have an array structure that I need to convert into a tree array using node.js. The current array looks like this: var data= [ { "id1": 1001, "id2": 1002, "id3": 1004, ... } ...

Working with JSON data in JavaScript is proving to be challenging

Here is a json encoded result: { "result":[ { "CODE":"STC\/R\/935", "WAY":"In", "DATE":"2016-02-19", "TYPE":"Re-Entry", "TKTP":"NA", "TIME":"2016-02-23 17: ...

Retrieving the value of a nested JSON object with a dynamic key

Currently, I am attempting to log a JSON key that is dynamic to the console. However, there is another nested object inside the main object that I also need to access a value from. The key of this nested object contains special characters, so I have been u ...

Trouble with CSS loading due to div in Visual Studio MVC

Currently, I am working with Visual Studio 2013 MVC and have a situation regarding the styling of my navbar in _Layout. The navbar includes a messages dropdown menu that utilizes CSS and JS extensively. Interestingly, when I load the messages as a partial ...

Animate the toggling of classes in jQuery

Here is a code snippet that I came across: $('li input:checked').click(function() { $(this).parent().parent().toggleClass("uncheckedBoxBGColor", 1000); }); This code is functioning correctly when the element is clicked for the first time. I ...

Troubleshooting Z-Index problem with Material UI Drawer component on iOS

I'm currently working on a project that involves the use of the Material UI Drawer component. However, I've encountered a specific issue when using an iPad, which presents two main problems: - The overlay does not appear above the navigation bar ...

What is the best way to make a flexbox stretch to fill the entire screen

Can someone guide me on how to ensure my flexbox expands to fill the entire screen? I am working on a website and I want to eliminate any empty spaces from it. >> https://i.sstatic.net/uAooe.png I have attempted setting margin and padding to zero b ...

Using Mongoose to Populate an Array with a Referenced Property

In the Post schema, I am using an array of Tags: tags: [ { type: Schema.Types.ObjectId, ref: 'Tag' } ], The Tag schema has the following structure: { name: String } When I populate the tags array, it populates with tag object literals. Is th ...

Refreshing a data object that is shared among Vue components

I've recently started diving into Vue, and I've found myself responsible for tweaking an existing codebase. There's this data.js file that caught my attention, containing a handful of objects holding city information, like: export default { ...