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

时间:2013-05-25 15:59:26

标签: javascript html html5 summary details

这是我的代码。

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

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

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

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

如何实现这一目标?

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

7 个答案:

答案 0 :(得分:10)

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

$('details').click(function (event) {
    $('details').not(this).removeAttr("open");  
    });

答案 1 :(得分:5)

另一种方法,稍短,效率稍高,without dependencies,并且HTML中没有onclick属性。

$pwd = “[your-service-principle-password]”
$subscriptionId = “[your-azure-subscription-id]”

Login-AzureRmAccount
Select-AzureRmSubscription -SubscriptionId $subscriptionId

$azureAdApplication = New-AzureRmADApplication `
                        -DisplayName “ Demo Web name” `
                        -HomePage “https://localhost/webdemo” `
                        -IdentifierUris “https://localhost/webdemo” `
                        -Password $pwd

New-AzureRmADServicePrincipal -ApplicationId $azureAdApplication.ApplicationId
New-AzureRmRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName $azureAdApplication.ApplicationId

$subscription = Get-AzureRmSubscription -SubscriptionId $subscriptionId
$creds = Get-Credential -UserName $azureAdApplication.ApplicationId -Message “Please use your service principle credentials”

Login-AzureRmAccount -Credential $creds -ServicePrincipal -TenantI $subscription.TenantId
public static string GetAccessToken()
{
    var authenticationContext = new AuthenticationContext("https://login.windows.net/{tenantId or tenant name}");  
    var credential = new ClientCredential(clientId: "{client id}", clientSecret: "{application password}");
    var result = authenticationContext.AcquireToken(resource: "https://management.core.windows.net/", clientCredential:credential);

    if (result == null) {
        throw new InvalidOperationException("Failed to obtain the JWT token");
    }

    string token = result.AccessToken;

    return token;
}

答案 2 :(得分:2)

对于不想使用 obsolete 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>

答案 3 :(得分: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");
      }
    }
  });
});

如果不符合标准,请建议我采用更好的方法。

答案 4 :(得分: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**

答案 5 :(得分:0)

哦,没有人回答<details> <summary>使用toogle事件吗?

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 = !open
    });
  }
}
<details>
  <summary>1</summary>
  Demo 1
</details>

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

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

答案 6 :(得分:0)

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

<块引用>

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

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

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

浏览器魔法更进一步!