21

这是我的代码。

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

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

<details>
  <summary>3</summary>
  Demo 3
</details>

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

如何做到这一点?

我知道<details>IE 或 Edge 不支持该标签。

4

7 回答 7

31

另一种方法,略短,效率略高,没有依赖关系,并且在 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");
      }
    });
  });
});
<details>
  <summary>1</summary>Demo 1
</details>

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

<details>
  <summary>3</summary>Demo 3
</details>

于 2016-05-03T02:51:52.133 回答
18

哇! 在我发帖之前...

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

  2. 没有人表明该open属性是布尔值
    将其设为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
    });
  }
}
<details>
  <summary>1</summary>
  Demo 1
</details>

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

<details>
  <summary>3</summary>
  Demo 3
</details>

ES10 以更短的方式实现相同的功能?=>.ontoggle直接事件方法

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

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

document.querySelectorAll('details').forEach((D,_,A)=>{
  D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })}
})
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;
  }
<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>

于 2019-05-17T23:13:26.533 回答
14

相同的概念,只是有点短。

$('details').click(function (event) {
    $('details').not(this).removeAttr("open");  
});
于 2016-05-03T02:23:54.640 回答
4

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

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

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

<details>
  <summary>3</summary>Demo 3
</details>

于 2021-01-11T21:09:33.030 回答
1

迟到总比没有好......我想指出这句话来自https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details

注意:您必须完全删除此属性才能隐藏详细信息。open="false" 使详细信息可见,因为此属性是布尔值。

(阅读属性段落末尾的注释。)

显然,在这种情况下,布尔意味着存在与否,并且不能设置为真或假......

浏览器魔法更进一步!

于 2021-05-19T05:45:28.730 回答
0

我想出了一个解决方案。如果这是错误的方法,请纠正我。

我向所有详细信息标签添加了一个 onclick 事件,并创建了一个函数,该函数thisindex(this)返回单击标签的索引,然后将获得的索引号传递给另一个函数,该函数closeAll()最小化/关闭所有其他打开的标签,除了索引匹配的标签与我们之前获得的。

这是代码。

function thisindex(elm){
  var nodes = elm.parentNode.childNodes, node;
  var i = 0, count = i;
  while( (node=nodes.item(i++)) && node!=elm )
    if( node.nodeType==1 ) count++;
  return count;
}

function closeAll(index){
  var len = document.getElementsByTagName("details").length;

  for(var i=0; i<len; i++){
    if(i != index){
      document.getElementsByTagName("details")[i].removeAttribute("open");
    }
  }
}
<details onclick="closeAll(thisindex(this));">
  <summary>1</summary>Demo 1
</details>

<details onclick="closeAll(thisindex(this));">
  <summary>2</summary>Demo 2
</details>

<details onclick="closeAll(thisindex(this));">
  <summary>2</summary>Demo 3
</details>

相同的帮助下jQuery

$(document).ready(function(){
  $('details').click(function (event) {
    var index = $('details').index(this);
    var len = $("details").length;
    for(var i=0; i<len; i++){
      if(i != index){
        $("details")[i].removeAttribute("open");
      }
    }
  });
});

如果这不符合要求,请建议我一个更好的方法。

于 2013-05-26T09:16:07.907 回答
0

与 polyfill jquery-details.js [Edge] 一起使用的修改

  var isIE = /*@cc_on!@*/false || !!document.documentMode;
  var isEdge = !isIE && !!window.StyleMedia;
  const details = Array.from(document.querySelectorAll("details"));
  details.forEach((targetDetail) => {
    targetDetail.addEventListener("click", () => {
      details.forEach((detail) => {
        if (detail !== targetDetail) {
          if(isEdge) {
            detail.className = detail.className.replace(/\bopen\b/g,"");
            detail.open =  false;
            detail.querySelector("summary").setAttribute("aria-expanded","false");
            var chil = detail.querySelectorAll("details > *");
            for(var j = 0; j < chil.length; j++) {
              if(chil[j].tagName != "SUMMARY") {
                chil[j].style.display = "none";
              }
            }
          } else {
            detail.removeAttribute("open");
          }
        }
      });
    });
  });**strong text**
于 2018-09-15T17:21:07.943 回答