Search code examples
javascripthtmlhtml-tag-detailshtml-tag-summary

Automatically close all the other <details> tags after opening a specific <details> tag


Here is my code.

<details>
  <summary>1</summary>
  Demo 1
</details>

<details>
  <summary>2</summary>
  Demo 2
</details>

<details>
  <summary>3</summary>
  Demo 3
</details>

What I want to do is -- if the details of any single <details> tag is open and I open/view another <details> tag, then the earlier one should close/hide/minimize.

How can this be achieved?

I'm aware the <details> tag is not supported in IE or Edge.


Solution

  • Another approach, slightly shorter, slightly more efficient, without dependencies, and without onclick attributes in the HTML.

    // Fetch all the details element.
    const detailsList = document.querySelectorAll("details");
    
    // When a details is open, close all other details.
    function handleDetailToggle(event) {
      // We are only interested in details being opened.
      // Also, without the guard below, we'd run into an infinite loop.
      if (!event.target.open) return;
      for (let details of detailsList) {
        details.open = details === event.target;
      }
    }
    
    // Add toggle listeners.
    for (let details of detailsList) {
      details.addEventListener("toggle", handleDetailToggle);
    }
    <details>
      <summary>1</summary>Demo 1
    </details>
    
    <details>
      <summary>2</summary>Demo 2
    </details>
    
    <details>
      <summary>3</summary>Demo 3
    </details>