如何一次只显示一只手风琴

时间:2019-07-04 16:08:55

标签: javascript html css

我有几个手风琴下拉菜单,可以分别打开和关闭它们,但是我真正想要实现的是

  1. 在我打开一个时自动关闭另一个
  2. 在我打开另一个孩子(用于多层手风琴)时关闭一个孩子

这就是我能够实现的目标

<div class="a0f13_2aGAs">
    <div class="_5cb4a_2yTAQ"><span>Categories</span></div>
    <ul class="_44ec6_3AFlz" id="accordion">
        <li class="_99e51_2Fldz">
            <button class="accordion"><a href="#y">Main drop 1</a></button>
            <div class="panel">
                <ul class="cat">
                    <li class="cat">
                        <div>
                            <a class="cat" href="#x">
                                <span class="_33353_3KdIO">
                                    PC</span><span class="_3b1e8_3gyVo">
                                    <svg height="16" viewBox="0 0 9 16" width="9"
                                        xmlns="http://www.w3.org/2000/svg" class=""
                                        name="chevron-next-outline">
                                        <path
                                            d="M.659.65a.532.532 0 0 0 0 .75l6.583 6.593-6.583 6.606a.532.532 0 0 0 0 .75.527.527 0 0 0 .747 0L8.349 8.38a.519.519 0 0 0 .155-.375.54.54 0 0 0-.155-.375L1.406.662A.516.516 0 0 0 .659.65z"
                                            fill="#50545B" fill-rule="evenodd"></path>
                                    </svg>
                                </span>
                            </a>
                        </div>
                    </li>
                    <li class="cat">
                        <div>
                            <a class="cat" href="#x">
                                <span class="_33353_3KdIO">
                                    PC 2</span><span class="_3b1e8_3gyVo">
                                    <svg height="16" viewBox="0 0 9 16" width="9"
                                        xmlns="http://www.w3.org/2000/svg" class=""
                                        name="chevron-next-outline">
                                        <path
                                            d="M.659.65a.532.532 0 0 0 0 .75l6.583 6.593-6.583 6.606a.532.532 0 0 0 0 .75.527.527 0 0 0 .747 0L8.349 8.38a.519.519 0 0 0 .155-.375.54.54 0 0 0-.155-.375L1.406.662A.516.516 0 0 0 .659.65z"
                                            fill="#50545B" fill-rule="evenodd"></path>
                                    </svg>
                                </span>
                            </a>
                        </div>
                    </li>
                </ul>
            </div>
        </li>
        <li class="_99e51_2Fldz">
            <button class="accordion"><a href="#y">Main drop 2</a></button>
            <div class="panel">
                <ul class="cat">
                    <li class="cat">
                        <button class="accordion ac2" data-parent="#myGroup"><a href="#y">sub drop 1</a></button>
                        <div class="panel">
                            <ul class="cat">
                                <li class="cat">
                                    <div>
                                        <a class="cat" href="#x">
                                            <span class="_33353_3KdIO">
                                                PC</span><span class="_3b1e8_3gyVo">
                                                <svg height="16" viewBox="0 0 9 16" width="9"
                                                    xmlns="http://www.w3.org/2000/svg" class=""
                                                    name="chevron-next-outline">
                                                    <path
                                                        d="M.659.65a.532.532 0 0 0 0 .75l6.583 6.593-6.583 6.606a.532.532 0 0 0 0 .75.527.527 0 0 0 .747 0L8.349 8.38a.519.519 0 0 0 .155-.375.54.54 0 0 0-.155-.375L1.406.662A.516.516 0 0 0 .659.65z"
                                                        fill="#50545B" fill-rule="evenodd"></path>
                                                </svg>
                                            </span>
                                        </a>
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </li>
                    <li class="cat">
                        <button class="accordion ac2" data-parent="#myGroup"><a href="#y">sup drop 2</a></button>
                        <div class="panel">
                            <ul class="cat">
                                <li class="cat">
                                    <div>
                                        <a class="cat" href="#x">
                                            <span class="_33353_3KdIO">
                                                PC</span><span class="_3b1e8_3gyVo">
                                                <svg height="16" viewBox="0 0 9 16" width="9"
                                                    xmlns="http://www.w3.org/2000/svg" class=""
                                                    name="chevron-next-outline">
                                                    <path
                                                        d="M.659.65a.532.532 0 0 0 0 .75l6.583 6.593-6.583 6.606a.532.532 0 0 0 0 .75.527.527 0 0 0 .747 0L8.349 8.38a.519.519 0 0 0 .155-.375.54.54 0 0 0-.155-.375L1.406.662A.516.516 0 0 0 .659.65z"
                                                        fill="#50545B" fill-rule="evenodd"></path>
                                                </svg>
                                            </span>
                                        </a>
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </li>
                </ul>
            </div>
        </li>
    </ul>
