Раскрывающиеся блоки довольно популярное решение, если необходимо сэкономить место или, когда контент разделен на группы, и какая-то его часть может быть не интересна ряду пользователей сайта.
Данный функционал может быть реализован различными способами, но в сегодняшней статье я не буду касаться готовых плагинов, а рассмотрю три варианта реализации «стандартными» средствами: с использованием библиотеки jQuery, при помощи JavaScript + classList API и на «чистом» JavaScript. Почему я отнес jQuery к «стандартным» средствам? Ну, согласитесь, библиотека получила настолько широкое распространение, что используется практически на всех сайтах, где вообще присутствует хоть какой-то JavaScript.
Перед тем как начнем вникать в код, хотелось бы рассмотреть плюсы и минусы данных реализаций раскрывающихся блоков.
Начнем с jQuery. Это самый короткий и легкий способ. Код получается длиной всего в несколько строк, причем написать его сможет и начинающий веб-разработчик. Главный минус – необходимость подключения библиотеки в несколько тысяч строк и маячащая на горизонте перспектива несовместимости выбранной версии jQuery с другими плагинами, которым в будущем неминуемо обрастет сайт.
Следующий вариант использовать все-таки JavaScript и сравнительно молодой classList API. Для тех, кто не знает, поясню: classList API появился с развитием стандарта HTML5 и позволяет получать список классов элементов DOM дерева, что значительно облегчает код и экономит нервы разработчику. Технология уже надежно поддерживается всеми современными браузерами, в том числе и IE10. Кроме того, благодаря ряду умельцев, появились скрипты позволяющие использовать classList API и в старых браузерах (более подробно об поддержке читаем тут caniuse). Все плюсы налицо и от пары-тройки тысяч строк избавились.
Ну и третий вариант – старый добрый JavaScript в чистом виде. Работает железно везде, если заморочиться над поддержкой! Но требует определенного уровня подготовки от разработчика.
За и против разобрали – приступим к конкретным примерам.
Создаем три заготовки: div с классом block, в него кладем два div с классами title и content:
<div class="block">
<div class="title">
<!-- Название -->
<span></span>
</div>
<div class="content">
<!-- Контент -->
</div>
</div>
Прописываем следующие стили, блок с контентом прячем при помощи свойства display со значением none:
.block{
background-color: #fff;
border: 1px solid #f0f0f0;
margin: 20px auto 0;
width: 550px;
}
.block .title{
cursor: pointer;
padding: 10px 7px;
position: relative;
}
.block .title.active{
background-color: #c7e7f9;
color: #1d7ee4;
}
.block .title span{
background: url(plus-minus.png) no-repeat 0 center;
display: block;
height: 9px;
position: absolute;
right: 7px;
top: 14px;
width: 9px;
}
.block .title.active span{
background-position: -9px 0 !important;
}
.block .content{
padding: 10px 7px;
font-size: 14px;
display: none;
}
.block .title.active + .content{
display: block;
}
Для отображения блока с контентом, мы при помощи скрипта будем добавлять класс active к элементу с классом title.
Для каждого примера пишем свои id: block-jq, block-jshtml5, block-js.
Первый вариант jQuery:
$("#block-jq .title").toggle(function(){
$(this).addClass("active");
}, function(){
$(this).removeClass("active");
});
Используем jQuery метод toggle(), который при первом клике на элемент c классом title, добавляет к нему класс active, в результате чего блок с контентом раскрывается. При повторном клике класс active удаляется, блок снова становится невидимым.
Второй вариант JavaScript + classList API:
var title1 = document.querySelector("#block-jshtml5 .title");
title1.onclick = function(){
if(this.classList.contains("active")){
this.classList.remove("active");
}else{
this.classList.add("active");
};
};
Здесь мы отслеживаем событие клика по элементу с классом title, после чего при помощи метода contains() проверяем наличие у него класса active. Если данный класс присутствует – удаляем его (remove), если нет – добавляем (add).
Третий вариант JavaScript:
var title2 = document.getElementById("block-js").getElementsByTagName("DIV")[0];
title2.onclick = function(){
if(this.className.indexOf("active") != -1){
this.className = this.className.replace(" active", "");
}else{
this.className += " active";
};
};
По существу, делаем то же самое, что и в предыдущем варианте, с тем отличаем, что JavaScript не имеет методов, чтобы отследить наличие класса active у элемента с несколькими классами и добавить или удалить его. Поэтому нам приходится оперировать со строками. Сначала находим элемент с нужным нам id, затем по клику мыши методом indexOf() находим первое (!=-1) вхождение подстроки «active» в значении className. Если таковая найдена, методом replace() заменяем её на пустую подстроку (« »), вследствие чего у элемента исчезает данный класс. Если же подстрока не найдена, то добавляем её путем конкатенации строки « active» к значению className.
Как видим логика во всех трех вариантах одинаковая, механика же разная. Чем пользоваться? Кто к чему привык. Первый вариант самый простой, но тянет за собой огромную библиотеку, у второго придется слега заморочиться с поддержкой старыми браузерами, третий отработает везде, вот только возможность сделать ошибку, даже в таком небольшом скрипте, достаточно высока.
Спасибо что читали, в одной из следующих статей я расскажу как реализовать данный пример с плавным раскрытием и закрытием блока контента, тоже несколькими способами.