Toto je 2. díl seriálu jQuery: Praktická webová aplikace, pokud se dostatečně neorientujete, zkuste první díl.
Toto je 2. díl seriálu jQuery: Praktická webová aplikace, pokud se dostatečně neorientujete, zkuste první díl.
V minulém díle jsme si vytvořili základní strukturu naší webové aplikace. Nyní zkusíme zajistit, aby naše aplikace byla schopna přepínat mezi jednotlivými stránkami.
Nejdříve budeme potřebovat menu, díky kterému budeme moci přepínat. Pojďme si ho přidat do <body>
:
<nav class="navbar navbar-fixed-top navbar-dark" style="background-color: #0083ff;"><a class="navbar-brand" href="#">The Wall</a><ul class="nav navbar-nav float-xs-right"><li class="nav-item active"><a class="nav-link" href="#" onclick="app.goTo('stories')">Stories</a></li><li class="nav-item"><a class="nav-link" href="#" onclick="app.goTo('stories')">Add</a></li></ul></nav>
Máme zde několik CSS tříd, které už pro nás Bootstrap má připravené a my je tudíž můžeme rovnou použít. Pojďme si je vysvětlit:
navbar
- základní stylování menu lišty
navbar-fixed-top
- přilepí menu lištu na horní okraj a zajistí, aby byla stále vidět (i při scrollu)
navbar-dark
- položky menu budou světlým písmem, takže jim můžeme dát pozadí syté barvy
Bootstrap nám standardně nastavil i barvu pozadí menu lišty, ale my jsme si ji změnili na modrou pomocí style parametru.
Dále:
navbar-brand
- nastyluje “název” aplikace
nav
a navbar-nav
- nastylují seznam položek menu
float-xs-right
- zarovná seznam položek menu doprava a to pro všechny velikosti obrazovek
nav-item
- nastyluje položky menu a pokud k ní přidáme i třídu active, tak Bootstrap už pro nás má samozřejmě připraven i speciální vzhled pro aktivní položky menu
Ke každé položce menu jsme si připravili i spuštení funkce app.goTo()
, která ještě neexistuje, ale bude právě zajišťovat přepínání stránek při kliku na danou položku.
<div id="page-stories" class="page">Latest stories</div><div id="page-story" class="page">Story detail</div><div id="page-add" class="page">Add a story</div>
Tak, teď už je alespoň něco v naší aplikaci vidět! My ale chceme vidět jen jednu stránku v jeden čas. Půjdeme tedy do screen.css a všechny stránky schováme. Později pak skriptem budeme ukazovat jen tu stránku, která se má zrovna zobrazovat. Obsahům stránek také dáme malé odsazení. Do screen.css přidáme:
.page {display: none;padding: 24px;margin-top: 54px;}
Každá stránka v naší aplikaci bude reprenzentována jako položka v objektu app
. Když si předem takto připravíme seznam stránek, bude snadnější s nimi pracovat:
window.app = {stories: {},story: {},add: {},init: function(){}}$(document).ready(app.init);
Je čas konečně zprovoznit přepínání stránek definováním funkce app.goTo()
, kterou si rovněž přidáme do app.js:
window.app = {stories: {},story: {},add: {},init: function(){},goTo: function(page){}}
Ve funkci goTo(page)
nejdříve zkontrolujeme, jestli stránka, která se má zobrazit (argument page
), vůbec existuje v našem objektu app
. Pokud ne, zobrazí se místo ní nějaká standardní stránka a tou jsme si řekli, že bude stránka s posledními příspěvky, tedy stories
:
if (!app[page])
page = 'stories';
Následně musíme zařídit, aby se naše aplikace hloupě nepřepínala ze stejné stránky na stejnou stránku. Aktuálně aktivní stránku si později uložíme do nové položky / proměnné v objektu app a bude se jmenovat currentPage. Nyní přidáme jen kontrolu, jestli app.currentPage
(aktuálně zobrazená stránka) není stejná, jako page
(stránka, na kterou chceme přepnout). Pokud se tedy hodnoty těchto dvou proměnných app.currentPage
a page
budou rovnat, ukončíme výkon funkce pomocí return
:
if (page == app.currentPage)
return;
Jestliže skript projde přes tuto kontrolu a bude se tedy jednat o jinou stránku k zobrazení než tu, která je aktuálně zobrazena, zobrazíme ji pomocí jQuery fade efektu:
if (app.currentPage)
{
$('#page-'+app.currentPage).fadeOut(250, function()
{
$('#page-'+page).fadeIn(250);
});
}
else
$('#page-'+page).fadeIn(250);
Tato část je trochu složitější, pojďme si ji vysvětlit:
Při zobrazení první (standardní) stránky (tedy stories
) ještě není proměnná app.currentPage
definována, má tedy hodnotu undefined
. Pomocí podmínky if (app.currentPage)
zjistíme, jestli už přepínáme z nějaké zobrazené stránky na jinou stránku v naší webové aplikaci a nebo (else
) jestli se naše aplikace právě načetla a teprve zobrazuje první stránku (stories
).
V případě, že se naše aplikace teprve načetla a teprve zobrazujeme první stránku (část za else
) použijeme jQuery efekt fade pomocí funkce fadeIn()
což neudělá nic jiného, než že nám zviditelní element <div>
s ID #page-stories spolu s jeho veškerým obsahem, který do něj později nahrajeme jinou funkcí. Zobrazí se tak stránka stories
s posledními příspěvky uživatelů.
Pokud se jedná o přepnutí z jedné stránky naší webové aplikace na jinou, nejdříve pomocí jQuery funkce fadeOut()
schováme aktuálně zobrazenou stránku, kterou už v této době máme uloženou v app.currentPage
. Jakmile efekt schování doběhne a aktivuje se callback funkce, hned se začne zobrazovat nová stránka pomocí funkce fadeIn()
. Celý efekt přepnutí mezi stránkami trvá tak 500 milisekund, tedy půl sekundy.
A nyní si pro příští přepnutí mezi stránkami uložíme tuto novou stránku (page
), na kterou jsme právě přepnuli, jako aktuální stránku (app.currentPage
):
app.currentPage = page;
Na konec do funkce app.init()
budeme chtít přidat kód:
app.goTo('stories');
Aby se při prvním spuštění aplikace zobrazila právě stránka stories
.
Na konci funkce goTo()
se nám bude ještě hodit malé udělátko. Řekněme, že při spuštění stránky stories
budeme chtít načíst poslední příspěvky ze serveru nějakou funkcí, kterou budeme mít uvnitř app.stories
, mohla by se jmenovat třeba start()
, položka stories by tedy vypadala takto:
window.app = {stories: {start: function(){}},// ...}
Je velmi pravděpodobné, že taková funkce při zobrazení stránky se nám bude hodit u více stránek než jen u stories. Pojdme tedy univerzálně už ve funkci goTo() zjišťovat, jestli stránka, na kterou právě přepínáme takovou funkci má a pokud ano, tak ji provedeme:
if (app[page].start)
app[page].start();
Když nyní spustíme naši aplikaci a kdykoli přepneme na stránku stories, měl by se nám v konzoli vypsat text "Stories".
S přepnutím na jinou stránku by se měla změnit i aktivní položka menu na korespondující stránku. Konkrétně mluvíme o vyjmutí CSS třídy active
z aktivní položky menu korespondující se stránkou, ze které právě přepínáme a přidání CSS třídy active
do položky menu korespondující se stránkou, na kterou právě přepínáme.
Zní to složitě, ale nebudeme se s tím trápit. Řádek:
$('nav li.active').removeClass('active');
nejdříve odstraní CSS třídu active
obecně ze všech položek menu, které ji náhodou mají a řádek:
$('nav a[onclick="app.goTo(\'' + page + '\')"]').parent().addClass('active');
Přidá CSS třídu active
do odkazu na stránku, kterou právě zobrazujeme.
Oba tyto řádky přidáme na konec funkce app.goTo()
.
Tímto máme přepínání mezi stránkami hotové. Příště se podíváme na přidávání příspěvků.
Na závěr rekapitulace celé naší webové aplikace:
.page {display: none;padding: 24px;margin-top: 54px;}
window.app = {stories: {start: function(){console.log('Stories');}},story: {},add: {},init: function(){app.goTo('stories');},goTo: function(page){if (!app[page])page = 'stories';if (page == app.currentPage)return;if (app.currentPage){$('#page-'+app.currentPage).fadeOut(250, function(){$('#page-'+page).fadeIn(250);});}else$('#page-'+page).fadeIn(250);app.currentPage = page;if (app[page].start)app[page].start();$('nav li.active').removeClass('active');$('nav a[onclick="app.goTo(\'' + page + '\')"]').parent().addClass('active');}}$(document).ready(app.init);
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>The Wall</title><link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"><link rel="stylesheet" href="screen.css"></head><body><nav class="navbar navbar-fixed-top navbar-dark" style="background-color: #0083ff;"><a class="navbar-brand" href="#">The Wall</a><ul class="nav navbar-nav float-xs-right"><li class="nav-item active"><a class="nav-link" href="#" onclick="app.goTo('stories')">Stories</a></li><li class="nav-item"><a class="nav-link" href="#" onclick="app.goTo('add')">Add</a></li></ul></nav><div id="page-stories" class="page">Latest stories</div><div id="page-story" class="page">Story detail</div><div id="page-add" class="page">Add a story</div><script type="text/javascript" src="bower_components/jquery/dist/jquery.min.js"></script><script type="text/javascript" src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script><script type="text/javascript" src="js/app.js"></script></body></html>