【问题标题】:Toggle issue with Accordions/Tabs using JS (ES6)使用 JS (ES6) 切换手风琴/标签的问题
【发布时间】:2017-12-03 22:10:51
【问题描述】:

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

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');
    }
};

【问题讨论】:

    标签: javascript css dom ecmascript-6 accordion


    【解决方案1】:

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

    (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 保存一个值,该值是当前具有类activeaccordion 元素的索引。所以0 &lt;= current &lt; accordion.length。可能没有活动元素(所有accordion 元素都已关闭),因此我们需要一个值来表明这一点。该值不得在上述范围内。它可以是任何东西:null, false, "oompa loompa", ... 由于使用 -1 是通用的(indexOf 确实表示不存在),所以我也选择了它。

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

    当一个元素被点击时,我们还想检查它是否不是活动元素(i !== -1)。因为如果我们不这样做,那么我们将删除if 中的活动类,toggles 会将它们添加回来。所以如果没有这个测试,当点击活动元素时,它将保持活动状态。

    【讨论】:

    • 太棒了,成功了。再次感谢易卜拉欣!你能解释一下为什么必须将当前变量设置为-1(这样我才能更好地理解)
    • @ImranR 不客气!我已经添加了一些解释。我希望很清楚,因为英语不是我的母语。另请查看代码 sn-p 中的 cmets,它们也很有帮助。
    • 谢谢你说得通!很有见地
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多