Expanding all details tags

亡梦爱人 提交于 2019-12-12 17:37:37

问题


Anyone know if there is a way to create an expand all link for pages that use the semantic <details> tag? I managed to create a link that would auto-open closed details: Link to details section that expands details section as well

Now I'm trying to add a link that will expand all <details>.

I'm guessing you can do it with javascript but I'm weak there. Something to the effect of clicking a link that initiates a script that finds all "<details in the html and inserting the word "open" before displaying the html. Little help would be appreciated.

So far I'v got

<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>

The below works for the first <details> tag but I guess my loop in the above is not correct ...

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

The below is the dummy html that I'm testing on

<details>Hello World<summary>summary</summary>lost</details>
<details>another<summary>good night moon</summary>find me</details>

回答1:


UPDATE

OP requested that the first 6 <detail>s be excluded. Swapped out .forEach() method for for loop.

See Snippet 2


Use the .open attribute of <details>. It's true if open false if closed. Details commented in Snippet.

SNIPPET 1

// 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);
<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>

SNIPPET 2

// 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);
<a href='#/' id='expAll' class='exp'>Expand All</a>

<details>Hello World
  <summary>summary 0</summary>lost</details>
<details>another
  <summary>good night moon 1</summary>find me</details>
<details>Hello World
  <summary>summary 2</summary>lost</details>
<details>another
  <summary>good night moon 3</summary>find me</details>
<details>Hello World
  <summary>summary 4</summary>lost</details>
<details>another
  <summary>good night moon 5</summary>find me</details>
<details>Hello World
  <summary>summary 6</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>
<details>Hello World
  <summary>summary</summary>lost</details>
<details>another
  <summary>good night moon</summary>find me</details>



回答2:


So zer00ne's solution seems to sometimes work in the browsers (Chrome / Firefox). Sometimes on the second click it works. Sometimes on the first. Sometimes not at all. Maybe because the details tag is still not fully supported?

I went with the solution below ... just has an absolute endpoint at 31 instead of stop at end.

<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:


The solutions didn't work for me. So, I altered @testing123 solution to get it to work with a complete example.

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>


来源:https://stackoverflow.com/questions/43008609/expanding-all-details-tags

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!