开发者

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

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