Главная > CSS/Style Sheets > jQuery Fixer Upper - развертывающиеся контентные секции

jQuery Fixer Upper - развертывающиеся контентные секции


7 июня 2011, 15:50. Разместил: Mysterious Master
Недавно на форуме CSS-Tricks пользователь под ником Waffle опубликовал небольшой отрывок кода jQuery javascript:

$(function(){

        $('.ContactArea').hide();

        $('.Portfolio').hide();

        $('.WebDesign').hide();

        $('.AboutCoadin').hide();

        $('li.Contact').click(function(){
                $(".ContactArea").slideToggle();
        });

        $('li.PortfolioBtn').click(function(){
                $(".Portfolio").slideToggle();
        });

        $('li.WebDesignBtn').click(function(){
                $(".WebDesign").slideToggle();
        });

        $('li.AboutBtn').click(function(){
                $(".AboutCoadin").slideToggle();
        });

});

Сам вопрос от пользователя заключался в том, какие существуют способы развития кода в целях добавления функционала типа прокручивания страницы вниз примерно на ту область, на которую раскрывается скрипт. Но отрывок кода был таков, что там явно нужна была рука профессионала, так как там были некоторые вещи, которые остальные разработчики реализовали бы совсем иначе. Нам показалось, что в мире достаточно разработчиков кода на уровне того пользователя (Waffle), и мы решили поделиться некоторыми уроками и с вами, наши читатели!

Всё это работает, но…

Давайте начнём с того, что с кодом Waffle всё в порядке, он отлично работает и даже практически не влияет на скорость загрузки страницы, так как имеет очень незначительный вес. Тем не менее, исправления, которые мы внесём, сделают код более приятным глазу, более эффективным, более гибким и позволят исправить ещё некоторые вещи. А также, объяснения внесённых изменения дадут возможность нашим пользователям понять и научиться чему-то новому и полезному.

Нужно ли нам положение готовности DOM?

Первая строка кода выглядит так:

