This code below closes all other detail tags open if one of them gets opened
document.addEventListener('click', function (e) {
const details = [...document.querySelectorAll('details')];
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') : '');
}
});
That's fine but I want to modify it so it will only close detail tags next to each other (siblings)
document.addEventListener('click', function (e) {
const details = [...document.querySelectorAll('details')];
details.some(f => {
if(f.previousElementSibling && f.previousElementSibling.contains(e.target) || f.nextElementSibling && f.nextElementSibling.contains(e.target)) {
details.forEach(f => f.removeAttribute('open'));
}
});
});
<div id="siblings1">
<details>
<summary>Parent 1</summary>
<details><summary>Child 1</summary>opened</details>
<details><summary>Child 2</summary>opened</details>
<details><summary>Child 3</summary>opened</details>
</details>
<details>
<summary>Parent 2</summary>
<details><summary>Child 1</summary>opened</details>
<details><summary>Child 2</summary>opened</details>
<details><summary>Child 3</summary>opened</details>
</details>
<details>
<summary>Parent 3</summary>
<details><summary>Child 1</summary>opened</details>
<details><summary>Child 2</summary>opened</details>
<details><summary>Child 3</summary>opened</details>
</details>
</div>
but I don't have it down right quite yet (clicking on the child will close its parent which I don't intend).
Goal: you click parent 1 and then child 1, then you click child 2, that should close child 1. Then you click parent 2, which should close parent 1 but its child 2 should remain open.
What is missing?
I think it my be easier if you don't start at document.
const details = document.querySelectorAll('details')
function close_slblings(event) {
event.stopPropagation()
for (let sib of this.parentElement.querySelectorAll(':scope > details'))
if (sib != this)
sib.removeAttribute('open')
// optionally recursively close their children details
}
for (let el of details) {
el.addEventListener('click',close_slblings)
}
details{padding-left: 1em;}
<details>
<summary>Parent 1</summary>
<details>
<summary>Parent 1-1</summary>
<details><summary>Child 1-1-1</summary></details>
<details><summary>Child 1-1-2</summary></details>
<details><summary>Child 1-1-3</summary></details>
</details>
<details><summary>Child 1</summary></details>
<details><summary>Child 2</summary></details>
<details><summary>Child 3</summary></details>
</details>
<details>
<summary>Parent 2</summary>
<details><summary>Child 1</summary></details>
<details><summary>Child 2</summary></details>
<details><summary>Child 3</summary></details>
</details>
<details>
<summary>Parent 3</summary>
<details><summary>Child 1</summary></details>
<details><summary>Child 2</summary></details>
<details><summary>Child 3</summary></details>
</details>