Задать вопрос
vladislav_boychenko
@vladislav_boychenko
Купаюсь в гривнах

Как прописать логику спойлеру, чтобы он закрывался на второй клик вместе со всеми остальными?

Написал спойлеры, цель: открыть можно только один спойлер, все остальные всегда закрыты, но также есть возможность закрыть все. То есть если я открываю один спойлер, то по первому клику все закрываются, а он открывается. По второму клику на этот же спойлер он закрывается.
Вот, что у меня получается пока что: тыц
Не могу продумать логику скрипта, как это взаимосвязать все.
  • Вопрос задан
  • 247 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Как опознать блоки со спойлерами, а также заголовки и контент у них внутри; какой класс надо переключать; как контент должен изменять свою видимость. Ну и сама логика переключения видимости контента - при закрытии спойлеров не надо обрабатывать текущий, т.е., инвертировали состояние кликнутого, взяли все, отбросили кликнутый, закрыли:

const containerSelector = '.spoiler-container';
const headerSelector = '.spoiler-header';
const contentSelector = '.spoiler-content';
const activeClass = 'active';
const toggleEffect = 'slideToggle'; // или fadeToggle, или toggle
const hideEffect = 'slideUp'; // или fadeOut, или hide

function toggle($containers, $container) {
  $containers
    .not($container)
    .removeClass(activeClass)
    .find(contentSelector)
    [hideEffect]();

  $container
    .toggleClass(activeClass)
    .find(contentSelector)
    [toggleEffect]();
}

Обработчик клика подключается блокам со спойлерами, но клики слушаться будут только по заголовкам:

const $containers = $(containerSelector).on('click', headerSelector, e => {
  toggle($containers, $(e.delegateTarget));
});

В случае, если предполагается добавление новых блоков уже после подключения обработчика, то его, обработчик, следует добавить на документ - так всё будет работать как надо без каких-либо дополнительных телодвижений:

$(document).on('click', `${containerSelector} ${headerSelector}`, e => {
  toggle($(containerSelector), $(e.target).closest(containerSelector));
});
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
planc
@planc
это называется - accordion

https://www.w3schools.com/howto/howto_js_accordion.asp
Ответ написан
Комментировать
vetero4eg
@vetero4eg
Frontend
Я не великий спец, но действовала бы так - механизм открытия реализовала бы через анимацию, повешенную на класс типа .active, и по клику, если элемент актив, убираем у него этот класс, если не актив - ему добавляем, а у всех остальных - убираем. функцию убрать все классы active у этой коллекции элементов можно вынести отдельно и повесить на ту кнопку ,по клику на которую все должны свернуться, если эта опция требуется отдельно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы