扩展所有细节标签

时间:2017-03-24 20:30:08

标签: javascript loops expand details

任何人都知道是否有办法为使用语义<details>标记的网页创建展开全部链接?我设法创建了一个自动打开已关闭详细信息的链接:Link to details section that expands details section as well

现在我尝试添加一个扩展所有<details>的链接。

我猜猜你可以用javascript来做,但我在那里很弱。点击启动脚本的链接可以找到所有&#34;&lt; html中的详细信息并插入单词&#34;打开&#34;在显示html之前。我们将不胜感激。

到目前为止,我已经

<button onclick="openAll()">Expand All</button>

<script>function openAll() {
    var x = document.getElementsByTagName("details");
    var i;
    for (i = 0; i < x.length; i++) {
         x[i].setAttribute("open", "true");
}
</script>

以下适用于第一个<details>代码,但我猜我上面的循环不正确...

<script>
function openAll() {
    document.getElementsByTagName("details")[0].setAttribute("open", "true"); 
}
</script>

以下是我在

上测试的虚拟html
<details>Hello World<summary>summary</summary>lost</details>
<details>another<summary>good night moon</summary>find me</details>

6 个答案:

答案 0 :(得分:2)

<强>更新

OP要求排除前6个<detail>。为.forEach()循环交换了for方法。

请参阅代码段2

<小时/> 使用.open的{​​{1}}属性。如果关闭则打开false,这是真的。 详细信息请参阅代码段。

SNIPPET 1

<details>
// Reference the toggle link
var xa = document.getElementById('expAll');

// Register link on click event
xa.addEventListener('click', function(e) {

  /* Toggle the two classes that represent "state"
  || determined when link is clicked
  */
  e.target.classList.toggle('exp');
  e.target.classList.toggle('col');

  // Collect all <details> into a NodeList
  var details = document.querySelectorAll('details');

  /* Convert NodeList into an array then iterate
  || throught it...
  */
  Array.from(details).forEach(function(obj, idx) {

    /* If the link has the class .exp...
    || make each <detail>'s open attribute true
    */
    if (e.target.classList.contains('exp')) {
      obj.open = true;
      // Otherwise make it false
    } else {
      obj.open = false;
    }

  });

}, false);

SNIPPET 2

<a href='#/' id='expAll' class='exp'>Expand All</a>

<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
// Reference the toggle link
var xa = document.getElementById('expAll');

// Register link on click event
xa.addEventListener('click', function(e) {

  /* Toggle the two classes that represent "state"
  || determined when link is clicked
  */
  e.target.classList.toggle('exp');
  e.target.classList.toggle('col');

  // Collect all <details> into a NodeList
  var details = document.querySelectorAll('details');

  /* Convert NodeList into an array then iterate
  || throught it...
  */
  var D = Array.from(details);

  /* Start a for loop at 6 instead of 0
  || Now 0 - 5 details are excluded
  */
  for (let i = 6; i < D.length; i++) {

    /* If the link has the class .exp...
    || make each <detail>'s open attribute true
    */
    if (e.target.classList.contains('exp')) {
      D[i].open = true;
      // Otherwise make it false
    } else {
      D[i].open = false;
    }

  }

}, false);

答案 1 :(得分:1)

这是我的解决方案:

    const expandElements = shouldExpand => {
        let detailsElements = document.querySelectorAll("details");
        
        detailsElements = [...detailsElements];

        if (shouldExpand) {
            detailsElements.map(item => item.setAttribute("open", shouldExpand));
        } else {
            detailsElements.map(item => item.removeAttribute("open"));
        }
    };

这里你可以如何使用它:

<button onClick={() => expandElements(true)}>Expand</button>
<button onClick={() => expandElements(false)}>Collapse</button>

答案 2 :(得分:0)

因此,zer00ne的解决方案似乎有时适用于浏览器(Chrome / Firefox)。有时在第二次点击它有效。有时在第一次。有时根本没有。也许是因为details标签仍未得到完全支持?

我选择了下面的解决方案......只有31的绝对终点,而不是在结束时停止。

<button id="expand" onclick="openAll()">Expand All +</button>

var elems = document.getElementsByTagName("details");

function openAll() {
  for (var i = 4; i <= 31; i++){
    elems[i].setAttribute("open", "true");
  }
  document.getElementById("expand").setAttribute( "onClick", "javascript: closeAll();" );
  document.getElementById("expand").innerHTML = "Collapse All -";
}

function closeAll() {
  for (var i = 4; i <= 31; i++){
    elems[i].removeAttribute("open");
  }
  document.getElementById("expand").setAttribute( "onClick", "javascript: openAll();" );
  document.getElementById("expand").innerHTML = "Expand All +";
}

答案 3 :(得分:0)

解决方案对我不起作用。因此,我更改了@ testing123解决方案以使其与完整的示例一起使用。

function openAll() {
  var elems = document.getElementsByTagName("details");
  document.getElementById("btnExpandHideAllDetails").innerHTML = "Hide All Details on page";
  document.getElementById("btnExpandHideAllDetails").setAttribute( "onClick", "javascript: closeAll();");

  for (var i = 4; i <= elems.length; i++){
    elems[i].setAttribute("open", "true");
    }
}

function closeAll() {	
  var elems = document.getElementsByTagName("details");
  document.getElementById("btnExpandHideAllDetails").setAttribute( "onClick", "javascript: openAll();" );
  document.getElementById("btnExpandHideAllDetails").innerHTML = "Expand All Details on Page";	
  
  for (var i = 4; i <= elems.length; i++){
    elems[i].removeAttribute("open");
  }
}
<button id="btnExpandHideAllDetails" onclick="openAll()" style="color:white;background-color:green;">Expand All Details on Page</button>
    
    
<details>
  <summary>0</summary>                            
</details>
<details>
  <summary>1</summary>                            
</details>
<details>
  <summary>2</summary>                            
</details>
<details>
  <summary>3</summary>                            
</details>
<details>
  <summary>Expand me.</summary>                        
    Hello World!
</details>

答案 4 :(得分:0)

纯HTML解决方案since this particular element has an attribute open

<details open>
    <summary>Details</summary>
    Something small enough to escape casual notice.
</details>

<details>
    <summary>Details</summary>
    Something small enough to escape casual notice.
</details>

答案 5 :(得分:0)

我想要一些自己使用的东西,所以我不在乎它是否适用于所有浏览器。

我的方法是在包含详细信息元素的页面的每个部分的每个标题中创建展开/关闭按钮。该按钮作为嵌入式块位于每个部分标题的末尾,而无需我手动添加它们。

该代码遍历页面详细信息元素以找到最接近的父级,该父级可以是一节,一旁,一篇文章,主要内容或div。然后,使用这些父分组元素的唯一数组将按钮添加到其各自的标题。这些标题是否为h1-h6都没有关系,无论每个节中的第一个标题都将用“扩展”按钮修改标题。

按钮本身在“展开”时更新为显示“关闭”,反之亦然,因此其行为类似于切换。

因为我希望能够搜索页面上的内容,所以在主元素的第一个标题之后还添加了“全部扩展”按钮。这说明您需要“全部展开”才能在页面中进行搜索。

此“全部扩展”将更新每个部分中的子级“扩展”按钮以显示“关闭”。它还会切换为“全部关闭”。

我认为,仅当您使用的是使用语义元素并在页面上包含大量内容的结构化内容时,才需要使用此方法。

details元素的一个失败之处在于它确实隐藏了页面搜索中的内容,这是我的最大努力,致力于解决可能要搜索的内容(例如,您可能希望隐藏代码段的技术说明)冗长的设置软件说明,但仍然想搜索给定的关键字。

document.addEventListener("DOMContentLoaded", function (t) {
var groups = ["section", "aside", "article", "main", "div"], headings = ["h1", "h2", "h3", "h4", "h5", "h6"],
    parents = [],
    details = document.querySelectorAll("details");
for (var detail of details) for (var group of groups) {
    var parent = detail.closest(group);
    if (parent) {
        if (!parents.includes(parent)) for (var heading in parents.push(parent), headings) {
            var location = parent.getElementsByTagName(headings[heading]);
            if (location.length) {
                var button = document.createElement("button");
                button.classList.add("details-helper"),
                    button.setAttribute("type", "button"),
                    button.textContent = "Expand",
                    button.style.display = "inline-block",
                    location[0].appendChild(button),
                    button.addEventListener("click", expandGroup(parent));
            }
        }
        break;
    }
}

if (parents.length) {
    var nav = document.createElement("nav");
    nav.classList.add("text-search");
    var button = document.createElement("button");
    button.classList.add("search-helper"),
        button.setAttribute("type", "button"),
        button.textContent = "Expand All",
        button.style.display = "inline-block",
        nav.appendChild(button),
        button.addEventListener("click", expandAll());
    var p = document.createElement("p");
    p.style.display = "inline-block";

    var em = document.createElement("em");
    em.textContent = "Press before searching this page with CTRL+F";
    p.appendChild(em);
    nav.appendChild(p);
    for (heading of headings) {
        if (location = document.querySelector("main " + heading)) {
            location.parentNode.insertBefore(nav, location.nextSibling);
            break;
        }
    }
}

function expandGroup(group) {
    return function () {
        this.classList.contains("close-details") ? (this.classList.remove("close-details"), this.textContent = "Expand", state = false) : (this.classList.add("close-details"), this.textContent = "Close", state = true);
        var details = group.getElementsByTagName("details");
        Array.from(details).forEach(function (detail) {
            detail.open = state;
        })
    }
}

function expandAll() {
    return function () {
        this.classList.contains("close-all-details") ? (this.classList.remove("close-all-details"), this.textContent = "Expand All", state = false) : (this.classList.add("close-all-details"), this.textContent = "Close All", state = true);
        var buttons = document.querySelectorAll('.details-helper');
        Array.from(buttons).forEach(function (button) {
            if(!state) {
                button.classList.remove("close-details");
            } else {
                button.classList.add("close-details");

            }
            button.textContent = state ? "Close" : "Expand";
            for (var group of groups) {
                var parent = button.closest(group);
                if (parent) {
                    var details = parent.querySelectorAll("details");
                    Array.from(details).forEach(function (detail) {
                        detail.open = state;
                    })
                }
            }
        })
    }
}
});

这可以包含在带有脚本标签-'details-helper.js'的文档中,并且创建的按钮包括样式。

要使按钮与详细信息元素的默认样式保持一致:

.search-helper,
.details-helper {
    font-size: .66em;
    margin: 0 1em;
    outline: none;
    padding: 0.25em;
    text-transform: uppercase;
    vertical-align: text-bottom;
    width: 8em;
}
.search-helper {
    width: 10em;
}
.search-helper::after,
.details-helper::after {
    content: ' ▶';
}
.close-all-details::after,
.close-details::after {
    content: ' ▼';
}

您的里程可能会因该解决方案而异,但希望您可能会发现其中一些有用的方法。假定您的页面具有内容的主要逻辑结构。尚未在每个元素嵌套在许多div中并且没有文章或部分的页面上对此进行测试。