Уеб уроци и ресурси по HTML,
CSS, CSS3, JavaScript и други

Динамично показване/скриване на съдържание с jQuery 8

Сподели урока

В този урок ще ти покажа как да изградиш FAQ (Често задавани въпроси) секция с динамично показване/скриване на информацията към всеки въпрос.

Планиране

Проблем: Представи си, че на сайта си имаш дълъг лист с въпроси и отговори (това може да бъде т.нар. секция с “Често задавни въпроси”). Според посетителя, обема на предоставената информацията е прекалено голям. Всичко изглежда някак си претрупано и неорганизирано. Това го смущава и обърква. “Защо всичко изглежда толкова трудно? Защо няма прост и бърз начин за улесняване на търсенето без да се налага да изразходвам толкова време и усилия?”

Звучи ли ти познато? За съжаление, голяма част от уеб сайтовете не мислят от гледна точка на посетители си! В повечето случаи информацията я има, но достъпа до нея е прекалено труден.

Твоят сайт обаче не е такъв. Ти искаш да улесниш посетителите си и да направиш престоя им приятен и запомнящ се. Е, в такъв случай, нека видим как можем да решим проблема представен по-горе.

Едно възможно решение на проблема: След кратко ровичкане в Интернет откриваш страхотен начин за организиране на съдържанието по двойки въпрос-отговор. Първоначално, отговорите са скрити. Единственото, което посетителя вижда са въпросите. Според него, избора тук е много по-лесен, защото вниманието му фокусирано изцяло върху проблема, без излишен текст, който да го разсейва. След като намери въпроса, който го интересува, той решава да кликне върху него. Това задейства кратка анимация, която “избутва” следващите въпроси надолу, а на тяхно място се показва съответния отговор. Всичко това става по интересен и приятен начин.

Това е т.нар. акордеон, който показва определена информация, която се скрива при повторно натискане върху нея.

Посетителя остава доволен не само от бързото намиране на решение, но и от начина, по който го е открил.

Това вече е нещо друго. Надявам се, че забелязваш разликата. В първият случай посетителя трябваше да положи повече усилия в търсене на това, което го интересува. Във вторият случай обаче, контрола е изцяло негов и той решава кое да бъде видимо и кое не.

Целта ни в този урок е да направим подобен лист с въпроси и отговори. Той трябва да бъде едновременно интерактивен и лесен за възприемане, което да подтиква посетителя да взаимодейства с него.

Според мен, първата стъпка при стартиране на какъвто и да е проект е планиране. Спри за миг и помисли какво точно искаш да постигнеш. Как мислиш да го постигнеш? Това ли е най-доброто за посетителите ти?

Вземи лист хартия и пробвай да нахвърлиш идеята си, така както си я представяш.

Нищо друго няма да ти даде толкова добри и мигновени резултати както доброто и адекватно планиране. Това не само ще ти помогне да помислиш реално върху проблема, но и ще те насочи в правилната посока.

Следващото изображение илюстрира нагледно идеята.

Скициране на идея: Често задавани въпроси

Никак не изглежда зле. Структурата е добре изградена, а информацията е лесна за сканиране. В следващата стъпка ще се заемем с реализирането.

Забележка: Решението, което предлагам тук в никакъв случай не е единственото решение! Понякога ще се нуждаеш от нещо напълно различно. Важното е да помислиш какво ще бъде най-добро за посетителите ти.

Изпълнение

След като вече имаме идеята и знаем какъв трябва да бъде крайният резултат е време да се заемем с изпълнението. Ще се опитам да го направя максимално лесно и достъпно, за да разбереш начина на работа. Да се захващаме.

Структура на файловете

В този урок ще работим с 3 отделни файла - една HTML страница, един външен CSS файл, и един външен JavaScript файл.

Структура на работните файлове.

HTML

Естествено, започваме от създаването на html страницата. Едновременнно с това ще добавим и нужното съдържание.

Създай нов html документ с Doctype по твой избор. Аз ще използвам xHTML Strict. Кода изглежда така:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; 
					charset=utf-8" />
    		<title>Демо</title>
	 </head>
	<body>
		
	</body>
</html>

До тук нищо ново. Резултата е празна страница. Нека я запълним.

Добавяне на съдържание