$(function(){

…что является укороченной версией от jQuery для «When the DOM is ready to manipulated, run this function...» (Когда DOM готов к управлению, запустите данную функцию…). Это достаточно безопасно потому, как, например, селекторы не будут запускаться при HTML-коде без парсинга, что может крайне удивить того, кто с этим не знаком. Здесь также не будет ожидания полной загрузки страницы, что может привести к тому, что скрипт покажется несуразным.

Всё дело в том, что мы должны запускать скрипты в самой нижней части страниц (перед закрытием тэга «/body»), тогда загрузка скрипта не будет задерживать загрузку остального контента страницы. Если мы правильно загружаем скрипты (в подвале страницы), то нам и не нужно будет положение готовности DOM, так как браузер уже разберётся со всем кодом HTML, прежде чем загружать скрипты.

Множественные селекторы, один объект jQuery

Следующие строки кода выглядят так:

$('.ContactArea').hide();
$('.Portfolio').hide();
$('.WebDesign').hide();
$('.AboutCoadin').hide();

Здесь не обязательно создавать 4 отдельных объекта jQuery, так как вы можете использовать разные селекторы для одного объекта. Этот код делает примерно то же самое:

$(".ContactArea, .Portfolio, .WebDesign, .AboutCoadin").hide();


Как и в случае с CSS-селектором. Тем не менее, возможно вам понадобится 4 отдельных объекта jQuery, чтобы можно было обратиться к ним в любой момент без нужды создания нового. В таком случае, можно установить переменные:

var contactArea = $('.ContactArea').hide(),
    portfolio   = $('.Portfolio').hide(),
    webDesign   = $('.WebDesign').hide(),
    about       = $('.AboutCoadin').hide();

Вам также стоит рассмотреть вариант применения имени класса к коду HTML типа «initial-hide» и применить его ко всем элементам, которые вы хотите скрыть на момент загрузки страницы. Но помните, что это может противоречить семантике кода.

ID

Сложно что-то объяснять, не имея на примере реального веб-сайта, но нам кажется, что области из разряда «контакты» и «портфолио» являются полностью уникальными областями. То есть они не повторяются по несколько раз. Уникальные области идеально подходят под применение ID (как альтернатива классам). Преимущество здесь заключается в скорости загрузки и работы.

$("#ContactArea") // is faster than
$(".ContactArea")

Ещё одна важная вещь, которую нужно знать об ID, это то, что они по сути своей являются естественными атрибутами для ссылок с указанием области на странице (причем, это будет работать независимо от активности поддержки javascript):

<!-- This link will jump down the page ... -->
<a href="#ContactArea">Contact</a>

<!-- ... to ensure this element is visible -->
<section id="ContactArea"></section>

Возможно, вам не понадобится прыгать по странице, тогда вы можете предотвратить это с помощью javascript. Без javascript вам точно захочется, чтобы навигация по одной странице состояла именно из ссылок с указанием области на странице.

Выберите нужный элемент

В следующей части кода у нас будет 4 повторения:

$('li.Contact').click(function(){
        $(".ContactArea").slideToggle();
});

$('li.PortfolioBtn').click(function(){
        $(".Portfolio").slideToggle();
});

$('li.WebDesignBtn').click(function(){
        $(".WebDesign").slideToggle();
});

$('li.AboutBtn').click(function(){
        $(".AboutCoadin").slideToggle();
});

Первое, что стоит упомянуть, это то, что здесь есть текущий выделенный элемент. Вёрстка здесь должна быть предположительно такой:

<nav>
  <ul>
     <li class="ContactArea"><a href="#">Contact</a></li>
     <li class="PortfolioBtn"><a href="#">Contact</a></li>
     <li class="WebDesignBtn"><a href="#">Contact</a></li>
     <li class="AboutBtn"><a href="#">Contact</a></li>
  </ul>
</nav>

Код jQuery выделяет пункты списка по их именам классов. С этим могут возникнуть различные нестыковки:

1. Они не все используют «Btn». Если вы будете использовать нечто с такими классами, то вам наверняка захочется сделать это приближенным к стандарту. Правда, если вы не будете придерживаться определенных правил, то это может повлечь другие более крупные несоответствия.

2. Вам не нужно уникально стилизовать классы CSS. Вы можете использовать :nth-child или :nth-of-type. До того момента, пока вам не придётся реализовывать поддержку более ранних версий браузеров, вы можете ими пользоваться.

3. Так как вам не нужно стилизовать их, мы бы предположили, что они совсем нам не нужны.

Учитывая, что вёрстка может быть изменена под использование ID вместо классов, то HTML-код будет выглядеть примерно так:

<nav>
  <ul>
     <li><a href="#ContactArea">Contact</a></li>
     <li><a href="#Portfolio">Portfolio</a></li>
     <li><a href="#WebDesign">Web Design</a></li>
     <li><a href="#AboutCoadin">About</a></li>
  </ul>
</nav>

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

Не повторяйтесь

Это правило часто используется в зарубежных коммьюнити в виде аббревиатуры DRY – («Don’t Repeat Yourself»). 4 положения ведут к повторению выделенного материала и slideToggling. Мы можем исправить это посредством нашей обновленной структуры HTML-кода.

Атрибут href для тех анкоров в навигации представляет собой нечто вроде «#contact», что нам как раз и требуется для того, чтобы использовать в качестве селектора. Невероятно удобно! Давайте возьмём этот атрибут и превратим его в селектор. Таким образом, одним кликом можно нажимать сразу на любую из 4-х имеющихся ссылок:

$("nav a").click(function(e){
  e.preventDefault();
  $($(this).attr("href")).slideToggle();
});

Итоговый код

Наш итоговый код заканчивается очень лаконично:

$("#ContactArea, #WebDesign, #Portfolio, #AboutCoadin").hide();

$("nav a").click(function(e){
  e.preventDefault();
  $($(this).attr("href")).slideToggle();
});

Посмотреть демо
Вернуться назад