search

Home  >  Q&A  >  body text

Nested collapsible visibility issue

` Whenever I expand a nested collapsible, the visibility of its parent is not calculated correctly. Some nested content is missing from the screen

This is the html code and js code that handles the scroll height

// Get all collapsible buttons
const collapsibles = document.getElementsByClassName('collapsible');

// Add click event listener for each collapsible
for (let i = 0; i < collapsibles.length; i++) {
  collapsibles[i].addEventListener('click', function() {
    this.classList.toggle('active');
    const content = this.nextElementSibling;
    if (content.style.maxHeight) {
      content.style.maxHeight = null;
    } else {
      content.style.maxHeight = content.scrollHeight + 'px';
    }

    // Get all nested collapsible buttons within this collapsible
    const nestedCollapsibles = content.getElementsByClassName('nested-collapsible');

    // Loop through nested collapsibles and expand or collapse them accordingly
    for (let j = 0; j < nestedCollapsibles.length; j++) {
      const nestedContent = nestedCollapsibles[j].nextElementSibling;
      if (this.classList.contains('active')) {
        if (!nestedContent.style.maxHeight) {
          nestedContent.style.maxHeight = nestedContent.scrollHeight + 'px';
          content.style.maxHeight = (parseInt(content.style.maxHeight) + nestedContent.scrollHeight) + 'px'; // Add nested collapsible's scroll height to parent collapsible's scroll height
        } else {
          nestedContent.style.maxHeight = null;
          content.style.maxHeight = (parseInt(content.style.maxHeight) - nestedContent.scrollHeight) + 'px'; // Subtract nested collapsible's scroll height from parent collapsible's scroll height
        }
      }
    }
  });
}
.active {
  color:blue;
}
<div id="HotLikeMiami">
  <div class="HLM">
    <div class="HLMRow">

      <div class="HLMTitle">
        <h1 class="sub-title">Fantastic League</h1>
      </div>
      <div class="HLMImg">
        <img src="fantasticLeague.png">
      </div>
      <div class="HLMDetails">
        <p>A 2D Top Down Shooter game which heavily focuses on Enemy AI. I have made an attempt to build this project from ground up. I have used SFML for rendering shapes and textures, the rest is made from scratch. The project involves the integration
          of complex enemy AI. A simple Data-Oriented Design approach has been followed in this project for handling different events and messages by the enemies. </p>
      </div>

      <div class="MyContibution">
        <button class="collapsible">My Contribution</button>
        <div class="ContributionContent">
          <p>Got a lot of contribution</p>
          <button class="collapsible nested-collapsible">My Contribution</button>
          <div class="ContributionContent">
            <p>1. This process involves the development and integration of states like Game Menu, Splash Screen, InGame, Game Over etc states. These states are fetched with delta time which is calculated from the Game Loop. ​ 2. This stage also includes
              the development of Asset Manager, Input Manager etc</p>
          </div>

          <button class="collapsible nested-collapsible">My Contribution</button>
          <div class="ContributionContent">
            <p>1. This process involves the development and integration of states like Game Menu, Splash Screen, InGame, Game Over etc states. These states are fetched with delta time which is calculated from the Game Loop. ​ 2. This stage also includes
              the development of Asset Manager, Input Manager etc</p>
          </div>

          <button class="collapsible nested-collapsible">My Contribution</button>
          <div class="ContributionContent">
            <p>1. This process involves the development and integration of states like Game Menu, Splash Screen, InGame, Game Over etc states. These states are fetched with delta time which is calculated from the Game Loop. ​ 2. This stage also includes
              the development of Asset Manager, Input Manager etc</p>
          </div>

        </div>
      </div>


    </div>

  </div>
</div>```

</kbd>

I need help with calculations and what affects visibility

I want all nests to be independent and they increase the height of the parent's visibility whenever expanded Here the last nesting is cut off:


P粉805922437P粉805922437305 days ago473

reply all(1)I'll reply

  • P粉426906369

    P粉4269063692024-02-22 13:32:27

    I've modified your code to work properly with dynamic heights and responsiveness.

    First check if you are expanding or collapsing. We can figure this out by getting the result of classList.toggle, which is true if the class was added, or false if it was removed. p>

    I added a wrapper inside each ContributionContent. This wrapper will be responsible for calculating the total height of the inner content. This is required because the height of ContributionContent can fluctuate.

    Listen to the transitionend event and set the maximum height to none. The height is only set when the accordion is expanded. Close 0px should be respected when closing.

    Since the maximum height is set to none when expanded, we must use a Double Request Animation Frame (Double RAF) to first set the height and then transition to 0px when closed. This is a (hacky) technique that performs tasks after rendering has occurred. See this post about Double RAF.

    // Get all collapsible buttons
    const collapsibles = document.querySelectorAll('.collapsible');
    
    // Add click event listener for each collapsible.
    for (const collapsible of collapsibles) {
      collapsible.addEventListener('click', function(event) {
        const button = event.target;
        const isExpanding = button.classList.toggle('active');
        const content = button.nextElementSibling;
        const wrapper = content.firstElementChild;
        
        // Get the calculated height of the wrapper.
        const { height } = wrapper.getBoundingClientRect();
        content.style.maxHeight = height 'px';
        
        // Remove max height after an exapnding transition.
        content.addEventListener('transitionend', () => {
          if (isExpanding) {
            content.style.maxHeight = 'none';
          }
        }, { once: true });
        
        // Hack to force a closing transition.
        if (!isExpanding) {
          requestAnimationFrame(() => {
            requestAnimationFrame(() => {
              content.style.maxHeight = '0px';
            });
          });
        }
      });
    }
    .active {
      color: blue;
    }
    
    .collapsible * {
      display: grid; /* This forces the wrapper to account for the margins. It avoids a jump. */
      overflow: hidden;
      transition: max-height 500ms ease-out;
    }

    Fantastic League

    A 2D Top Down Shooter game which heavily focuses on Enemy AI. I have made an attempt to build this project from ground up. I have used SFML for rendering shapes and textures, the rest is made from scratch. The project involves the integration of complex enemy AI. A simple Data-Oriented Design approach has been followed in this project for handling different events and messages by the enemies.

    Got a lot of contribution

    1. This process involves the development and integration of states like Game Menu, Splash Screen, InGame, Game Over etc states. These states are fetched with delta time which is calculated from the Game Loop. ​ 2. This stage also includes the development of Asset Manager, Input Manager etc

    1. This process involves the development and integration of states like Game Menu, Splash Screen, InGame, Game Over etc states. These states are fetched with delta time which is calculated from the Game Loop. ​ 2. This stage also includes the development of Asset Manager, Input Manager etc

    1. This process involves the development and integration of states like Game Menu, Splash Screen, InGame, Game Over etc states. These states are fetched with delta time which is calculated from the Game Loop. ​ 2. This stage also includes the development of Asset Manager, Input Manager etc

    作为结束语。 W3Schools 有很多很好的例子,但众所周知它们已经过时了。寻找示例时,请了解他们的年龄以及他们是否使用最新的做法。

    reply
    0
  • Cancelreply