问题描述:

My accordion keeps filling up the space of my div bigger and smaller based on it opening and closing. I want to wrap a div around it and set it to the height of the accordion expanded to prevent this behavior. Trouble is my js is dependent on selecting this.nextSibling and that breaks everything.

var acc = document.getElementsByClassName("review-button");

var i;

for (i = 0; i < acc.length; i++) {

acc[i].onclick = function() {

this.classList.toggle("active");

var panel = this.nextElementSibling;

if (panel.style.maxHeight){

panel.style.maxHeight = null;

} else {

panel.style.maxHeight = panel.scrollHeight + 'px';

}

}

}

It must be using "this" within scope because there are multiple accordions.

My original thought was to do something like...

this.nextElementSibling.children[0];

but that didn't work.

how do I wrap the current content in a div with a set height, while still keeping the accordion functionality?

<!--accordion 1-->

<button class="review-button" data-target="#demo{{ gameIndex }}">

<span class="review-button-chevron fa fa-angle-down"></span>

Our Reviews

</button>

<!-- Slide out -->

<div class="quote-machine-container">

<div id="demo{{ gameIndex }}" class=" quote-machine"></div>

</div>

<!--accordion 2-->

<button class="review-button" data-target="#demo{{ gameIndex }}">

<span class="review-button-chevron fa fa-angle-down"></span>

Our Reviews

</button>

<!-- Slide out -->

<div class="quote-machine-container">

<div id="demo{{ gameIndex }}" class=" quote-machine"></div>

</div>

网友答案:
  1. Placed each <header> and <div> in it's own <section>
  2. Wrapped everything in <main> and added an eventListener() to it. Any clicks to it will be delegated to the header that was clicked (e.target.)
  3. The event handler (acc()) will:
    • determine what is e.target (clicked node) by comparing it to the e.currentTarget (the node being captured at the moment.)
    • Once established, e.target will lose or gain the .active class.
    • In order to eliminate the limiting property of nextElementSibling, we replace that functionality with a simple CSS ruleset: .active + .x-panel which is basically the same as nextElementSibling.

SNIPPET

var main = document.getElementById("x-main");

main.addEventListener('click', acc, false);

function acc(e) {
  if (e.target !== e.currentTarget) {
    var tgt = e.target;
    tgt.classList.toggle("active");
  }
}
.x-section {
  height: 100px;
}
.x-header {
  cursor: pointer;
  border: 3px outset grey;
  height: 30px;
}
.x-panel {
  border: 3px inset black;
  max-height: 0;
  opacity: 0;
  transition: opacity .2s ease-in;
}
.active + .x-panel {
  opacity: 1;
  max-height: 300px;
  overflow-y: hidden;
  transition: max-height 1s ease-in .1s, opacity 1s;
}
<main id='x-main'>
  <section class='x-section'>
    <header class='x-header'>HEADER</header>
    <div class='x-panel'>
      CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT
    </div>
  </section>
  <section class='x-section'>
    <header class='x-header'>HEADER</header>
    <div class='x-panel'>
      CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT
    </div>
  </section>
  <section class='x-section'>
    <header class='x-header'>HEADER</header>
    <div class='x-panel'>
      CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT
    </div>
  </section>
</main>
相关阅读:
Top