1

我将 HTML5 标记详细信息用于公司的常见问题解答部分。一个问题是,如果用户打开另一个问题,另一个问题不会自动关闭。因此我在网上搜索并找到了以下解决方案:

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");
        }
      }
    }

这段代码在某种意义上确实可以正常工作,但它有一些小问题。有时它会同时打开两个问题并且很有趣。有没有一种方法可以正常工作?这应该适用于台式机、平板电脑和移动设备。

不想要的效果: 在此处输入图像描述

我用所有代码创建了一个小提琴http://jsfiddle.net/877tm/ 。javascript 在那里工作,如果您想实时查看,请单击此处

4

4 回答 4

5

由于您标记了 jQuery,您可以这样做:

$('.info').on('click', 'details', function () {
    $('details').removeAttr('open');
    $(this).attr('open', '');
});

所有这一切都是在您单击 any 时删除open所有标签的属性,然后重新打开您刚刚单击的标签。detaildetail

http://jsfiddle.net/877tm/3/

于 2013-11-16T21:06:21.270 回答
1
  1. thisindex 函数的洞是愚蠢的,可以删除。您可以简单地将 details 元素传递给 closeAll。

  2. closeAll 非常愚蠢,它也在 for 循环中搜索细节,哇。

// 关闭所有

function closeAll (openDetails){
    var details = document.getElementsByTagName("details");
    var len = details.length;
    for(var i=0; i<len; i++){
        if(details[i] != openDetails){
            details[i].removeAttribute("open");
        }
    }
}

如果您想编写干净的代码。

  1. 您应该使用 $.on 或 addEventlistener。
  2. 尝试在特定的上下文中,并且只在此上下文中操作细节。(如果你想有两个手风琴区域会发生什么。或者在同一个站点上的一些正常细节,但不在组内。)
  3. 如果详细信息已打开未关闭,则仅在组中搜索详细信息。
  4. 给 boolen open 属性一些爱,而不是使用 content 属性

我做了小小提琴,它试图做到这一点

于 2013-11-16T23:14:57.833 回答
0

要将详细信息制作为手风琴标签,您可以在 jquery 下方使用。

$("#edit-container details summary").click(function(e) {
    var clicked = $(this).attr('aria-controls');
    closeAll(clicked);
});
function closeAll (openDetailid){
      $("#edit-container details" ).each(function( index ) {
        var detailid = $(this).attr('id');
        var detailobj = document.getElementById(detailid);
          if (openDetailid != detailid ) {
           detailobj.open = false;
          }
       });
      $('html, body').stop().animate({ scrollTop: $('#'+openDetailid).offset().top -100 }, 1000);
  }
于 2019-05-07T10:00:52.023 回答
-1

我有一个 jQuery 的解决方案

$('details').on('click', function(ev){ //on a '<details>' block click
        ev.preventDefault(); //prevent the default behavior
        var attr = $(this).attr('open');
        if (typeof attr !== typeof undefined && attr !== false){ //if '<details>' block is open then close it
            $(this).removeAttr('open');
        }else{ // if '<details>' block is closed then open the one that you clicked and close all others
            var $that = $(this); //save the clicked '<details>' block
            $(this).attr('open','open'); //open the '<details>' block
            $('details').each(function(){ //loop through all '<details>' blocks
                if ($that.is($(this))){ //check if this is the one that you clicked on, if it is than open it or else close it
                    $(this).attr('open','open');
                }else{
                    $(this).removeAttr("open");
                }
            });
        }
    });
于 2015-01-16T08:51:50.450 回答