Search code examples
javascriptaccordion

Simple vanilla javascript accordion - problem when click on active item


I have a problem with my accordion script.

Can someone explain me - why after clicking on the active item, the animation is not performed like when clicking on the next item?

It seems to me that the problem is at the beginning of the if condition:

if (this.nextElementSibling.style.maxHeight) {

when I click on accordionItemHead

let accordions = document.querySelectorAll('.js-accordions');

accordions.forEach(function(accordion) {

  let singleAccordionItems = accordion.querySelectorAll('.js-accordions-item');

  singleAccordionItems.forEach(function(accordionItem) {

    let accordionItemHead = accordionItem.querySelector('.js-accordions-head');
    let accordionItemContent = accordionItem.querySelector('.js-accordions-content');

    accordionItemHead.addEventListener("click", function() {

      if (this.nextElementSibling.style.maxHeight) {
        this.nextElementSibling.style.maxHeight = null;

      } else {

        singleAccordionItems.forEach(function(item) {

          item.querySelector('.js-accordions-content').style.maxHeight = null;
          item.classList.remove('is-active');

        });
      }

      accordionItemContent.style.maxHeight = accordionItemContent.scrollHeight + "px";
      accordionItem.classList.toggle('is-active');

    });


  });

});
.c-accordion {
  box-shadow: 2px 2px 24px rgba(0, 0, 0, 0.05);
}

.c-accordion__item {
  padding-left: 20px;
}

.c-accordion__header {
  position: relative;
  cursor: pointer;
  padding: 26px 0 22px;
}

.c-accordion__header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background-color: blue;
}

.c-accordion__item:first-child .c-accordion__header::before {
  content: none;
}

.c-accordion__header h4 {
  padding-right: 60px;
  font-size: 18px;
  font-weight: 500;
  line-height: 1.2;
}

.c-accordion__text {
  max-height: 0;
  overflow: hidden;
  visibility: hidden;
  transition-duration: 400ms;
  transition-property: max-height, visibility;
  transition-delay: 0, 400ms;
}

.is-active .c-accordion__text {
  visibility: visible;
  transition-duration: 400ms;
  transition-property: max-height, visibility;
  transition-delay: 400ms, 0;
}

.c-accordion__text p {
  margin-top: 0;
  margin-bottom: 25px;
}

.c-accordion__text-inner {
  display: flex;
  flex-direction: column;
}

.c-accordion__icon {
  position: absolute;
  top: 50%;
  margin-top: -9px;
  right: 25px;
  font-size: 18px;
  color: red;
}

.c-accordion__icon::after {
  position: absolute;
  top: 50%;
  margin-top: -1px;
  left: 0;
  content: '';
  width: 19px;
  height: 2px;
  background-color: blue;
  transform: scalex(0);
  transition: transform 0.4s;
}

.is-active .c-accordion__icon::after {
  transform: scaleX(1);
}

.c-accordion__icon::before {
  display: inline-block;
  transition: transform 0.3s, opacity 0.5s;
}

.is-active .c-accordion__icon::before {
  transform: rotate(90deg);
  opacity: 0;
}
<div class="c-accordion js-accordions">
  <div class="c-accordion__item js-accordions-item">

    <div class="c-accordion__header js-accordions-head">
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span class="c-accordion__icon icon icon-plus"></span>
    </div>

    <div class="c-accordion__text js-accordions-content" style="">
      <div class="c-accordion__text-inner">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Consectetur adipiscing elit.
          Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. 2</p>
      </div>
    </div>

  </div>

  <div class="c-accordion__item js-accordions-item">

    <div class="c-accordion__header js-accordions-head">
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span class="c-accordion__icon icon icon-plus"></span>
    </div>

    <div class="c-accordion__text js-accordions-content">
      <div class="c-accordion__text-inner">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Consectetur adipiscing elit.
          Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
      </div>
    </div>

  </div>

  <div class="c-accordion__item js-accordions-item">

    <div class="c-accordion__header js-accordions-head">
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span class="c-accordion__icon icon icon-plus"></span>
    </div>

    <div class="c-accordion__text js-accordions-content">
      <div class="c-accordion__text-inner">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Consectetur adipiscing elit.
          Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
      </div>
    </div>

  </div>

  <div class="c-accordion__item js-accordions-item">

    <div class="c-accordion__header js-accordions-head">
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span class="c-accordion__icon icon icon-plus"></span>
    </div>

    <div class="c-accordion__text js-accordions-content">
      <div class="c-accordion__text-inner">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Consectetur adipiscing elit.
          Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
      </div>
    </div>
  </div>
</div>


