В этом туториале я рассмотрю пример создания приложения FAQ (часто задаваемые вопросы), в котором вопросы и ответы будут располагаться в двух расположенных рядом контейнерах с полосами прокрутки. Вместо стандартных полос прокрутки я создам собственный дизайн, а прокручивание сделаю плавным, плюс добавлю меню-аккордеон со списком вопросов.
Окончательный результат будет работать следующим образом: смотреть.
Для создания полос прокрутки я буду применять плагин jScrollPane, который в свою очередь требует jquery.dimensions.js, а также jquery.mousewheel.js чтобы можно было прокручивать список при помощи колесика мышки.
Для начала скачайте дистрибутив jScrollPane и распакуйте его в папку с вашим приложением. Затем создайте HTML документ в который подключите библиотеку jQuery и затем три вышеперечисленных скрипта, которые входят в состав дистрибутива jScrollPane:
<script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery.dimensions.min.js"></script> <script type="text/javascript" src="js/jquery.mousewheel.min.js"></script> <script type="text/javascript" src="js/jScrollPane.js"></script>
Далее подключаем необходимые CSS файлы — jScrollPane.css, который содержит стили полос прокрутки, и style.css — файл в котором я буду указывать все остальные стили на странице:
<link rel="stylesheet" type="text/css" media="all" href="css/style.css" /> <link rel="stylesheet" type="text/css" media="all" href="css/jScrollPane.css" />
Теперь можно собственно приступать к созданию нашего ЧаВО. Чтобы обеспечить принцип «ненавязчивости» для скрипта (пользователь должен иметь возможность пользоваться ЧаВО даже если JavaScript не включен), заголовки ответов, которые будут находиться в правой части, заключим в ссылки типа <a name=»h_b_1″>ответ</a> переход к которым будем осуществлять ссылками вида <a href=»#h_b_1″>Q: вопрос .. ?</a>.
Общая структура выглядит следующим образом:
<div id="container"> <div id="title">Часто задаваемые вопросы (ЧаВо)</div> <div id="left_pane"> <div class="scrollable"> <h6 class="opened">Общая информация (заголовок раздела)</h6> <ul> <li><a href="#a_i_1">Q: Какой то вопрос?</a></li> .... </ul> .... </div> </div> <div id="right_pane"> <div class="scrollable"> <h4>Общая информация</h4> <p class="question"><a name="a_i_1">Q: Какой то вопрос?</a><br/> A: Некоторый ответ.</p> .... </div> </div> <br style="clear:both" /> </div>
Див с id=container размещаем посреди страницы, указывая для него width и margin, а левый и правый контейнеры для вопросов и ответов располагаем при помощи float. Div с классом scrollable используется как контейнер с прокруткой, для него ставим overflow:auto. В общем содержимое файла style.css будет следующим:
body { font-size: 12px; font-family: Georgia, Arial, Verdana, sans-serif; } h6 { font-size: 12px; font-weight: bold; margin: 4px 0; cursor: pointer; } #container { width:780px; margin: 20px auto; background: #fff; border: 1px solid #aaa; } #title { padding: 6px 0; text-align: center; font-size: 20px; } #left_pane, #right_pane { border: 1px solid #aaa; } .scrollable { width: 370px; height: 350px; overflow: auto; } .scrollable ul { position: relative; } #left_pane { float: left; margin: 10px 0 10px 10px; } #right_pane { float: right; margin: 10px 10px 10px 0; } .question a {font-style:italic}
На этом этапе приложение выглядит следующим образом: смотреть.
Теперь наведем немного красоты — создадим меню аккордеон:
$(document).ready(function(){ $('#left_pane h6').each(function(i){ if(i!=0){ $(this).next().hide(); $(this).attr('class','closed'); } $(this).click(function(){ if ($(this).hasClass('opened')) return; // закрываем все подменю $('#left_pane h6.opened').each(function(){ $(this).attr('class','closed'); $(this).next().slideUp(); }); // открываем меню, на котором щелкнул пользователь $(this).attr('class','opened'); $(this).next().slideDown('slow'); }); }); });
В самом начале мы закрываем все подменю при помощи функции slideUp(), оставляя открытым только первое (используем аргумент i в функции each для получения индекса). Подменю будет открываться/закрываться при нажатии на заголовке (тег h6) при помощи функций slideUp() и slideDown(), при этом открытому меню будет присваиваться класс opened, а закрытому — closed.
Следующий шаг — создание полос прокрутки. Для этого добавляем вызов функции jScrollPane():
$('.scrollable').jScrollPane({animateTo:true, showArrows:true, scrollbarWidth:11});
Здесь параметр animateTo указывает на то что нужно использовать анимацию при последующих вызовах scrollTo(), showArrows — для отображения стрелок вверху и внизу полосы прокрутки, scrollbarWidth устанавливает ширину полосы прокрутки.
И последнее, плавное прокручивание к нужному месту обеспечиваем при помощи следующей функции:
$('#left_pane li a').click(function(event){ var target = $('#right_pane a[name='+$(this).attr('href').replace('#','')+']'); var cont = $('#right_pane .scrollable'); var p = target.parent(); var h = parseInt(p[0].offsetTop); cont[0].scrollTo(h); event.preventDefault(); });
Указатель на тег с ответом мы получаем из атрибута href ссылки, затем определяем координату этого элемента по вертикали при помощи offsetTop() и затем плавное прокручивание функцией scrollTo().
Окончательный код выглядит следующим образом:
$(document).ready(function(){ $('#left_pane h6').each(function(i){ if(i!=0){ $(this).next().hide(); $(this).attr('class','closed'); } $(this).click(function(){ if ($(this).hasClass('opened')) return; $('#left_pane h6.opened').each(function(){ $(this).attr('class','closed'); $(this).next().slideUp(); }); $(this).attr('class','opened'); $(this).next().slideDown('slow'); $('#left_pane .scrollable').jScrollPane({animateTo:true, showArrows:true, scrollbarWidth:11}); }); }); $('.scrollable').jScrollPane({animateTo:true, showArrows:true, scrollbarWidth:11}); $('#left_pane li a').click(function(event){ var target = $('#right_pane a[name='+$(this).attr('href').replace('#','')+']'); var cont = $('#right_pane .scrollable'); var p = target.parent(); var h = parseInt(p[0].offsetTop); cont[0].scrollTo(h); event.preventDefault(); }); });
Обратите внимание, что вызов функции jScrollPane() добавлен дополнительно в функцию, реализующую меню. Это сделано для того, чтобы полоса прокрутки появлялась только в том случае, если открывшееся меню будет больше видимой части контейнера.
И последнее — подкорректируем дизайн полосы прокрутки, редактируя файл jScrollPane.css. На следующей картинке указано, какие стили в нем нужно редактировать:

Всё, приложение готово.
P.S.: текст FAQ в демо примере взят на одном из сайтов, которые я недавно разрабатывал, ибо «Lorem Ipsum» уже несколько поднадоел.