Automatically close all the other
tags after opening a specific
tag

前端 未结 6 513
日久生厌
日久生厌 2021-02-06 01:08

Here is my code.



        
相关标签:
6条回答
  • 2021-02-06 01:09

    Another approach, slightly shorter, slightly more efficient, without dependencies, and without onclick attributes in the HTML.

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

    0 讨论(0)
  • 2021-02-06 01:20

    I have come up with a solution. Please correct me if this is a wrong approach.

    I added an onclick event to all of the details tag and made a function thisindex(this) which returns the index of the clicked tag and the obtained index number is then passed to the another function closeAll() which minimizes/closes all the other open tags except for one whose index matches with what we obtained earlier.

    Here is the code.

    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>

    Same with the help of 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");
          }
        }
      });
    });
    

    Kindly suggest me a better approach if this not up to the mark.

    0 讨论(0)
  • 2021-02-06 01:23

    Whao, nobody answering about <details> <summary> are using toogle event ?

    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>

    0 讨论(0)
  • 2021-02-06 01:29

    Modification for use with 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**
    
    0 讨论(0)
  • 2021-02-06 01:30

    Same concept, just a bit shorter.

    $('details').click(function (event) {
        $('details').not(this).removeAttr("open");  
    });
    
    0 讨论(0)
  • 2021-02-06 01:35

    Yet another answer for those who don't want to use obsolete jQuery and those who loves functional 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>

    0 讨论(0)
提交回复
热议问题