使用JS(ES6)切换Accordions / Tabs的问题

时间:2017-12-03 22:10:51

标签: javascript css dom ecmascript-6 accordion

我对以下手风琴/标签布局有轻微问题:

https://jsfiddle.net/drj3m5tg/

正如您将看到的,在移动设备上,当打开和关闭其他标签时,右侧的“+”图标将保留为“ - ”图标。在桌面视图中,有时需要单击选项卡两次以显示下面的内容。我检查了chrome检查器,并且可以看到在再次单击之前不会删除活动类。有没有办法使用JS来解决这个问题?

const accordion = document.getElementsByClassName("accordion");
const panel = document.getElementsByClassName("panel");

for(let i = 0; i < accordion.length; i++){
  accordion[i].addEventListener('click', function(){
    removeOpen();
    // add active class to clicked element and open class to next slibling
    const toggleResult = this.classList.toggle('active');
    this.nextElementSibling.classList.toggle('panel-open', toggleResult);


  });
};

 // remove open class for all elements
function removeOpen (){
    for(let i = 0; i < panel.length; i++) {
       panel[i].classList.remove('panel-open');
    }
};

1 个答案:

答案 0 :(得分:1)

这是因为您必须从其他active按钮中删除accordion类。当你这样做时,你将陷入另一个问题,即切换不再有效。所以我建议你这样做(重构整个事情):

(function() {                                                           // not really necessary (just to hide our variables from the outside scope)
    const accordion = document.getElementsByClassName("accordion");     // the .accordion buttons (no need for panels, we can get them using nextElementSibling)
    let current = -1;                                                   // the index of the current active accordion element (-1 indicate that currently no element is active)

    for (let i = 0; i < accordion.length; i++) {
        accordion[i].addEventListener('click', function() {             // when clicking a .accordion element
            if (i !== current && current !== -1) {                      // if this is not the currently active element (i !== current), and if there is a currently active element (current !== -1)
                accordion[current].classList.remove('active');          // then desactivate the currently active element
                accordion[current].nextElementSibling.classList.remove('panel-open'); // ...
            }
            this.nextElementSibling.classList.toggle('panel-open');     // now toggle the current element
            current = this.classList.toggle('active') ? i : -1;         // ... (if this element is toggled on, then set current to be this element, if it is toggled off then set current to -1 as there will be no active elements)
        });
    };
})();

JSFiddle

修改

current包含一个值,该值是具有类accordion的当前active元素的索引。所以0 <= current < accordion.length。可能没有活动元素(所有accordion元素都已关闭),因此我们需要一个值来表示。该值不得在上述范围内。它可以是任何内容:nullfalse"oompa loompa",...因为使用-1是通用的(因为indexOf表示不存在),我也选择了它。

至于我们为什么要使用它?。好吧,不是每次点击一个元素时从所有元素中删除活动类,我们只是跟踪活动元素,每次点击另一个元素时我们只从一个元素中删除它们(其索引存储在{{1 }})。由于当前也表明没有元素,我们必须先测试(current)。

单击某个元素时,我们还要检查它是否不是活动元素(current !== -1)。因为如果我们不这样做,那么我们会删除i !== -1中的活动类,而if会将它们添加回来。因此,如果没有此测试,单击活动元素时,它将保持活动状态。