vladislav_boychenko
@vladislav_boychenko
Купаюсь в гривнах

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

Написал спойлеры, цель: открыть можно только один спойлер, все остальные всегда закрыты, но также есть возможность закрыть все. То есть если я открываю один спойлер, то по первому клику все закрываются, а он открывается. По второму клику на этот же спойлер он закрывается.
Вот, что у меня получается пока что: тыц
Не могу продумать логику скрипта, как это взаимосвязать все.
  • Вопрос задан
  • 243 просмотра
Решения вопроса 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 у этой коллекции элементов можно вынести отдельно и повесить на ту кнопку ,по клику на которую все должны свернуться, если эта опция требуется отдельно.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы