Home > Enterprise >  Simple vanilla javascript accordion - problem when click on active item
Simple vanilla javascript accordion - problem when click on active item

Time:05-20

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

    <div >
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span ></span>
    </div>

    <div  style="">
      <div >
        <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 >

    <div >
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span ></span>
    </div>

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

    <div >
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span ></span>
    </div>

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

    <div >
      <h4>Długie pytanie w dwóch linijkach</h4>
      <span ></span>
    </div>

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

CodePudding user response:

I think it's because you're triyng to control the animation using both css and javascript.
One thing that you could do, is to have a css classes for both states active and no-active, and then you use Js to swtich betwen them.

.no-active {
max-height: 0px
}
.no-active {
max-height: 9999px
}

CodePudding user response:

I think the issue is in the conditionals:

  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");
    }
  });
  • Related