В <body> тага поставим съдържанието, с което разполагаме. Първо нека видим кода, след което ще обясня неговото значение.

Забележка: Тук ще сложа само малка част от съдържанието, за да не удължавам излишно страницата. Пълният текст обаче ще бъде видим в демото.

<h1>Често задавани въпроси</h1>
<div class="accordion">
	<h2>Как работи формата за регистрация?</h2>
	<div>
		<p>Lorem ipsum <a href="#">link</a> sit amet, 
		<strong>bold</strong> <em>adipisicing</em> 
		elit. Nesciunt possimus sequi magnam nobis est cum 
		neque sint dolorem perspiciatis tempora!</p>
		<h3>Заглавие</h3>
		<ul>
			<li>Lorem ipsum dolor sit.</li>
			<li>Lorem ipsum dolor sit.</li>
			<li>Lorem ipsum dolor sit.</li>
		</ul>
	</div>
	<h2>Защо не мога да се регистрирам?</h2>
	<div>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing 
		elit. Nesciunt possimus sequi magnam nobis est cum 
		neque sint dolorem perspiciatis tempora!</p>
	</div>
</div>

Започваме с h1 заглавие. Това маркира началото на секцията с въпроси. Веднага след това създаваме нов <div> с клас <em>accordion</em>, който ще послужи като контейнер на останалото съдържание. Всеки въпрос тук ще бъде ново h2 заглавие, а всеки отговор ще бъде в отделен <div>.

Шаблона изглежда така:

Структура на шаблона въпрос-отговор.

Добави колкото искаш въпроси и отговори. Аз ще се огранича до 3.

Резултата до тук изглежда така:

Добавяне на основно съдържание

Добавяне на стил

Честно казано страницата не изглежда зле и в този си вид, но нищо няма да ни навреди, ако малко я разнообразим.

Първото нещо е да добавим линк към външния CSS файл. За тази цел добави следния код в <head>.

<link rel="stylesheet" type="text/css" href="style.css" />

Сега отвори CSS файла и добави следния код.

body {
	font: 14px/21px Verdana, Arial, sans-serif;
	margin: 0 auto;
	width: 550px;
}
h1, h2 {
	font-weight: normal;
	margin: 0;
	padding: 0;
}
h1 {
	background-color: #DC522F;
	border-radius: 5px 5px 0 0;
	color: #fff;
	font-size: 21px;
	margin-top: 15px;
	padding: 15px;
}
.accordion h2 {
	background-color: #FDF6E3;
	color: #268BD2;
	font-size: 18px;
	padding: 10px;
}
.accordion h2:hover {
	cursor: pointer;
	color: #DC522F;
}
.accordion {
	background-color: #FDF6E3;
	border: 1px solid #9f9f9f;
}
.accordion div {
	padding: 0 15px;
}

Общо взето не би трябвало да имаш проблеми с кода по-горе. Всичко е доста елементарно. Все пак ще опиша накратко най-важното.

  • body селектор – Тук променяме шрифта на цялата страница. 14px/21px означава, че текста ще бъде 14px голям, а разстоянието между редовете 21px. Също така ограничаваме ширината на 550px, след което посредством margin:0 auto; центрираме страницата в прозореца.

  • h1, h2 селектор – Зануляваме margin и padding. Променяме тежеста на текста на нормална.

  • .accordion h2:hover селектор – Най-интересното тук е, че курсора ще се промени на ръчичка, всеки път когато посетителя постави мишката върху заглавието. Това подсказва на посетителя, че може да кликне върху него.

Резултата изглежда доста приятно.

Резултат след добавяне на стил.

Надявам се, че останалото е ясно. Ако имаш въпроси, задай ги в коментарите след урока.

Добавяне на интерактивност чрез jQuery

Дойде момента да добавим и малко интерактивност. Честно казано в този си вид страницата изглежда доста отегчително и безинтересно. Наистина, текста е добре структуриран и подреден, но сякаш липсва нещо много малко, което да направи нещата още по-приятни.

Най-напред трябва да добавим jQuery към настоящата страница. В този урок ще използвам възможностите на Google Hosted Libraries, за да добавя линк към последната версия на jQuery. В случай, че искаш да научиш повече за тази услуга, разгледай урока “Добавяне на jQuery чрез Google Hosted Libraries”.

