开发者

Detecting the opening or closing of a details element [closed]

开发者 https://www.devze.com 2023-04-04 06:58 出处:网络
Closed. This question needs to be more focused. It is not currently accepting answers. Want to improve this question? Update the question so it foc开发者_运维百科uses on one problem only by
Closed. This question needs to be more focused. It is not currently accepting answers.

Want to improve this question? Update the question so it foc开发者_运维百科uses on one problem only by editing this post.

Closed 1 year ago.

Improve this question

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 not.


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>


To test the current state, without events listeners, we can simply check if the attribute open is set:

// Test
onclick = () => {
  console.log(
    !detailElem.hasAttribute("open")
  )
}
<details id="detailElem">
  <summary>Some details</summary>
</details>


In jQuery you can catch the event using .on('toggle') like this:

$('#detail-id').on('toggle', function() {
   //code
});


/* 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>


$("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>


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>


No need to detect toggles/clicks or use jQuery. Just loop through the array result of document.querySelectorAll("details[open]") for open details elements and document.querySelectorAll("details:not([open])") for closed details elements. (You can also style closed/open details element using those selectors in CSS3.)


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>
0

精彩评论

暂无评论...
验证码 换一张
取 消