简单的原生 javascript 手风琴 - 单击活动项目时出现问题

问题描述 投票:0回答:3

我的手风琴脚本有问题。

有人可以解释一下 - 为什么单击活动项目后,动画不像单击下一个项目时那样执行?

在我看来,问题出在 if 条件的开头:

if (this.nextElementSibling.style.maxHeight) {

当我点击 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>

javascript accordion
3个回答
1
投票

只需对条件进行一点更改即可使其发挥作用:

      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>


0
投票

我认为这是因为你尝试使用 css 和 javascript 来控制动画。
你可以做的一件事是,为活动状态和非活动状态创建一个 css 类,然后使用 Js 在它们之间进行切换。

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

0
投票

更正的JS代码:

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;
                accordionItem.classList.remove('is-active');

            } 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');
            }
            
        });
        
    
    });
    
});
© www.soinside.com 2019 - 2024. All rights reserved.