Отвори html файла и добави следния код точно преди затварящия <head> таг.

	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
	<script src="custom.js" type="text/javascript"></script>
</head>

В custom.js ще поставим нашия jQuery код затова е важно този файл да бъде добавен след jQuery библиотеката.

Отвори custom.js и добави следното:

$(document).ready(function(){
	var h2 = $('.accordion h2');
	$('.accordion > div').hide();

	h2.click(function() {
		$(this).next().slideToggle('fast');
	});
});

Тук вече става интересно.

  • Фунцкията $(document).ready(function(){ } я разгледахме в урока “Въвенение в jQuery” затова няма да навлизам в подробности. Само ще спомена, че тя изчаква зареждането на страницата преди да изпълни кода в нея.

  • var h2 = $('.accordion h2'); - Тъй като на страницата има няколко h2 заглавия е добра идеята да бъдат запазени в променлива. Селектора $('.accordion h2') ще избере (селектира) всички h2 заглавия, които се намират в елемента с клас accordion. Повече информация за class селектори в сайта на jQuery.

  • $('.accordion > div').hide(); - Когато страницата зареди, искаме всички отговори да бъдат скрити. Селектора $('.accordion > div') ще избере всички div елементи, които са директни “деца” на .accordion. (Повече за селектори тип “родител > дете” в сайта на jQuery).

След като изберем нужните елементи, извикваме функцията hide(), която ще ги скрие.

До тук резултата е следния:

Скриване на отговори с jQuery.

Близо сме до крайния резултат. В момента всички отговори са скрити. За съжаление обаче все още не сме добавили начин за показване, което ги прави неоткриваеми. Нека променим това.

Все още сме в custom.js. Веднага след кода от по-рано, добави следното:

h2.click(function() {
	$(this).next().slideToggle('fast');
});

Тук нещата изглеждат малко по-сложни, но всъщност не са. Нека разгледаме всичко стъпка по стъпка.

h2 е променливата, която създадохме по-рано. Едно от предимствата тук е, че вместо да избираме h2 заглавията отново, просто използваме вече създадената променлива. Тя ни дава доректна връзка към тях.

Веднага след това използваме метода click(), който имаме на разположение в jQuery. Този метод е т.нар. event handler, което означава, че ще се изпълни при настъпване на определено събърие. В случая това е кликване с мишката върху някое от h2 заглавията.

При клик ще се изпълни анонимната функция намираща се в скобите.

  • $(this) – Признавам си, това може да бъде малко трудно за възприемане. Особено, когато човек е начинаещ. Ще се опитам да създам специален урок за $(this) затова сега няма да навлизам в големи подробности. Единственоето, което трябва да знаеш е, че в този контекст, $(this) се отнася до h2 заглавието, върху което е било кликнато.

    Ако посетителя кликне върху първото h2 заглавие, то $(this) ще се отнася само за първото h2 заглавие. Ако кликне върху второто, $(this) ще се отнася само за второто и т.н.

  • next() – Това е jQuery метод, чрез който можем да избирем следващия елемент от същото ниво (т.нар. sibling) т.е. next() ще избере <div>-а, който се намира след h2 заглвавието.

  • slideToggle('fast') - Накрая добавяме slideToggle ефект, който ще покаже или скрие елемента в зависимост от настоящото му състояние.

    Думата fast, оградена в еденични кавички, определея бързината на показване/скриване. Възможните стойности тук са 'fast', 'slow' или произволна цифрова стойност в милисекунди (1000 = 1 сек). Ако не се зададе никаква стойност, ефекта ще бъде с бързина от 400 милисекунди (това е по подразбиране).

Ок, време е да запазиш промените. Сега отвори страницата в браузър. Ако си следвал/-а внимателно стъпките до тук (а и да не си ги, винаги можеш да разгледаш демото), трябва да имаш лист с въпроси, но без (видими) отговори. След като кликнеш върху някой от въпросите, съдържанието трябва да се “плъзне” надолу и на негово място да се появи съответния отговор.

Успешно изпълнение на урока.

Поздравления за добре свършената работа!

В този урок създадохме интерактивен и лесен за използване раздел с често задавни въпроси. Логиката, която използвахме тук, може да ти послужи за създаване и на други подобни неща – например меню, слайдшоу, логин форма и т.н. Използвай фантазията си, възможностите са неограничени.

Надявам се, че урока ти хареса, и че стъпките бяха лесно за следване. Как мислиш, би ли използвал подобно нещо на сайта си? Посетителите ти ще бъдат ли доволни и ще подобри ли престоя им? Сподели мнението си в коментарите по-долу.

Поздравления, това е краят на този урок!
За награда получаваш вкусен мъфин.

Награда за това, че успя да достигнеш до края на урока.

Хареса ли ти урока? Сподели го със света :)

