打开特定的<details>标记后自动关闭所有其他<details>标记

roh*_*_vg 8 html javascript html5 summary details

这是我的代码.

<details>
  <summary>1</summary>
  Demo 1
</details>

<details>
  <summary>2</summary>
  Demo 2
</details>

<details>
  <summary>3</summary>
  Demo 3
</details>
Run Code Online (Sandbox Code Playgroud)

我想要做的是 - 如果任何单个<details>标签的详细信息是打开的,我打开/查看另一个<details>标签,那么前一个标签应该关闭/隐藏/最小化.

怎么能实现这一目标?

我知道<details>IE或Edge不支持该标记.

Mis*_*ojo 14

哇! 在我发帖之前...

  1. 没有人表明<details>元素与toggle事件一起工作?
    -- 而不是click
    -- 并且该toggle事件也适用于键盘交互。

  2. 没有人指出该open属性是一个boolean
    使其成为trueor false,不要做.removeAttr("open") ;)

文档:https : //developer.mozilla.org/en-US/docs/Web/HTML/Element/details

const All_Details = document.querySelectorAll('details');

All_Details.forEach(deet=>{
  deet.addEventListener('toggle', toggleOpenOneOnly)
})

function toggleOpenOneOnly(e) {
  if (this.open) {
    All_Details.forEach(deet=>{
      if (deet!=this && deet.open) deet.open = false
    });
  }
}
Run Code Online (Sandbox Code Playgroud)
<details>
  <summary>1</summary>
  Demo 1
</details>

<details>
  <summary>2</summary>
  Demo 2
</details>

<details>
  <summary>3</summary>
  Demo 3
</details>
Run Code Online (Sandbox Code Playgroud)

ES10 以更短的方式做同样的事情?=>.ontoggle直接事件方法

document.querySelectorAll('details').forEach((D,_,A)=>{
  D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })}
})
Run Code Online (Sandbox Code Playgroud)

看看它的实际效果:(加上一些 CSS 改进;)

document.querySelectorAll('details').forEach((D,_,A)=>{
  D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })}
})
Run Code Online (Sandbox Code Playgroud)
details {
  border        : 1px solid lightgrey;
  width         : 24em;
  padding       : 0 .6em;
  border-radius : .3em;
  margin        : .3em;
  }
details > summary  {
  font-weight   : bold;
  margin        : 0em -.6em;
  list-style    : none;
  display       : block;
  padding       : .5em;
  }
details[open] {
  padding-bottom : .6em;
  }
details[open] summary {
  border-bottom : 1px solid #aaa;
  margin-bottom : .6em  ;
  }
summary::marker {
  display : none;
  }
summary::-webkit-details-marker {
  display : none;
  }
summary::after {
  display    : block;
  float      : right;
  content    : '\1405';
  cursor     : pointer;
  transition : 180ms;
  transform  : rotate(90deg);
  }
details[open] > summary:after {
  transform  : rotate(-90deg);
  }
summary:hover {
  outline          : none;
  background-color : whitesmoke;
  }
Run Code Online (Sandbox Code Playgroud)
<details>
  <summary>Lorem ipsum one</summary>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, 
  dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas 
  ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, 
  enim est eleifend mi, non fermentum diam nisl sit amet erat.
</details>
<details>
  <summary>Lorem ipsum two</summary>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, 
  dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas 
  ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, 
  enim est eleifend mi, non fermentum diam nisl sit amet erat.
</details>
<details>
  <summary>Lorem ipsum three</summary>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, 
  dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas 
  ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, 
  enim est eleifend mi, non fermentum diam nisl sit amet erat.
</details>
Run Code Online (Sandbox Code Playgroud)


小智 11

相同的概念,只是更短一点.

$('details').click(function (event) {
    $('details').not(this).removeAttr("open");  
    });
Run Code Online (Sandbox Code Playgroud)


Que*_*Roy 10

另一种方法,略短,稍微高效,没有依赖关系,并且HTML中没有onclick属性.

// Fetch all the details element.
const details = document.querySelectorAll("details");

// Add the onclick listeners.
details.forEach((targetDetail) => {
  targetDetail.addEventListener("click", () => {
    // Close all the details that are not targetDetail.
    details.forEach((detail) => {
      if (detail !== targetDetail) {
        detail.removeAttribute("open");
      }
    });
  });
});
Run Code Online (Sandbox Code Playgroud)
<details>
  <summary>1</summary>Demo 1
</details>

<details>
  <summary>2</summary>Demo 2
</details>

<details>
  <summary>3</summary>Demo 3
</details>
Run Code Online (Sandbox Code Playgroud)


Jan*_*roň 6

对于那些不想使用过时的 jQuery和喜欢函数式 javascript 的人来说,这是另一个答案

[...document.getElementsByTagName("details")].forEach( (D,_,A) =>
  D.addEventListener("toggle", E =>
    D.open && A.forEach(d =>
      d!=E.target && (d.open=false)
    )
  )
)
Run Code Online (Sandbox Code Playgroud)
<details>
  <summary>1</summary>Demo 1
</details>

<details>
  <summary>2</summary>Demo 2
</details>

<details>
  <summary>3</summary>Demo 3
</details>
Run Code Online (Sandbox Code Playgroud)