修复Vanilla JS手风琴一次扩展一个选项卡 [英] Fixing Vanilla JS Accordion to expand one tab at a time

查看:77
本文介绍了修复Vanilla JS手风琴一次扩展一个选项卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在手风琴上工作,但是,我试图弄清楚如何一次只扩展一个(单击另一个选项卡,另一个关闭)。我尝试了其他方法来删除该类,但未获得所需的结果。我也一直在尝试将 for 循环重构为ES6标准,但这并不是一件容易的事。

I have this accordion working, however, I am trying to figure out how to expand only one at a time (click another tab, the other closes). I tried different methods to remove the class, but not getting the desired result. I have also been trying to refactor for loop to ES6 standards, but that's lesser of a concern.

样式是Sass,因此无法在JSFiddle中正确输出。

Styling is Sass so won't output correctly in JSFiddle.

const acc = document.querySelector('#accordion');
if (acc === null) {

} else {
    let accordianHeaders = acc.querySelectorAll('header');
    let size = accordianHeaders.length;
    for (i = 0; i < size; i++) {
        accordianHeader = accordianHeaders[i];
        accordianHeader.setAttribute('class', 'toggle');
        accordianHeader.nextElementSibling.setAttribute('class', '');
        accordianHeader.onclick = function() {
            if (this.getAttribute('class') == 'toggle') {
                this.setAttribute('class', 'toggle-active');
                this.nextElementSibling.setAttribute("class", 'active');
                this.previousElementSibling.removeAttribute('class', 'active');
            } else {
                this.setAttribute('class', '');
                this.nextElementSibling.setAttribute('class', '');
            }
        }
    }
}

#accordion {
    padding-top: 25%;
    overflow: hidden;
    li {
        width: 100%;
        list-style-type: none;
    }
    header {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        width: 100%;
        overflow: hidden;
        background-color: blue;
        max-width: 500px;
        padding: 10px;
    }
    i {
        width: 10%;
        color: white;
    }
    h3 {
        margin: 0;
        width: 90%;
        color: white;
    }

    article {
        max-height: 0;
        overflow: hidden;
        max-width: 600px;
        transition: 500ms max-height ease;
        &.active {
            max-height: 1000px;
        }
    }
    .toggle-active {
        i:before {
            content: "\f106";
        }
    }
}

<ul id="accordion">
    <li>
        <header>
            <i class="fa fa-angle-down"></i>
            <h3>List 1</h3>
        </header>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        </article>
    </li>
    <li>
        <header>
            <i class="fa fa-angle-down"></i>
            <h3>List 2</h3>
        </header>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        </article>
    </li>
    <li>
        <header>
            <i class="fa fa-angle-down"></i>
            <h3>List 3</h3>
        </header>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        </article>
    </li>
</ul>

推荐答案

这是使用您的类的另一种方法(因为我看到您正在使用过渡,所以我想您想保留动画)。

Here is another take, using your classes (since I see you are using transitions, so I guess you want to keep your animation).

const acc = document.querySelector('#accordion');
if (acc !== null) {
    const accordianHeaders = acc.getElementsByTagName('header');
    let accordianActive = null;
    [...accordianHeaders].forEach(h => h.addEventListener('click', i => {
      // on currently active accordian, remove `toggle-active` from header and `active` from article
      accordianActive && accordianActive.classList.remove('toggle-active');
      accordianActive && accordianActive.nextElementSibling.classList.remove('active');
      // set currently active accordian to clicked one, and apply classes
      accordianActive = i.currentTarget;
      accordianActive.classList.add('toggle-active');
      accordianActive.nextElementSibling.classList.add('active');
    }));
}

关于我的实现的一些说明:

Some notes about my implementation:


  • 我尊重您使用的 #accordion 选择器。虽然我不建议使用 id 来匹配CSS(BEM方法不建议使用此匹配项)。

  • 我不删除类在所有其他标签中,我使用一个变量来跟踪当前处于活动状态的标签。

  • 我已经将您的SASS转换为CSS,以使代码段起作用。
  • 当然,您可以使用原始的SASS代码。
  • I'm respecting the #accordion selector you use. Altough I don't recommend using id to match CSS (it's not recommended by BEM methodology).
  • I don't remove classes from all other tags, I use a variable to keep track of the currently active tag. Maybe it's a bit more performant this way.
  • I've converted your SASS to CSS to make the snippet work. Of course you can use your original SASS code.

const acc = document.querySelector('#accordion');
if (acc !== null) {
    const accordianHeaders = acc.getElementsByTagName('header');
    let accordianActive = null;
    [...accordianHeaders].forEach(h => h.addEventListener('click', i => {
      // on currently active accordian, remove `toggle-active` from header and `active` from article
      accordianActive && accordianActive.classList.remove('toggle-active');
      accordianActive && accordianActive.nextElementSibling.classList.remove('active');
      // set currently active accordian to clicked one, and apply classes
      accordianActive = i.currentTarget;
      accordianActive.classList.add('toggle-active');
      accordianActive.nextElementSibling.classList.add('active');
    }));
}

#accordion {
  padding-top: 25%;
  overflow: hidden;
}
#accordion li {
  width: 100%;
  list-style-type: none;
}
#accordion header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  overflow: hidden;
  background-color: blue;
  max-width: 500px;
  padding: 10px;
}
#accordion i {
  width: 10%;
  color: white;
}
#accordion h3 {
  margin: 0;
  width: 90%;
  color: white;
}
#accordion article {
  max-height: 0;
  overflow: hidden;
  max-width: 600px;
  transition: 500ms max-height ease;
}
#accordion article.active {
  max-height: 1000px;
}
#accordion .toggle-active i:before {
  content: "\f106";
}

<ul id="accordion">
    <li>
        <header>
            <i class="fa fa-angle-down"></i>
            <h3>List 1</h3>
        </header>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        </article>
    </li>
    <li>
        <header>
            <i class="fa fa-angle-down"></i>
            <h3>List 2</h3>
        </header>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        </article>
    </li>
    <li>
        <header>
            <i class="fa fa-angle-down"></i>
            <h3>List 3</h3>
        </header>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        </article>
    </li>
</ul>

这篇关于修复Vanilla JS手风琴一次扩展一个选项卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