Начало

8 страхотни коментара

  1. 1

    Георги
    13 януари 2013 13:53

    Само една идея да вметна, според мен ще е най-чисто DIV-овете да се крият с CSS, защото в момента при зареждане на страницата (особено при бавна връзка) ще се отворят всички DIV-ове и след това ще се скрият, което си е грозновато.

  2. 2

    Джават Ушев (автор)
    14 януари 2013 11:05

    @Георги: Идеята е наистина полезна. Благодаря. Определено не се бях замислял за това. Може би в днешно време прекалено много разчитаме на бързия интернет, който имаме, и е трудно да си представим, че има хора с по-бавен.

    Един проблем, който виждам при тази техника обаче е, че ако JavaScript по някаква причина бъде изключен, то страницата ще стане неизползваема, защото отговорите няма как да бъдат отворени. Докато при настоящото решение, изключването на JavaScript няма да навреди толкова много, защото ще се загуби само функционалността, но не и съдържанието.

    Може би решението е в баланс между двете.

  3. 3

    Данчо
    14 януари 2013 12:39

    Доста популярно решение в момента е да се прави такъв акордеон само с CSS3. Това изключва нуждата от включване на jQuery и наш отделен скрипт, плюс това не се притесняваме от изключен JavaScript.

    П.П.: От друга страна според мен няма нужда да се притесняваме от това дали някой си е изключил JavaScript-а на браузъра, понеже днешния WEB разчита твърде много на него и той така или иначе няма да може да види почти нищо от съвременните сайтове.

  4. 4

    Джават Ушев (автор)
    14 януари 2013 13:26

    @Данчо: Напълно си прав. Навлизането на CSS3 е наистина вълнуващо. Доста от нещата, които до скоро бяха постижими с jQuery (като това например), ще се създават без проблеми с CSS3. Така няма да сме толкова зависими от JS библиотеките, които използваме в момента. Бъдещето пред нас е светло :)

    Прав си и за притеснението от изключен JavaScript. Може би трябва да имаме малко повече доверие на посетителите :)

  5. 5

    Дани
    31 януари 2013 22:45

    Много красиви бутончета :) Направи така да изглежда и "Обратно към урока". Хареса ми приложението на спойлера. А статистика имаш ли за това колко от сърфиращите блокират JavaScript? Аз твърде много разчитам на него. Поздрави :)

  6. 6

    Дани
    31 януари 2013 22:48

    Още нещо се сетих. Защо вместо картинки илюстриращи приложението, което може да се види, ако се последва линк към отделна страница, просто не я вградиш с iframe? От една страна може даже общия размер да падне, а аз си спомням при първият ми досег с полезния ти сайт как цъках на картинките очаквайки да реагират :D

  7. 7

    Джават Ушев (автор)
    03 февруари 2013 11:34

    @Дани: За съжаление нямам никаква статистика за това, колко хора си изключват JavaScript-а. Според мен обаче не са много. Посетителите също твърде много зависят от него, за да го блокират. В днешно време почти няма сайт, който да не използва JS по някакъв начин. Ако някой го изключи, това е по-скоро негово лично предпочитание, отколкото тренд. Въпреки това обаче би било хубаво, ако сайта е достъпен и при изключен JavaScript.

    Обмислял съм дали да не вградя единствено крайния резултат след урока, но не винаги има полза. За някои уроци е по-добре да има отделна Демо страница. Поставянето на iframe показващ прогреса след всяка стъпка, според мен, ще натовари страницата и ще увеличи времето за зареждане. Все пак ще се опитам да експериментирам с идеята в бъдещите уроци. Благодаря, че я предложи. :)

  8. 8

    Руми
    28 март 2016 21:37

    Благодаря ти за урока. Ще го пробвам сега с по-новата версия, сигурно няма да има значими различия.