How to handle expand/collapse event of Html5 <details> element?
Asked Answered
P

2

6

I use details/summary elements to get an expandable section:

https://www.w3schools.com/TAGS/tag_details.asp

d3.select('details')
  .on('click',()=>{
     alert('clicked');
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<details>
  <summary>Header</summary>
  <p>Content</p>
  <p>Content</p>
</details>

I want to execute an action when the open state of the details element is toggled. How can I do so?

If I would use the onclick event, the event is also fired if a user clicks on the summary or the content. I only want to handle "clicks on the toggle arrow".

Percussion answered 19/2, 2019 at 12:7 Comment(0)
P
3

d3.select('details')
  .on('toggle',()=>{
     alert('clicked');
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<details>
  <summary>Header</summary>
  <p>Content</p>
  <p>Content</p>
</details>
Percussion answered 19/2, 2019 at 12:11 Comment(1)
Or using plain vanilla js: document.querySelector('details').addEventListener('toggle', () => {});Dialectical
O
2

summary::-webkit-details-marker

summary::-webkit-details-marker summary::marker is the arrow you want, unfortunately it's in the shadow DOM and access to that isn't cross-browser (Chrome only).

The following demo:

  • Hides the original arrow

  • Replaced arrow with: <b>▶</b>

  • Animated with CSS

  • Basic JavaScript is applied to arrow

Demo

document.querySelector('summary b').onclick = function(e) {
  console.log('clicked');
};
summary::marker {
  content: "";
}

summary {
  height: 1rem;
  font-size: 1rem;
}

summary:focus {
  outline: none
}

summary b {
  display: inline-block;
  font-size: 0.75rem;
  margin: 0;
  padding: 5px;
  cursor: pointer;
  line-height: 1rem;
  height: 1rem;
  vertical-align: middle;
  transform: rotate(0deg);
  transition: transform 0.3s;
}

[open] b {
  transform: rotate(90deg);
  transition: transform 0.3s;
  transform-origin: 50% 45%;
}
<details>
  <summary><b>▶</b>Header</summary>
  <p>Content</p>
  <p>Content</p>
</details>
Onceover answered 19/2, 2019 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.