</div>

请给我任何帮助,

还请注意,如某些示例所示,我尝试了data-parent="#accordion"方法,但这没有用

这是一个工作的jsfiddle

https://jsfiddle.net/k7f38es6/

谢谢

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作。我还没有完全测试过,但这应该可以。 希望这会有所帮助。

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

for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
        resetAccordian(this);
        var panel = this.nextElementSibling;
        if (panel.style.display === "block") {
            panel.style.display = "none";
            this.classList.remove("active");
        } else {
            panel.style.display = "block";
        }
    });
}


resetAccordian = (originalTarget) => {
    let accordians = Object.values(acc);
    accordians.forEach( data => {
        if (data != originalTarget) {
            let target = data.nextElementSibling;
            data.classList.remove("active");
            if (target.style.display === "block") {
                target.style.display = "none";
            }
        } else {
            data.classList.add("active");
        }  
    }, originalTarget);
}

答案 1 :(得分:1)

我已经修改了您原来的小提琴,以实现我认为您想要实现的目标。

modified fiddle

这是代码的关键:

function openAccordionWindow(){
   for( var closeIndex = 0; closeIndex < acc.length; closeIndex++){
        acc[closeIndex].classList.remove('active');
        var panel = acc[closeIndex].nextElementSibling;
        console.log(panel);
        panel.style.display = 'none';
   }
   this.classList.add("active");
   var panel = this.nextElementSibling;
   panel.style.display = 'block';
   expandParents(panel);
}

function expandParents(target){
   var parent = target.parentElement;
   if(parent.id==='accordion'){
     return;
   }
   if(parent.classList.contains('panel')){
     parent.style.display = 'block';
   }
   parent.classList.add('tagged');
   expandParents(parent);
}

通常是我的处理方式:

  • 遍历所有手风琴元素,并将其关闭
  • 将属性添加到要打开的属性中。
  • 转到父元素。如果是面板,也将其打开。
  • 保持递归调用expandParents函数,直到您到达手风琴的根为止。在这种情况下,点击ID为“ accordion”的元素。
    • 到达面板时,将其展开。

存在一些效率问题,但是它将实现您想要的目标,并且不会有太大的问题,因为您永远不会真正拥有那么多手风琴。

但是,有些注释使将来变得更容易。

  • 当您要关闭/打开某些东西时,尽量不要使用切换键。很多人会犯此错误,通常可以正常工作,但是如果面板不知何故还不是“活动”的,您会把它设为“活动”。
  • 将匿名点击处理程序添加到事件侦听器是很常见的事情。这不仅会给内存带来问题(因为每个元素都会有一个单独的函数副本)(这是次要的),而且还会试图弄清楚代码的作用。功能齐全的函数可以使其立即变得很明显。
  • 您正在向元素添加“活动”类以使其突出显示,并且如果您的面板嵌套在手风琴本身中,则同一类也可以扩展手风琴。当然,这并不总是可能的。然后,“活动”类可以修改嵌套子级的显示状态。
  • 添加类进行扩展通常比直接修改内联样式更好。诸如“ activePanel”之类的类可以更改显示并提供灵活性,并使添加其他属性更加容易。
  • 您的面板可能并不总是紧随开关元件之后。在手风琴中可能会是这种情况,但是在药丸菜单以及此类或选项卡面板中,它们可能会被移除一定距离,或者在直接的父/子流程中未移除。您可能会考虑将自定义属性附加到手风琴选项卡和面板,以允许选择不是直接同级的其他元素。 bootstrap collapse模块的功能与此类似。
  • 假设您对语言或库/框架的某些要求没有任何限制,那么有很多事情可能会使这对您来说变得简单得多。 jQuery选择器和方法,以及诸如实现和引导之类的东西提供了这种功能,仅举几例。

编辑  -添加了额外的代码以扩展子菜单,并扩展了其子菜单的解释。