How can I detect when a details element is opened or closed in Javascript? Other than attaching a listener to the click function and checking if the open attribute is set or
In jQuery you can catch the event using .on('toggle')
like this:
$('#detail-id').on('toggle', function() {
//code
});
Example component in Vue:
<template>
<details @toggle="toggle" :open="openItem">
<summary>
<slot name="summary"/>
</summary>
<slot name="content"/>
</details>
</template>
<script>
export default {
props: {
open: {
type: Boolean,
default: false
}
},
data() {
return {
openItem: this.open,
}
},
methods: {
toggle({target}) {
this.openItem = target.open
}
}
}
</script>
You can use the toggle event:
var details = document.querySelector("details")
details.addEventListener("toggle", function() {
details.firstChild.textContent = "done"
})
<!doctype html>
<details>
<summary>toggle event</summary>
</details>
$("details").on("click", function () {
$("details[open]").not(this).removeAttr("open");
});
@import "https://fonts.googleapis.com/css?family=Montserrat:400,400i,700";*{position:relative;margin:0;padding:0;box-sizing:border-box;font-family:Montserrat,sans-serif}:focus{outline:none}body{background:#e0e0e0;height:100vh}div{width:400px;margin:0 auto;top:50%;transform:translateY(-50%);color:#464646;border:1px solid silver}p,summary{background:#fff}summary{padding:20px;width:400px;font-size:19px;z-index:1;border-bottom:1px solid silver;cursor:pointer}p{width:440px;margin:-2px -20px 0;padding:30px;font-size:15px;line-height:1.5;border:1px solid silver;text-align:justify;z-index:2;box-shadow:0 0 30px -12px #000}details[open] p{animation:det .3s}@keyframes det{0%{opacity:0}100%{opacity:1}}button{float:right;background:#0288d1;border:0;padding:11px;margin:-6px -6px 0 0;color:#fff;border-radius:4px;cursor:pointer}button:hover{background:#01579b}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<details>
<summary>Standard Room</summary>
<p>A standard room of a standard size, with a standard number of beds. Comes with the standard number of facilities. The view is of, well the usual. No balcony.</p>
</details>
<details>
<summary>Deluxe Room</summary>
<p>Like the Standard Room, but better. Comes with a balcony.</p>
</details>
<details>
<summary>Family Suite</summary>
<p>A suite for families. Twice the size of the standard room, three times the number of beds and four balconies.</p>
</details>
</div>
Since this is continuing to be voted down, and I can't remove it since it's the accepted answer, I'll refer to @Daniel Herr's post as a more up-to-date solution.
Old answer:
<details id="element">
<p>Details</p>
</details>
<script>
var isOpen = ($("#element").attr("open") == "open");
alert ("Open = " + isOpen);
</script>
/* Handle for details */
const detailsElements = document.querySelectorAll("details");
function handleClickOnDetails() {
// close all details
let detailsOpened = document.querySelectorAll("details[open]");
for (const item of detailsOpened) {
// keep open only details clicked
if (this != item) {
item.removeAttribute("open");
}
}
}
detailsElements.forEach(function (item) {
item.addEventListener("click", handleClickOnDetails);
});
<details>
<summary>Some details 1</summary>
<p>More info about the details.</p>
</details>
<details>
<summary>Some details2 </summary>
<p>More info about the details.</p>
</details>