4

this code below almost does the trick. If you open any details tag and then click anywhere outside of it it will close. However, currently open details tags wont close as a new details tag is open.

var details = [...document.querySelectorAll('details')];
document.addEventListener('click', function(e) {
  if (!details.some(f => f.contains(e.target))) {
    details.forEach(f => f.removeAttribute('open'));
  }
})
<details>
  <summary>Details 1</summary>
  <p>content</p>
</details>

<details>
  <summary>Details 2</summary>
  <p>content</p>
</details>

<details>
  <summary>Details 3</summary>
  <p>content</p>
</details>

What am I missing?

Thank you.

Spectric
  • 30,714
  • 6
  • 20
  • 43
Cain Nuke
  • 2,843
  • 5
  • 42
  • 65

1 Answers1

7

You can check whether the target is a details tag, and if not, close all details tags.

If it is, only close the ones that don't have the event target as a child.

var details = [...document.querySelectorAll('details')];
document.addEventListener('click', function(e) {
  if (!details.some(f => f.contains(e.target))) {
    details.forEach(f => f.removeAttribute('open'));
  } else {
    details.forEach(f => !f.contains(e.target) ? f.removeAttribute('open') : '');
  }
})
<details>
  <summary>Details 1</summary>
  <p>content</p>
</details>

<details>
  <summary>Details 2</summary>
  <p>content</p>
</details>

<details>
  <summary>Details 3</summary>
  <p>content</p>
</details>
Spectric
  • 30,714
  • 6
  • 20
  • 43
  • why did you delete your previous answer? It seemed to work fine just by removing the condition as you said. – Cain Nuke Aug 04 '21 at 01:11
  • 1
    Oh, I see why now. With the previous one the tag will close even if you click inside of it. This new one seems to go around that too. thank you. – Cain Nuke Aug 04 '21 at 01:13