Переключить проблему с Аккордеонами / Вкладками, используя JS (ES6)

1

У меня небольшая проблема со следующим оформлением аккордеона/табуляции:

https://jsfiddle.net/drj3m5tg/

Как вы увидите, на мобильном телефоне значок "+" справа отображается как значок "-" при открытии и закрытии других вкладок. А на рабочем столе на вкладках иногда нужно дважды щелкнуть, чтобы отобразить содержимое ниже. Я проверил в хромовом инспекторе и вижу, что активный класс не удаляется, пока не щелкнет снова. Есть ли способ исправить это поведение с помощью 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');
    }
};
Теги:
ecmascript-6
dom
accordion

1 ответ

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 закрыты), поэтому нам нужно значение, чтобы указать это. Значение не должно находиться в вышеупомянутом диапазоне. Это может быть что угодно: null, false, "oompa loompa" ,... Поскольку универсально использовать -1 (поскольку indexOf делает для указания на неспособность), я тоже выбрал его.

Почему мы это используем? Ну, вместо того, чтобы удалять активные классы из всех элементов при каждом щелчке элемента, мы просто отслеживаем активный элемент, и каждый раз, когда нажимаем другой элемент, мы удаляем их только из одного элемента (индекс которого хранится в current). Поскольку ток также указывает, что нет элемента, мы должны сначала проверить (current !== -1).

Когда элемент кликается, мы также хотим проверить, не является ли он активным элементом (i !== -1). Потому что, если мы этого не сделаем, мы удалим активные классы внутри if и toggle добавит их обратно. Таким образом, без этого теста при нажатии активного элемента он останется активным.

  • 0
    Удивительно, что сделали свое дело. Еще раз спасибо, Ибрагим! Можете ли вы объяснить мне, почему текущая переменная должна быть установлена в -1 (просто, чтобы я лучше понял)
  • 0
    @ImranR Добро пожаловать! Я добавил некоторые объяснения. Я надеюсь, это понятно, потому что английский не мой родной язык. Также проверьте комментарии в фрагменте кода, они также полезны.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню