【问题标题】:Make accordion item open by default使手风琴项默认打开
【发布时间】:2022-09-27 15:43:48
【问题描述】:

在我的手风琴集中,我试图在页面加载时默认打开第一个手风琴项目。

我正在将类 .open 添加到该元素,如下所示:

<button class=\"open\">

这似乎可行,但问题是当我单击同一个元素而不是关闭它时,它会不断重新打开它并且通过查看 JS 脚本我不太明白可能是什么问题。

演示

var accordionButton = document.querySelectorAll(\"button\");

for (var i = 0; i < accordionButton.length; i++) {
  accordionButton[i].addEventListener(\"click\", switchClasses);
}

function switchClasses() {
  for (var i = 0; i < accordionButton.length; i++) {
    if (this !== accordionButton[i]) {
      accordionButton[i].classList.remove(\"open\");
      accordionButton[i].nextElementSibling.style.maxHeight = null;
    }
  }
  this.classList.toggle(\"open\");
  var nextAccordionButton = this.nextElementSibling;
  if (nextAccordionButton.style.maxHeight) {
    nextAccordionButton.style.maxHeight = null;
  } else {
    nextAccordionButton.style.maxHeight =
      nextAccordionButton.scrollHeight + \"px\";
  }
}
.accordion-item {
  border: 1px solid lightgrey;
}

button {
  background: none;
  border: none;
  width: 100%;
  max-width: none;
  height: auto;
  padding: 12px;
  text-align: left;
  cursor: pointer;
  transition: 0.5s;
}

.content-wrapper {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}

.content {
  padding: 0 10px;
}

.open {
  background: lightgray;
  border-bottom: none;
}

.open + .content-wrapper {
  max-height: none;
}
<div class=\"accordion-item\">
  <button class=\"open\">
    <span class=\"accordion__title\">Accordion 1</span>
  </button>
  <div class=\"content-wrapper\">
    <div class=\"content\">
      <p>Accordion 1 content.
    </div>
  </div>
</div>
<div class=\"accordion-item\">
  <button>
    <span class=\"accordion__title\">Accordion 2</span>
  </button>
  <div class=\"content-wrapper\">
    <div class=\"content\">
      <p>Accordion 2 content.
    </div>
  </div>
</div>
<div class=\"accordion-item\">
  <button>
    <span class=\"accordion__title\">Accordion 3</span>
  </button>
  <div class=\"content-wrapper\">
    <div class=\"content\">
      <p>Accordion 3 content.
    </div>
  </div>
</div>

    标签: javascript css accordion


    【解决方案1】:

    您还必须检查当前单击的元素。发生的事情是,您在删除元素后不断地重新将open 应用到该元素。

    此外,尝试将const 用于不会重新分配的变量。和let 用于将被变异的变量。 不建议使用var 关键字。

    const accordionButton = document.querySelectorAll('button');
    
    for (let i = 0; i < accordionButton.length; i++) {
      accordionButton[i].addEventListener('click', switchClasses);
    }
    
    function switchClasses() {
      for (let i = 0; i < accordionButton.length; i++) {
        if (this !== accordionButton[i]) {
          accordionButton[i].classList.remove('open');
          accordionButton[i].nextElementSibling.style.maxHeight = null;
          continue;
        }
    
        if (this === accordionButton[i]) {
          if (!this.classList.contains('open')) {
            this.classList.add('open');
            const nextAccordionButton = this.nextElementSibling;
            nextAccordionButton.style.maxHeight =
              nextAccordionButton.scrollHeight + 'px';
          } else {
            accordionButton[i].classList.remove('open');
            accordionButton[i].nextElementSibling.style.maxHeight = null;
          }
        }
      }
    }
    .accordion-item {
      border: 1px solid lightgrey;
    }
    
    button {
      background: none;
      border: none;
      width: 100%;
      max-width: none;
      height: auto;
      padding: 12px;
      text-align: left;
      cursor: pointer;
      transition: 0.5s;
    }
    
    .content-wrapper {
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.2s ease-out;
    }
    
    .content {
      padding: 0 10px;
    }
    
    .open {
      background: lightgray;
      border-bottom: none;
    }
    
    .open+.content-wrapper {
      max-height: none;
    }
    <div class="accordion-item">
      <button class="open">
        <span class="accordion__title">Accordion 1</span>
      </button>
      <div class="content-wrapper">
        <div class="content">
          <p>Accordion 1 content.</p>
        </div>
      </div>
    </div>
    <div class="accordion-item">
      <button>
        <span class="accordion__title">Accordion 2</span>
      </button>
      <div class="content-wrapper">
        <div class="content">
          <p>Accordion 2 content.</p>
        </div>
      </div>
    </div>
    <div class="accordion-item">
      <button>
        <span class="accordion__title">Accordion 3</span>
      </button>
      <div class="content-wrapper">
        <div class="content">
          <p>Accordion 3 content.</p>
        </div>
      </div>
    </div>

    【讨论】:

    • 我希望能够单击打开的元素并将其关闭。谢谢。
    • @Nesta 你去 :)
    【解决方案2】:

    这是一个简单的手风琴示例,可以简化您的问题/结构。 单击时,如果单击的元素具有类,我将删除 open。否则,如果打开手风琴,我会删除该类,然后打开单击的手风琴。

    document.querySelectorAll("button").forEach((e) => {
      e.addEventListener("click", () => {
        if (e.classList.contains("open")) {
          e.classList.remove("open")
        } else {
          let opened = document.querySelector("button.open")
          if (opened) {
            opened.classList.remove("open")
          }
          e.classList.add("open")
        }
      })
    });
    .content {
      display: none;
    }
    
    button {
      display: block;
    }
    
    .open {
      background-color: orange;
    }
    
    .open+.content {
      display: block;
    }
    <button class="open">Accordion 1</button>
    <div class="content">Content 1</div>
    <button>Accordion 2</button>
    <div class="content">Content 2</div>
    <button>Accordion 3</button>
    <div class="content">Content 3</div>

    此外,如果您想允许同时打开多个手风琴,您可以使用checkboxes 仅使用 HTML 和 CSS 进行设置。

    input {
      display: none;
    }
    
    label {
      display: block;
      width: fit-content;
    }
    
    input:checked+label {
      background-color: orange;
    }
    
    .content {
      display: none;
    }
    
    input:checked+label+.content {
      display: block;
    }
    <input type="checkbox" id="accordion-1" checked/>
    <label class="btn" for="accordion-1">Accordion 1</label>
    <div class="content">Content 1</div>
    <input type="checkbox" id="accordion-2" />
    <label class="btn" for="accordion-2">Accordion 2</label>
    <div class="content">Content 2</div>
    <input type="checkbox" id="accordion-3" />
    <label class="btn" for="accordion-3">Accordion 3</label>
    <div class="content">Content 3</div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多