Javascript 一次只打开一个手风琴标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37745154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:41:31  来源:igfitidea点击:

Only open one accordion tab at one time

javascripthtmlaccordion

提问by Usman Zafar

I have an accordion that works really well, it looks good on the site and works as it should. However, I'm trying to add some more JavaScript functionality to it, to make it more it look more professional.

我有一个非常好用的手风琴,它在网站上看起来不错并且可以正常工作。但是,我正在尝试向它添加更多 JavaScript 功能,使其看起来更专业。

Currently, the accordion allows you to have multiple panels open at one time i.e. if I open one tab, and then open another tab, both tabs will be open at the same time. And the only way to close these panels, is to re-click on the header.

目前,手风琴允许您同时打开多个面板,即如果我打开一个选项卡,然后打开另一个选项卡,两个选项卡将同时打开。关闭这些面板的唯一方法是重新单击标题。

What I would like is some JavaScript code that prevents multiple tabs from being open at one time, so if I click on a new panel, it should close the existing open panel first. Here is my HTML code for the accordion:

我想要的是一些 JavaScript 代码,可以防止同时打开多个选项卡,所以如果我点击一个新面板,它应该先关闭现有的打开面板。这是我的手风琴 HTML 代码:

<div class="accordion"><b>Heading 1</b></div>
<div class="panel">
    <p class="text-light">Text 1</p>
</div>
<div class="accordion"><b>Heading 2</b></div>
<div class="panel">
    <p class="text-light">Text 2</p>
</div>

Here is my JavaScript code in a separate JavaScript file which currently allows multiple tabs to be open at one time

这是我在单独的 JavaScript 文件中的 JavaScript 代码,该文件当前允许同时打开多个选项卡

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
        this.classList.toggle("active");
        this.nextElementSibling.classList.toggle("show");
    }
}

Not sure if you need all the CSS, but heres the CSS for showing the panel

不确定您是否需要所有 CSS,但这里是用于显示面板的 CSS

div.panel.show {
    display: block !important;
}

Hopefully someone can help! Thanks in advance!

希望有人能帮忙!提前致谢!

回答by Rory McCrossan

To achieve this you need to reset the state of the accordion back to its original state on each click, before you set the required classes on the clicked elements. To do that you can extract functionality to set the class names in to their own function and call it as required. Try this:

为此,您需要在每次单击时将手风琴的状态重置回其原始状态,然后再在单击的元素上设置所需的类。为此,您可以提取功能以将类名设置为它们自己的函数并根据需要调用它。尝试这个:

var acc = document.getElementsByClassName("accordion");
var panel = document.getElementsByClassName('panel');

for (var i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
        var setClasses = !this.classList.contains('active');
        setClass(acc, 'active', 'remove');
        setClass(panel, 'show', 'remove');

        if (setClasses) {
            this.classList.toggle("active");
            this.nextElementSibling.classList.toggle("show");
        }
    }
}

function setClass(els, className, fnName) {
    for (var i = 0; i < els.length; i++) {
        els[i].classList[fnName](className);
    }
}

Working example

工作示例

回答by Colin

var acc = document.getElementsByClassName("accordion");
var i;
var last;
for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
        if(last){
            last.classList.toggle("active",false);
            last.nextElementSibling.classList.toggle("show",false);
        }
        this.classList.toggle("active");
        this.nextElementSibling.classList.toggle("show");
        last=this;
    }
}

variable last will track the last active accordion, so you don't need to iterate every accordion and panel again.

变量 last 将跟踪最后一个活动的手风琴,因此您不需要再次迭代每个手风琴和面板。

回答by melancia

When selecting one item, you just need to hide all of them beforehand.

选择一项时,您只需要事先隐藏所有项。

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
        hideAll();

        this.classList.toggle("active");
        this.nextElementSibling.classList.toggle("show");
    }
}

function hideAll() {
    for (i = 0; i < acc.length; i++) {
        acc[i].classList.toggle("active", false);
        acc[i].nextElementSibling.classList.toggle("show", false);
    }
}

回答by Vishal

Close all opened tabs before opening selected tab. This will prevent multiple tabs from being open at one time.

在打开选定的选项卡之前关闭所有打开的选项卡。这将防止同时打开多个选项卡。

// Get all Accordion and Panel
let accHeading = document.querySelectorAll(".accordion");
let accPanel = document.querySelectorAll(".accordion-panel");

for (let i = 0; i < accHeading.length; i++) {
    // Execute whenever an accordion is clicked 
    accHeading[i].onclick = function() {
        if (this.nextElementSibling.style.maxHeight) {
           hidePanels();     // Hide All open Panels 
        } else {
           showPanel(this);  // Show the panel
        } 
    };
}

// Function to Show a Panel
function showPanel(elem) {
  hidePanels();
  elem.classList.add("active");
  elem.nextElementSibling.style.maxHeight = elem.nextElementSibling.scrollHeight + "px";
}

// Function to Hide all shown Panels
function hidePanels() {
  for (let i = 0; i < accPanel.length; i++) {
      accPanel[i].style.maxHeight = null;
      accHeading[i].classList.remove("active");
  }
}
* {box-sizing: border-box;}

/* Style the Headings that are used to open and close the accordion panel */
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  margin: 0;
  font-weight: 300;
}

/* Change color of the heading and icon (on hover and click) */
.active, .accordion:hover, .accordion:hover::after {
  background-color: #007eff;
  color: white;
}

/* Add "plus" sign (+) after Accordion */
.accordion::after {
  content: '
<div style="border: 1px solid lightgray;">
  <h2 class="accordion">Section 1</h2>
  <div class="accordion-panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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>
  </div>

  <h2 class="accordion">Section 2</h2>
  <div class="accordion-panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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>
  </div>

  <h2 class="accordion">Section 3</h2>
  <div class="accordion-panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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>
  </div>

  <h2 class="accordion">Section 4</h2>
  <div class="accordion-panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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>
  </div>
</div>
2B'; color: #777; font-weight: bold; float: right; } /* Add "minus" sign (-) after Accordion (when accordion is active) */ .active::after { content: "12"; color: white; } /* Style the accordion panel */ .accordion-panel { padding: 0 18px; overflow: hidden; max-height: 0; transition: max-height 0.2s ease-out; }
html
<div class="accordion"><b>Heading 1</b>
    <div class="panel">
        <p class="text-light">Text 1</p>
    </div>
    </div>
<div class="accordion"><b>Heading 2</b>
    <div class="panel">
        <p class="text-light">Text 2</p>
    </div>
    </div>

jquery:
$('.accordion').click(function() {
$(this).find('.panel').show();
$(this).siblings().find('.panel').hide();

});

回答by Maharajan

you have to cover the panel with accordion, so you can easily do that.

你必须用手风琴盖住面板,这样你就可以很容易地做到这一点。

refer this

参考这个

##代码##

Working example

工作示例