Блог о веб-технологиях и JavaScript

Туториал — приложение FAQ на jQuery

В этом туториале я рассмотрю пример создания приложения 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» уже несколько поднадоел.

смотреть демозагрузить пример

Дмитрий Ищенко © 2007 - 2013