Solution

  • Just a little change in the conditionals makes it work:

          let accordions = document.querySelectorAll(".js-accordions");
    
          accordions.forEach(function (accordion) {
            let singleAccordionItems = accordion.querySelectorAll(".js-accordions-item");
    
            singleAccordionItems.forEach(function (accordionItem) {
              let accordionItemHead = accordionItem.querySelector(".js-accordions-head");
              let accordionItemContent = accordionItem.querySelector(".js-accordions-content");
    
              accordionItemHead.addEventListener("click", function () {
                if (this.nextElementSibling.style.maxHeight) {
                  this.nextElementSibling.style.maxHeight = null;
                } else {
                  singleAccordionItems.forEach(function (item) {
                    item.querySelector(".js-accordions-content").style.maxHeight = null;
                    item.classList.remove("is-active");
                  });
                  accordionItemContent.style.maxHeight = accordionItemContent.scrollHeight + "px";
                  accordionItem.classList.toggle("is-active");
                }
              });
            });
          });
         .c-accordion {
            box-shadow: 2px 2px 24px rgba(0, 0, 0, 0.05);
          }
    
          .c-accordion__item {
            padding-left: 20px;
          }
    
          .c-accordion__header {
            position: relative;
            cursor: pointer;
            padding: 26px 0 22px;
          }
    
          .c-accordion__header::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 1px;
            background-color: blue;
          }
    
          .c-accordion__item:first-child .c-accordion__header::before {
            content: none;
          }
    
          .c-accordion__header h4 {
            padding-right: 60px;
            font-size: 18px;
            font-weight: 500;
            line-height: 1.2;
          }
    
          .c-accordion__text {
            max-height: 0;
            overflow: hidden;
            visibility: hidden;
            transition-duration: 400ms;
            transition-property: max-height, visibility;
            transition-delay: 0, 400ms;
          }
    
          .is-active .c-accordion__text {
            visibility: visible;
            transition-duration: 400ms;
            transition-property: max-height, visibility;
            transition-delay: 400ms, 0;
          }
    
          .c-accordion__text p {
            margin-top: 0;
            margin-bottom: 25px;
          }
    
          .c-accordion__text-inner {
            display: flex;
            flex-direction: column;
          }
    
          .c-accordion__icon {
            position: absolute;
            top: 50%;
            margin-top: -9px;
            right: 25px;
            font-size: 18px;
            color: red;
          }
    
          .c-accordion__icon::after {
            position: absolute;
            top: 50%;
            margin-top: -1px;
            left: 0;
            content: "";
            width: 19px;
            height: 2px;
            background-color: blue;
            transform: scalex(0);
            transition: transform 0.4s;
          }
    
          .is-active .c-accordion__icon::after {
            transform: scaleX(1);
          }
    
          .c-accordion__icon::before {
            display: inline-block;
            transition: transform 0.3s, opacity 0.5s;
          }
    
          .is-active .c-accordion__icon::before {
            transform: rotate(90deg);
            opacity: 0;
          }
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
        <div class="c-accordion js-accordions">
          <div class="c-accordion__item js-accordions-item">
            <div class="c-accordion__header js-accordions-head">
              <h4>Długie pytanie w dwóch linijkach</h4>
              <span class="c-accordion__icon icon icon-plus"></span>
            </div>
    
            <div class="c-accordion__text js-accordions-content" style="">
              <div class="c-accordion__text-inner">
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac
                  aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
                  himenaeos. Consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis.
                  Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. 2
                </p>
              </div>
            </div>
          </div>
    
          <div class="c-accordion__item js-accordions-item">
            <div class="c-accordion__header js-accordions-head">
              <h4>Długie pytanie w dwóch linijkach</h4>
              <span class="c-accordion__icon icon icon-plus"></span>
            </div>
    
            <div class="c-accordion__text js-accordions-content">
              <div class="c-accordion__text-inner">
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac
                  aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
                  himenaeos. Consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis.
                  Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
              </div>
            </div>
          </div>
    
          <div class="c-accordion__item js-accordions-item">
            <div class="c-accordion__header js-accordions-head">
              <h4>Długie pytanie w dwóch linijkach</h4>
              <span class="c-accordion__icon icon icon-plus"></span>
            </div>
    
            <div class="c-accordion__text js-accordions-content">
              <div class="c-accordion__text-inner">
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac
                  aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
                  himenaeos. Consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis.
                  Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
              </div>
            </div>
          </div>
    
          <div class="c-accordion__item js-accordions-item">
            <div class="c-accordion__header js-accordions-head">
              <h4>Długie pytanie w dwóch linijkach</h4>
              <span class="c-accordion__icon icon icon-plus"></span>
            </div>
    
            <div class="c-accordion__text js-accordions-content">
              <div class="c-accordion__text-inner">
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac
                  aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
                  himenaeos. Consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis.
                  Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
              </div>
            </div>
          </div>
        </div>