You are on page 1of 63

Web Apps Versus NaIive Apps

Mobile Web App?


A moblle web app ls a webslLe speclflcally opLlmlzed for Lhe
phone lL can be anyLhlng from a LlmeLracker Lo an expense
reporL screen A web app ls bullL wlLh websLandard Lechnologles
lL ls avallable aL a u8L (publlc prlvaLe or behlnd a logln) and lL ls
opLlmlzed for Lhe moblle devlces A web app ls noL lnsLalled on
Lhe phone ls noL avallable ln Lhe Apple SLore or Androld SLore
Mobile NaIive App?
naLlve apps are lnsLalled on Lhe phone have access Lo devlce
hardware (speakers acceleromeLer camera eLc) and are wrlLLen
wlLh Cb[ecLlveC or !ava 1hey are also avallable aL Lhe Apple or
Androld SLore
Pros and Cons
ros
%Access Lo paylng cusLomers
%Iery sophlsLlcaLed developmenL envlronmenL llke xcode
lnLerface 8ullder and Cocoa 1ouch framework on Apple slde
Cn Lhe Androld slde Lcllpse Androld Suk
%Access Lo all Lhe cool hardware feaLures of Lhe devlce

ons
%$year developer fee Lo Apple
%uependenL Lhe Apple approval process (boLh for app and bugs)
%need Cb[ecLlveC $!ava Lo develop r
%need a Mac for lhone naLlve developmenL

ros of web app deve|opment
%uevelopers can reuse Lhelr currenL auLhorlng Lools and skllls
%noL llmlLed Lo developlng on Lhe Mac CS
%App wlll run on any devlce LhaL has a web browser
%Can flx bugs ln real Llme

ons of web app deve|opment
%LlmlLed access Lo all cool hardware feaLures of Lhe phone
%ow Lo charge for your app?
%ulfflculL Lo achleve sophlsLlcaLed anlmaLlon and 3u effecLs

Web Programming
1he 3 Lechnologles needed are 1ML CSS and !avaScrlpL
lnIro Io HTML
We wlll pace Lhrough Lhls qulckly
amp|e 1 n1ML sn|ppet
<h>ue11o there!<,h>
<p>We1come to Mob1e Web 0eve1opment.<,p>
<p>let us 1earn somethng about Mob1e deve1opment.<,p>

?ou can also puL 1ML Lags lnslde of oLher 1ML Lags (nesLlng)
Lxample 2 shows an unordered llsL (u1) Lag LhaL conLalns Lhree
llsL lLems (1) ln a browser Lhls would show up as a bulleLed llsL
wlLh each lLem on lLs own llne When you have a Lag or Lags lnslde
anoLher Lag Lhe lnner Lags are called n||d e|ements or chlldren
of Lhe parent tag ere Lhe 1s are chlldren of u1 parenL
amp|e 2 Unordered ||st
<u1>
<1>u1Ml<,1>
<1>JavaScrpt<,1>
<1>CSS2<,1>
<,u1>

An 1ML documenL ls made up of Lwo secLlons Lhe ead and Lhe
body 1he body ls where you puL all Lhe conLenL LhaL you wanL
users Lo see 1he head conLalns lnformaLlon abouL Lhe page mosL
of whlch ls lnvlslble Lo Lhe user 1he body and head are always
wrapped ln an htm1 elemenL amp|e 3 shows Lhe snlppeL ln Lhe
conLexL of a proper 1ML documenL lor now Lhe head secLlon
conLalns a title elemenL whlch Lells Lhe browser whaL LexL Lo
dlsplay ln Lhe LlLle bar of Lhe wlndow
amp|e 3 A proper n1ML donment
<htm1>
<head>
<tt1e>Mob1e Web 0eve1opment<,tt1e>
<,head>
<body>
<h>We1come!<,h>
<p>8e-usng your web sk11s 1or mob1e<,p>
<p>Standard web techno1oges<,p>
<u1>
<1>u1MlS<,1>
<1>CSS2<,1>
<1>JavaScrpt<,1>
<,u1>
<,body>
<,htm1>
uslng a browser you can access pages hosLed on Lhe web or on
your local machlne ?ou can use a LexL edlLor for modlfylng Lhls
lnIro Io CSS
8rowsers render 1ML elemenLs wlLh dlsLlncL sLyles (headlngs are
large and bold paragraphs are followed by a blank llne eLc)
1hese sLyles are very baslc and are prlmarlly lnLended Lo help Lhe
reader undersLand Lhe sLrucLure and meanlng of Lhe documenL
1o go beyond Lhls slmple sLrucLurebased renderlng you can use
Cascadlng SLyle SheeLs (CSS) CSS ls a language used Lo deflne Lhe
vlsual aspecLs of a 1ML documenL ?ou can use CSS Lo deflne
Lhlngs llke tet no|or s|ze and sty|e (bo|d |ta||n% or nomp|e
t|ngs ||ke page |ayot grad|ents opan|ty and much more
amp|e 4 show a slmple CSS rule LhaL lnsLrucLs Lhe browser Lo
dlsplay any LexL ln Lhe body elemenL uslng Lhe color red ln Lhls
example body ls Lhe se/ector (whaL ls affecLed by Lhe rule) and
Lhe curly braces enclose Lhe dec/orotion (Lhe rule lLself) 1he
declaraLlon lncludes a seL of properties and Lhelr vo/ues ln Lhls
example co1or ls Lhe properLy and red ls Lhe value
amp|e 4 A s|mp|e r|e
body { co1or: red, )
roperLy names are predeflned ln Lhe CSS speclflcaLlon whlch
means LhaL you can'L [usL make Lhem up Lach properLy expecLs
an approprlaLe value and Lhere can be loLs of approprlaLe values
and value formaLs for a glven properLy lor example you can
speclfy colors wlLh predeflned keywords llke red or by uslng
1ML color code noLaLlon 1hls uses a hexadeclmal noLaLlon eg
#aabbcc (3 palrs of hexadeclmal dlglLs (l) represenLlng (from
lefL Lo rlghL) 8ed Creen and 8lue values) roperLles LhaL expecL
measuremenLs can accepL values llke px 7Sx and em
Lxample 3 Some common CSS declaraLlons" shows some
common declaraLlons (1he color code shown for background-
co1or corresponds Lo Lhe CSS gray")
amp|e S ome nommon den|arat|ons
body {
co1or: red,
background-co1or: 888,
1ont-sze: px,
1ont-sty1e: ta1c,
1ont-weght: bo1d,
1ont-1am1y: ^ra1,
)

SelecLors come ln a varleLy of flavors lf you wanLed all of your
hyperllnks (Lhe a elemenL) Lo dlsplay ln lLallcs you would add Lhe
followlng Lo your sLylesheeL
a { 1ont-sty1e: ta1c, )

lf you wanLed Lo be more speclflc and only lLallclze Lhe hyperllnks
wlLhln an h Lag you would add Lhe followlng Lo your sLylesheeL
h a { 1ont-sty1e: ta1c, )
?ou can also deflne your own cusLom selecLors by addlng d
and$or c1ass aLLrlbuLes Lo your 1ML Lags Conslder Lhe
followlng 1ML snlppeL
<h c1ass="1oud">We1come!<,h>

<p d="hgh1ght">usng d and c1ass attrbutes.<,p>
<p>1hs s rea11y 1un stu11.<,p>
<u1>
<1 c1ass="1oud">u1Ml<,1>
<1>CSS2<,1>
<1>Javascrpt<,1>
<,u1>

lf l added .1oud { 1ont-sty1e: ta1c, ) Lo Lhe CSS for
Lhls 1ML u there! and zza would show up lLallclzed
because Lhey boLh have Lhe 1oud class 1he doL ln fronL of Lhe
.1oud selecLor ls lmporLanL lL's how Lhe CSS knows Lo look for
1ML Lags wlLh a class of 1oud lf you omlL Lhe doL Lhe CSS would
look for a 1oud Lag whlch doesn'L exlsL ln Lhls snlppeL (or ln
1ML aL all) Applylng CSS by d ls slmllar 1o add a yellow
background flll Lo Lhe hgh1ght paragraph Lag you'd use
hgh1ght { background-co1or: ye11ow, )

symbol Lells CSS Lo look for an 1ML Lag wlLh ld highlight
?ou can opL Lo selecL elemenLs by Lag name (eg body h p) by
class name (eg .1oud .subt1e .error) or by d (eg
hgh1ght 1ogn promo) And you can geL more speclflc
by chalnlng selecLors LogeLher (eg h a body u1 .1oud)
-ote
1here are dlfferences beLween c1ass and d c1ass aLLrlbuLes
should be used when you have more Lhan one lLem on Lhe page
wlLh Lhe same c1ass value Conversely d values have Lo be
unlque Lo a page lease noLe selecLlng elemenLs by d ls much
fasLer Lhan selecLlng Lhem by c1ass so you can hurL
performance by overuslng c1ass selecLors
1o apply a sLyle sheeL one can llnk Lo Lhe sLylesheeL ln Lhe head of
Lhe 1ML documenL as seen ln Lxample 6 Llnklng Lo a CSS
sLylesheeL" 1he hre1 aLLrlbuLe ln Lhls example ls a relaLlve paLh
meanlng LhaL lL polnLs Lo a LexL flle named screen.css ln Lhe
same dlrecLory as Lhe 1ML page ?ou can also speclfy absoluLe
llnks such as http:,,examp1e.com,screen.css
amp|e 6 L|nk|ng to a sty|eseet
<htm1>
<head>
<tt1e>Mob1e Web 0eve1opment<,tt1e>
<1nk re1="sty1esheet" hre1="screen.css" type="text,css",>
<,head>
<body>
<h>We1come!<,h>
<p>8e-usng your web sk11s 1or mob1e<,p>
<p>Standard web techno1oges<,p>
<u1>
<1>u1MlS<,1>
<1>CSS2<,1>
<1>JavaScrpt<,1>
<,u1>
<,body>
<,htm1>


Lxample 7 A slmple sLylesheeL"
amp|e 7 A s|mp|e sty|eseet
body {
1ont-sze: px,
1ont-weght: bo1d,
1ont-1am1y: ^ra1,
)
a { 1ont-sty1e: ta1c, )
h a { 1ont-sty1e: ta1c, )
.1oud { 1ont-sty1e: ta1c, )
hgh1ght { background-co1or: ye11ow, )


lor a qulck and Lhorough crash course ln CSS Lry c55 locket
kefeteoce by Lrlc Meyer (C'8ellly)
lnIro Io |avaScripI
Slnce we know how Lo sLrucLure a documenL wlLh 1ML and how
Lo modlfy lLs vlsual presenLaLlon wlLh CSS now we'll add some
!avaScrlpL !avaScrlpL ls a scrlpLlng language LhaL can be added Lo
an 1ML page Lo make lL more lnLeracLlve and convenlenL for Lhe
user lor example you can wrlLe some !avaScrlpL LhaL wlll lnspecL
Lhe values Lyped ln a form Lo make sure Lhey are valld Cr you can
have !avaScrlpL show or hlde elemenLs of a page dependlng on
where Lhe user cllcks !avaScrlpL can even conLacL Lhe web server
Lo execuLe daLabase modlflcaLlons wlLhouL refreshlng Lhe currenL
web page (A!Ax!) Llke any modern scrlpLlng language !avaScrlpL
has varlables arrays ob[ecLs and all Lhe Lyplcal conLrol sLrucLures
(1 wh1e 1or and so on) Lxample 8 8aslc !avaScrlpL synLax"
shows a snlppeL of !avaScrlpL lllusLraLlng several core concepLs
amp|e 8 8as|n Iavanr|pt synta
var techs = j'u1Ml', 'CSS2', 'Javascrpt',
1or {var n techs) {
1 {techsj == 'CSS2') {
a1ert{techsj + ' are knd o1 trcky!'),
) e1se {
a1ert{techsj + ' are okay.'),
)
)

ere's an explanaLlon of whaL's happenlng here
ueflne an array named 1oods LhaL conLalns Lhree elemenLs
2 Cpen a 1or loop wlLh varlable LhaL wlll conLaln Lhe
lndex of each elemenL of Lhe array durlng Lhe loop
3 1 check Lo see lf Lhe currenL elemenL of Lhe array ls equal Lo ^pp1es
4 1hls ls dlsplayed lf Lhe currenL elemenL of Lhe array ls equal Lo CSS2
3 1hls ls dlsplayed lf Lhe currenL elemenL of Lhe array ls oot equal Lo CSS2
Some polnLs abouL !avaScrlpL's synLax worLh noLlng
%SLaLemenLs are LermlnaLed wlLh semlcolons
%Code blocks are enclosed ln curly braces
%Iarlables are declared uslng Lhe var keyword
%Array elemenLs can be accessed wlLh square brackeL noLaLlon
%Array keys are asslgned beglnnlng aL
%1he slgn ls asslgnmenL and slgn ls Lhe equlvalence operaLor
%1he + slgn ls Lhe sLrlng concaLenaLlon operaLor
!avaScrlpL can lnLeracL wlLh Lhe elemenLs of an 1ML page
(manlpulaLlng Lhe uCM") Lxample 9 Slmple CnCllck
handler" shows a !avaScrlpL LhaL changes some LexL on Lhe
page when user cllcks on Lhe h
amp|e 9 |mp|e Cn||nk and|er
<htm1>
<head>
<tt1e>My Mob1e 0eve1opment age<,tt1e>
<scrpt type="text,avascrpt" charset="ut1-8">
1uncton sayue11o{) {
document.getL1ement8y1d{'1oo').nneru1Ml = '0uch! 1t hurts!!!',
)
<,scrpt>
<,head>
<body>
<h d="1oo" onc1ck="sayue11o{)">ress me!<,h>
<,body>
<,htm1>
ere's an explanaLlon
Added a scrlpL block Lo Lhe head of Lhe 1ML documenL
2 lnslde Lhe scrlpL block deflned a slngle !avaScrlpL funcLlon named sayue11o
3 1he sayue11o{) funcLlon conLalns a slngle sLaLemenL whlch Lells Lhe
browser Lo look Lhrough Lhe documenL for an elemenL LhaL has Lhe ld
'foo' and seL lLs lnner1ML conLenLs Lo 'ress Me!'" 1he effecL of Lhls ln
Lhe browser ls LhaL Lhe LexL ress me!" wlll be replaced wlLh Cuch lL hurLs!"
when Lhe user cllcks on Lhe h elemenL
4 Lnd of Lhe sayue11o{) funcLlon
3 Lnd of Lhe scrlpL block
6 1he onc1ck aLLrlbuLe of Lhe h elemenL Lells Lhe browser Lo do
someLhlng when Lhe user cllcks on Lhe h namely Lo run Lhe sayue11o{) f
A !avaScrlpL llbrary Lo conslder ls [Cuery [Cuery ls a relaLlvely
small LhaL allows you Lo wrlLe your !avaScrlpL code ln a way LhaL
wlll work Lhe same ln a wlde varleLy of browsers WhaL's more lL
greaLly slmpllfles a number of common web developmenL Lasks
Lxample [Cuery CnCllck handler" ls a [Cuery rewrlLe of
prevlous example noLlce LhaL you have Lo lnclude Lhe llbrary
Cur porLlon of Lhe code ls slgnlflcanLly reduced
amp|e 10 [ery Cn||nk and|er
<htm1>
<head>
<tt1e>My Mob1e 0eve1opment age<,tt1e>
<scrpt type="text,avascrpt" src="query.s"><,scrpt>
<scrpt type="text,avascrpt" charset="ut1-8">
1uncton sayue11o{) {
${'1oo').text{0uch t uurts!'),
)
<,scrpt>
<,head>
<body>
<h d="1oo" onc1ck="sayue11o{)">ress me!<,h>
<,body>
<,htm1>
[Cuery downloads documenLaLlon and LuLorlals are avallable aL
hLLp$$[querycom 1o use [Cuery you wlll need Lo download lL
from Lhe webslLe rename Lhe flle you downloaded (such as
query-.2..mn.s) Lo query.s and puL a copy of lL ln
Lhe same dlrecLory as your 1ML documenL
Mobilizing your websiIe
lmaglne LhaL you have a webslLe LhaL you wanL Lo lhonelze ln
Lhls scenarlo Lhere are a number of easy Lhlngs you can do Lo
opLlmlze a slLe for Lhe lhone (or for Androld)
amp|e 11 n1ML donment we w||| be sty||ng
<htm1>
<head>
<1nk re1="sty1esheet" hre1="phone.css" type="text,css" ,>
<tt1e>Somnath 8aneree<,tt1e>
<,head>
<body>
<dv d="contaner">
<dv d="header">
<h><a hre1=".,">Somnath 8aneree<,a><,h>
<dv d="ut1ty">
<u1>
<1><a hre1="about.htm1">^bout<,a><,1>
<1><a hre1="b1og.htm1">81og<,a><,1>
<,u1>
<,dv>
<dv d="nav">
<u1>
<1><a hre1="customers.htm1">Customers<,a><,1>
<1><a hre1="contact.htm1">Contact<,a><,1>
<1><a hre1="deve1opment.htm1">0eve1opment<,a><,1>
<,u1>
<,dv>
<,dv>
<dv d="content">
<h>^bout<,h>
<p>Somnath 8aneree s a web deve1oper, speaker, and author. us c1ents
nc1ude ^dobe, 61axoSmthk1ne, Iorbes and Lastman Chemca1 Company....<,p>
<,dv>
<dv d="sdebar">
<mg a1t="ortrat o1 Somnath 8aneree"
src="mages,somnath.png"
<p>Somnath 8aneree s a mob1e and web app1caton deve1oper who be1eves
n bu1dng so1utons that make a d11erence.<,p>
<,dv>
<dv d="1ooter">
<u1>
<1><a hre1="servces.htm1">Servces<,a><,1>
<1><a hre1="about.htm1">^bout<,a><,1>
<1><a hre1="b1og.htm1">81og<,a><,1>
<,u1>
<p c1ass="subt1e">Somnath 8aneree<,p>
<,dv>
<,dv>
<,body>
<,htm1>

amp|e 12 |one ty|e eet
<1nk re1="sty1esheet" type="text,css"
hre1="phone.css" meda="on1y screen and {max-wdth: 48px)" ,>
<1nk re1="sty1esheet" type="text,css"
hre1="desktop.css" meda="screen and {mn-wdth: 48px)" ,>
i1 15)>
link rel="stylesheet" type="text/css" hre1="explorer.css" media="all"
/>
endi1)>
ere's an explanaLlon
usually Safarl on Lhe lhone wlll assume LhaL your page ls 98px
wlde ln Lhe ma[orlLy of cases Lhls works greaL owever you are
golng Lo formaL our conLenL speclflcally for Lhe smaller
dlmenslons of Lhe lhone so you musL leL Moblle Safarl know
abouL lL by addlng a vlewporL meLa Lag Lo Lhe head secLlon
amp|e 13 V|ewort
<meta name="vewport" content="user-sca1ab1e=no, wdth=devce-
wdth" ,>

lf you don'L seL Lhe vlewporL wldLh Lhe page wlll be zoomed way
ouL when lL flrsL loads

|g 1 nreenot W|tot V|ewort



|g 2 nreenot W|t V|ewort set to dev|new|dt
iPhone CSS
1here are a number of user lnLerface (ul) convenLlons LhaL make
an lhone app look llke an lhone app We need Lhe d|st|nnt|ve
t|t|e bar ||sts w|t ronded norners f|ngerfr|end|y ||nks tat
|ook ||ke g|ossy bttons and so on uslng a LexL edlLor creaLe a
flle named phone.css add Lhe followlng code
amp|e 14 |one ty|e eet
body {
background-co1or: ddd, ,* 8ackground co1or *,
co1or: , ,* Ioreground text co1or*,
1ont-1am1y: ue1vetca,
1ont-sze: 4px,
margn: , ,* ^mount o1 negatve space
around the outsde o1 the body *,
paddng: , ,* ^mount o1 negatve space
around the nsde o1 the body *,
)
PIeuse note thut the overuII ]ont s set to HeIvetcu whch s the ]ont
used b) most Phone uppIcutons.
now l'll aLLack Lhe header dv LhaL conLalns Lhe maln home llnk
(le Lhe logo llnk) and Lhe prlmary and secondary slLe navlgaLlon
1he flrsL sLep ls Lo formaL Lhe logo llnk as a cllckable LlLle bar Add
Lhe followlng Lo Lhe phone.css flle

amp|e 1S |one ty|e eet
header h {
margn: ,
paddng: ,
)
header h a {
background-co1or: ccc,
border-bottom: px so1d 666,
co1or: ,
dsp1ay: b1ock,
1ont-sze: px,
1ont-weght: bo1d,
paddng: px ,
text-a1gn: center,
text-decoraton: none,
)

|g 3 ome ty||ng app||ed

l'm golng Lo formaL Lhe prlmary and secondary navlgaLlon ul
blocks ldenLlcally so l can [usL use Lhe generlc Lag selecLors (le
#header ul) as opposed Lo Lhe Lag lds (le #header ul#uLlllLy
#header ul#nav) WlLh Lhls llLLle blL of CSS we have already made
a blg lmprovemenL on Lhe lhone page deslgn nexL add some
paddlng Lo Lhe conLenL and sldebar dvs Lo lndenL Lhe LexL from
Lhe edge of Lhe screen a blL

amp|e 12 |one ty|e eet
<1nk re1="sty1esheet" type="text,css"
hre1="phone.css" meda="on1y screen and {max-wdth: 48px)" ,>

header u1 {
1st-sty1e: none,
margn: px,
paddng: ,
)

header u1 1 a {

background-co1or: IIIIII,
border: px so1d ,
co1or: ,
dsp1ay: b1ock,
1ont-sze: 7px,
1ont-weght: bo1d,
margn-bottom: -px,
paddng: px px,
text-decoraton: none,
)
content, sdebar {
paddng: px,
)

1he conLenL ln Lhe fooLer of Lhls page ls baslcally a repeaL of Lhe
navlgaLlon elemenL aL Lhe Lop of Lhe page (Lhe u1 elemenL wlLh
Lhe ld nav) so we can remove Lhe fooLer from Lhe lhone verslon
of Lhe page by seLLlng Lhe dlsplay Lo none

1ooter {
dsp1ay: none,
)



|g 4 L|tt|e b|t of sty||ng
now lL's Llme Lo geL a llLLle fancler SLarLlng from Lhe Lop of Lhe
page add a plxel whlLe drop shadow Lo Lhe logo llnk LexL and a
CSS gradlenL Lo Lhe background
header h a {
text-shadow: px px px 111,
background-mage: -webkt-gradent{1near, 1e1t top,
1e1t bottom, 1rom{ccc), to{)),
)

ln Lhe text-shadow declaraLlon Lhe parameLers from lefL Lo
rlghL are or|zonta| offset vert|na| offset b|r and no|or MosL of
Lhe Llme you'll be applylng Lhe exacL values shown here Lo your
LexL because LhaL's whaL usually looks good on Lhe lhone buL lL
ls fun Lo experlmenL wlLh text-shadow because lL can add a
subLle buL sophlsLlcaLed Louch Lo your deslgn
1he -webkt-gradent llne deserves speclal aLLenLlon lL's an
lnsLrucLlon Lo Lhe browser Lo generaLe a gradlenL lmage on Lhe fly
1herefore a CSS gradlenL can be used anywhere you would
normally speclfy a ur1{) (eg background lmage llsL sLyle
lmage) 1he parameLers from lefL Lo rlghL are as follows Lhe
gradlenL Lype (can be ||near or rad|a|) Lhe sLarLlng polnL of Lhe
gradlenL (can be |eft top |eft bottom r|gt top or r|gt bottom)
Lhe end polnL Lhe sLarLlng color and Lhe endlng color
1he nexL sLep ls Lo add Lhe LradlLlonal rounded corners Lo Lhe
navlgaLlon menus
header u1 1:1rst-ch1d a {
-webkt-border-top-1e1t-radus: 8px,
-webkt-border-top-rght-radus: 8px,
)
header u1 1:1ast-ch1d a {
-webkt-border-bottom-1e1t-radus: 8px,
-webkt-border-bottom-rght-radus: 8px,
)

As you can see l'm uslng cornerspeclflc verslons of Lhe -
webkt-border-radus properLy Lo apply an 8plxel radlus Lo
boLh Lhe Lop Lwo corners of Lhe flrsL llsL lLem and Lhe boLLom Lwo
corners of Lhe lasL llsL lLem (llgure 3 CradlenLs LexL shadows
and rounded corners sLarL Lo Lransform your web page lnLo a
naLlvelooklng lhone app")

|g S konded orners and adow

Basic Behavior wiIh jQuery
When 8ulldlng web apps for Lhe lhone one can be reasonably
sure LhaL !avaScrlpL ls enabled l wanL Lo allow users Lo show and
hlde Lhe blg honklng navlgaLlon secLlon ln Lhe header so LhaL Lhey
only see lL when Lhey wanL Lo ln order Lo make Lhls work l'm
golng Lo wrlLe some new CSS and use some !avaScrlpL Lo apply
Lhe new CSS Lo Lhe exlsLlng 1ML llrsL leL's Lake a look aL Lhe
new CSS SLep one ls Lo hlde Lhe u1 elemenLs ln Lhe header so
Lhey don'L show up when Lhe user flrsL loads Lhe page lf you are
followlng along aL home open your phone.css flle and add Lhe
followlng We have also added Lhe CSS sLyles for buLLon
lor Lhe graphlcs you can download [C1ouch from
hLLp$$[qLouchcom$ and copy Lhe graphlcs from Lhe
themes,qt,mg dlrecLory uL Lhese coples lnLo an mages
subdlrecLory beneaLh Lhe 1ML dlrecLory
header u1.hde {
dsp1ay: none,
)

header dv.1e1t8utton {
poston: abso1ute,
top: 7px,
1e1t: 6px,
heght: 2px,
1ont-weght: bo1d,
text-a1gn: center,
co1or: whte,
text-shadow: rgba{,,,.6) px -px px,
1ne-heght: 8px,
border-wdth: 8px 8px,
-webkt-border-mage: ur1{mages,button.png) 8 8,
)

1.1aklng lL from Lhe Lop l seL Lhe poslLlon Lo absoluLe Lo
remove Lhe dv from Lhe documenL flow whlch allows me
Lo seL lLs Lop and lefL plxel coordlnaLes
. ere l seL Lhe helghL Lo 3px so lL's blg enough Lo Lap easlly
3.nexL l sLyle Lhe LexL bold whlLe wlLh a sllghL drop shadow
and cenLered ln Lhe box
4.ln CSS Lhe rgba{) funcLlon allows you Lo speclfy a fourLh
parameLer LhaL deflnes Lhe alpha value (le opaclLy) of Lhe
color 1he range of allowable values ls Lo where ls
fully LransparenL and ls fully opaque declmal values
beLween and wlll be rendered LranslucenL
5. 1he 1ne-heght declaraLlon moves Lhe LexL down
verLlcally ln Lhe box so lL's noL flush up agalnsL Lhe Lop
border
6.1he border-wdth and -webkt-border-mage llnes
are Lwo properLles LogeLher allow you Lo asslgn porLlons of
a slngle lmage Lo Lhe border area of an elemenL 1hls means
no more nonsemanLlc nesLed dvs or sllclng lmages lnLo
tople1tCorner.png top8ghtCorner.png eLc lf Lhe
box reslzes because Lhe LexL lncreases or decreases Lhe
border lmage wlll sLreLch Lo accommodaLe lL lL's really a
greaL Lhlng havlng fewer lmages means less work less
bandwldLh and shorLer load Llmes WlLh Lhe border-
wdth llne l'm Lelllng Lhe browser Lo apply a border Lo
Lhe Lop an 8px border Lo Lhe rlghL a wldLh border Lo Lhe
boLLom and an 8pxwldLh border Lo Lhe lefL (le Lhe four
parameLers sLarL aL Lhe Lop of Lhe box and work Lhelr way
around clockwlse) noLe LhaL l don'L need Lo speclfy a color
or sLyle for Lhe border
7. WlLh Lhe border wldLhs ln place l can apply Lhe border
lmage 1he flve parameLers from lefL Lo rlghL are Lhe ur1 of
Lhe lmage Lhe Lop wldLh Lhe rlghL wldLh Lhe boLLom
wldLh and Lhe lefL wldLh (agaln clockwlse from Lop) 1he
url can be absoluLe or relaLlve 8elaLlve paLhs are based on
Lhe locaLlon of Lhe sLylesheeL noL Lhe 1ML page LhaL
lncludes Lhe sLylesheeL

Add Lhese llnes Lo Lhe head secLlon of your 1ML documenL
<scrpt type="text,avascrpt" src="query.s"><,scrpt>
<scrpt type="text,avascrpt" src="phone.s"><,scrpt>



Add Lhese llnes Lo your lhone[s

1 {wndow.nnerWdth && wndow.nnerWdth <= 48) {
${document).ready{1uncton{){
${'header u1').addC1ass{'hde'),
${'header').append{'<dv c1ass="1e1t8utton"
onc1ck="togg1eMenu{)">Menu<,dv>'),
)),
1uncton togg1eMenu{) {
${'header u1').togg1eC1ass{'hde'),
${'header .1e1t8utton').togg1eC1ass{'pressed'),
)
)

1.1he enLlre page ls wrapped ln an 1 sLaLemenL LhaL checks
Lo make sure Lhe nnerWdth properLy of Lhe wndow
ob[ecL exlsLs (lL doesn'L exlsL ln some verslons of lnLerneL
Lxplorer) and LhaL Lhe wldLh ls less Lhan or equal Lo 48
(Lhe max wldLh for Lhe lhone) 8y addlng Lhls llne we
ensure LhaL Lhe code only execuLes when Lhe user ls
browslng Lhe page wlLh an lhone or some oLher slmllarly
slzed devlce
. ere we have Lhe socalled documenL ready" funcLlon
documenL ready funcLlon baslcally says When Lhe
documenL ls ready run Lhls code"
3. 1hls ls Lyplcal [Cuery code LhaL beglns by selecLlng Lhe u1s
ln Lhe header and addlng Lhe hlde" CSS class Lo Lhem
8emember hde ls Lhe selecLor we used ln Lhe prevlous
CSS 1he neL effecL of execuLlng Lhls llne ls Lo hlde" Lhe
header u1 elemenLs 1ake speclal noLe had we noL
wrapped Lhls llne ln Lhe documenL ready funcLlon lL
would have mosL llkely execuLed before Lhe u1s were
even flnlshed loadlng 1hls means LhaL Lhe !avaScrlpL
would load Lhls llne would fall because Lhe u1s wouldn'L
exlsL yeL
4.ere ls where l append a buLLon Lo Lhe header LhaL wlll
allow Lhe user Lo show and hlde Lhe menu (llgure 6 1he
Menu buLLon has been added Lo Lhe Loolbar dynamlcally
uslng [Cuery") lL has a class LhaL corresponds Lo Lhe CSS
we wroLe prevlously for .1e1t8utton and lL has an
onc1ck handler LhaL calls Lhe funcLlon togg1eMenu{)
whlch comes nexL
5.togg1eMenu{) funcLlon uses [Cuery's togg1eC1ass{)
funcLlon Lo add$remove Lhe speclfled class Lo Lhe selecLed
ob[ecL We Loggle Lhe hde class on Lhe header u1s
6. We Loggle Lhe pressed class on Lhe header 1e1t8utton


|g 6 Add|ng a Men btton
Co back Lo phone.css and lnserL Lhe followlng
header dv.pressed {
-webkt-border-mage: ur1{mages,button_c1cked.png)
8 8,
)

As you can see l'm slmply speclfylng a dlfferenL lmage for Lhe
buLLon border (lL happens Lo be sllghLly darker) 1hls wlll add a
LwosLaLe effecL Lo Lhe buLLon LhaL should make lL evldenL Lo
Lhe user LhaL Lhe buLLon can boLh show and hlde Lhe menu
(llgure 7 Menu buLLon dlsplays darker when pressed")

|g 7 D|fferent |mage wen men btton n||nked


Advanced iPhone SIyling
We have learnL how Lo use CSS Lo sLyle a collecLlon of 1ML
pages Lo ook llke an lhone app now we wlll make Lhose same
pages bebove llke an lhone app Speclflcally we'll dlscuss
uslng A[ax Lo Lurn a full webslLe lnLo a slnglepage app how Lo
creaLe a back buLLon wlLh hlsLory uslng !avaScrlpL and how Lo
Lake advanLage of Lhe Web Cllp lcon and full screen mode
feaLures of Lhe lhone Lo launch Lhe app
Ajax
A[ax ls a Lechnlque of uslng !avaScrlpL Lo send requesLs Lo a web
server wlLhouL reloadlng Lhe currenL page (eg Lo reLrleve some
1ML submlL a form and so on) 1hls approach makes for a very
smooLh user experlence buL does requlre LhaL you relnvenL a loL
of wheels lor example lf you are loadlng exLernal pages
dynamlcally Lhe browser wlll noL glve any lndlcaLlon of progress
or errors Lo Lhe users lurLhermore Lhe back buLLon wlll noL work
as expecLed unless you Lake palns Lo supporL lL ln oLher words
you have Lo do a loL of work Lo make a sweeL A[ax app Lven so
Lhere are some very good reasons Lo go Lo Lhe Lrouble ln
parLlcular lL opens Lhe door Lo creaLlng lhone apps LhaL can run
fullscreen and even offllne

eIIing SIarIed
We wlll use a slngle page phone.htm1 LhaL wlll slL ln fronL of
oLher pages and wlll handle requesLs Cn flrsL load phone.htm1
wlll presenL Lhe user wlLh a nlcely formaLLed verslon of Lhe slLe
navlgaLlon l'll Lhen use [Cuery Lo hl[ack" Lhe onc1ck acLlons of
Lhe nav llnks so LhaL when Lhe user cllcks on one Lhe browser
page wlll oot navlgaLe Lo Lhe LargeL llnk 8aLher [Cuery wlll load a
porLlon of Lhe 1ML from Lhe remoLe page and updaLe Lhe
currenL page 1ML for phone.htm1 wrapper page ls slmple
(Lxample 3 Slmple 1ML wrapper markup") 1he head secLlon
tt1e and vewport are seL and lnclude llnks Lo a sLylesheeL
(phone.css) and Lwo !S flles query.s and phone.s
1he body [usL has Lwo dv conLalners a header wlLh Lhe lnlLlal
LlLle ln an h Lag and an empLy dv conLalner whlch wlll end up
holdlng 1ML snlppeLs reLrleved from oLher pages
amp|e 13 |mp|e n1ML Wrapper Markp
<htm1>
<head>
<tt1e>Somnath 8aneree<,tt1e>
<meta name="vewport" content="user-sca1ab1e=no, wdth=devce-wdth" ,>
<1nk re1="sty1esheet" hre1="phone.css" type="text,css" meda="screen" ,>
<scrpt type="text,avascrpt" src="query.s"><,scrpt>
<scrpt type="text,avascrpt" src="phone.s"><,scrpt>
<,head>
<body>
<dv d="header"><h>Somnath 8aneree<,h><,dv>
<dv d="contaner"><,dv>
<,body>
<,htm1>

ere ls Lhe new lhonecss
body {
background-co1or: ddd,
co1or: ,
1ont-1am1y: ue1vetca,
1ont-sze: 4px,
margn: ,
paddng: ,
)
header {
background-co1or: ccc,
background-mage: -webkt-gradent{1near, 1e1t top,
1e1t bottom, 1rom{ccc), to{)),
border-co1or: 666,
border-sty1e: so1d,
border-wdth: px ,
)
header h {
co1or: ,
1ont-sze: px,
1ont-weght: bo1d,
margn: auto,
paddng: px ,
text-a1gn: center,
text-shadow: px px px 111,
)
u1 {
1st-sty1e: none,
margn: px,
paddng: ,
)
u1 1 a {
background-co1or: III,
border: px so1d ,
co1or: ,
dsp1ay: b1ock,
1ont-sze: 7px,
1ont-weght: bo1d,
margn-bottom: -px,
paddng: px px,
text-decoraton: none,
)
u1 1:1rst-ch1d a {
-webkt-border-top-1e1t-radus: 8px,
-webkt-border-top-rght-radus: 8px,
)
u1 1:1ast-ch1d a {
-webkt-border-bottom-1e1t-radus: 8px,
-webkt-border-bottom-rght-radus: 8px,
)
u1 1 a:actve,u1 1 a:hover {
background-co1or:b1ue,
co1or:whte,
)
content {
paddng: px,
text-shadow: px px px 111,
)
content a {
co1or: b1ue,
)


1hls lhone[s converLs Lhe llnks Lo A!Ax requesLs
${document).ready{1uncton{){
1oadage{),
)),
1uncton 1oadage{ur1) {
1 {ur1 == unde1ned) {
${'contaner').1oad{'ndex.htm1 header u1',
hacklnks),
) e1se {
${'contaner').1oad{ur1 + ' content',
hacklnks),
)
)
1uncton hacklnks{) {
${'contaner a').c1ck{1uncton{e){
e.prevent0e1au1t{),
1oadage{e.target.hre1),
)),
)

1.[Cuery's documenL ready funcLlon Lo have Lhe browser run
Lhe 1oadage{) funcLlon when Lhe uCM ls compleLe
. 1he 1oadage{) funcLlon accepLs a slngle parameLer
called ur1 and checks wheLher a value has been senL
3. lf a value ls noL senL lnLo Lhe funcLlon ur1 wlll be
undeflned and Lhls llne wlll execuLe 1hls llne and Lhe
followlng are examples of [Cuery's 1oad{) funcLlon 1he
1oad{) funcLlon ls excellenL for addlng qulck and dlrLy A[ax
funcLlonallLy Lo a page lf Lhls llne were LranslaLed lnLo
Lngllsh lL would read CeL all of Lhe u1 elemenLs from Lhe
header elemenL of ndex.htm1 and lnserL Lhem lnLo Lhe
contaner elemenL of Lhe currenL page When you're
done run Lhe hacklnks{) funcLlon" noLe LhaL
ndex.htm1 refers Lo Lhe home page of Lhe slLe
4.1hls llne ls execuLed lf Lhe ur1 parameLer has a value lL
says ln effecL CeL Lhe content elemenL from Lhe ur1
LhaL was passed lnLo Lhe 1oadages{) funcLlon and lnserL
lL lnLo Lhe contaner elemenL of Lhe currenL page When
you're done run Lhe hacklnks{) funcLlon
5. Cnce Lhe 1oad{) funcLlon has compleLed Lhe
contaner elemenL of Lhe currenL page wlll conLaln Lhe
1ML snlppeL LhaL was reLrleved 1hen 1oad{) wlll run Lhe
hacklnks{) funcLlon
6.Cn Lhls llne hacklnks{) flnds all of Lhe llnks LhaL are ln
Lhe new 1ML and blnds a cllck handler Lo Lhem uslng Lhe
llnes of code LhaL follow Cllck handlers are auLomaLlcally
passed an evenL ob[ecL whlch l'm capLurlng as Lhe funcLlon
parameLer e 1he evenL ob[ecL of a cllcked llnk conLalns Lhe
u8L of Lhe remoLe page ln e.target.hre1
7. normally a web browser wlll navlgaLe Lo a new page when
a llnk ls cllcked 1hls navlgaLlon response ls called Lhe
defaulL behavlor" of Lhe llnk Slnce we are handllng cllcks
and loadlng pages manually we need Lo prevenL Lhls
defaulL behavlor Cn Lhls llne l've done so by calllng Lhe
bullLln prevent0e1au1t{) meLhod of Lhe evenL ob[ecL lf
l had lefL LhaL llne ouL Lhe browser would have navlgaLed Lo
Lhe u8L of Lhe cllcked llnk
8. When Lhe user cllcks u8L of Lhe remoLe page ls passed Lo
1oadage{) funcLlon and Lhe cycle sLarLs all over agaln

Loading lndicaIor
Slnce we are noL allowlng Lhe browser Lo navlgaLe from page Lo
page Lhe user wlll noL see any lndlcaLlon of progress whlle daLa
ls loadlng We need Lo provlde some feedback Lo leL users
know LhaL someLhlng ls ln facL happenlng WlLhouL Lhls
feedback users wlll wonder lf Lhey acLually cllcked Lhe llnk or
mlssed lL and wlll ofLen sLarL cllcklng all over Lhe place ln
frusLraLlon 1hls can lead Lo lncreased server load and
appllcaLlon crash

1hanks Lo [Cuery provldlng Lhls sorL of feedback only Lakes Lwo
llnes of code We'll [usL append a loadlng dv Lo Lhe body when
1oadage{) sLarLs and remove Lhe loadlng dv when
hacklnks{) ls done 1hls blL of !avaScrlpL ln lphone[s
converLs Lhe llnks on Lhe page Lo A[ax requesLs" 1he llnes you
need Lo add Lo phone.s are shown ln bold
${document).ready{1uncton{){
1oadage{),
)),
1uncton 1oadage{ur1) {
Tody.appenddiv id="progress">Loading.../div>
1 {ur1 == unde1ned) {
${'contaner').1oad{'ndex.htm1 header u1',
hacklnks),
) e1se {
${'contaner').1oad{ur1 + ' content', hacklnks),
)
)
1uncton hacklnks{) {
${'contaner a').c1ck{1uncton{e){
e.prevent0e1au1t{),
1oadage{e.target.hre1),
)),
progress.remove
)

<<<<<<<lig .8 Screen ShoI ol iPhone>>>>>>>


CSS added Lo Lhe sLyle sheeL
progress {
-webkt-border-radus: px,
background-co1or: rgba{,,,.7),
co1or: whte,
1ont-sze: 8px,
1ont-weght: bo1d,
heght: 8px,
1e1t: 6px,
1ne-heght: 8px,
margn: auto,
poston: abso1ute,
text-a1gn: center,
top: px,
wdth: px,
)

My slLe happens Lo have a slngle h aL Lhe beglnnlng of each
page LhaL would make a nlce page LlLle (see llgure 8efore
movlng Lhe page headlng Lo Lhe Loolbar") 1o be more
lhoneesque l'm golng Lo pull LhaL LlLle ouL of Lhe conLenL and
puL lL ln Lhe header (see llgure and afLer movlng Lhe
page headlng Lo Lhe Loolbar") Agaln [Cuery Lo Lhe rescue you
can [usL add Lhree llnes Lo Lhe hacklnks{) funcLlon Lo
make lL happen Lxample below shows Lhe hacklnks
funcLlon wlLh Lhese changes

1uncton hacklnks{) {
${'contaner a').c1ck{1uncton{e){
e.prevent0e1au1t{),
1oadage{e.target.hre1),
)),
var title = h.html || ello
h.htmltitle
h.remove
${'progress').remove{),
)
Llke mosL slLes mlne has llnks Lo exLernal pages (le pages
hosLed on oLher domalns) l don'L wanL Lo hl[ack Lhese exLernal
llnks because lL wouldn'L make sense Lo ln[ecL Lhelr 1ML lnLo
my lhonespeclflc layouL ln Lxample 39 ?ou can allow
exLernal pages Lo load normally by checklng Lhe domaln name
of Lhe u8L" l have added a condlLlonal LhaL checks Lhe u8L for
Lhe exlsLence of my domaln name lf lL's found Lhe llnk ls
hl[acked and Lhe conLenL ls loaded lnLo Lhe currenL page LhaL
ls A[ax ls ln effecL lf noL Lhe browser wlll navlgaLe Lo Lhe u8L
normally

1uncton hacklnks{) {
${'contaner a').c1ck{1uncton{e){
var url = e.target.hre1
i1 url.match/somncthbcner]ee2010.com/ (
e.prevent0e1au1t{),
1oadage{ur1),

)),
var tt1e = ${'h').htm1{) || 'ue11o!',
${'h').htm1{tt1e),
${'h').remove{),
${'progress').remove{),
)


#oll Your Own Back BuIIon
1he elephanL ln Lhe room aL Lhls polnL ls LhaL Lhe user has no way
Lo navlgaLe back Lo prevlous pages (remember LhaL we've
hl[acked all Lhe llnks so Lhe Safarl page hlsLory won'L work) LeL's
address LhaL by addlng a back buLLon Lo Lhe LoplefL corner of Lhe
screen llrsL l'll updaLe Lhe !avaScrlpL and Lhen l'll do Lhe CSS
Addlng a sLandard lhonelzed back buLLon Lo Lhe app means
keeplng Lrack of Lhe user's cllck hlsLory 1o do Lhls we'll have Lo
A) sLore Lhe u8L of Lhe prevlous page so we know where Lo go
back Lo and 8) sLore Lhe LlLle of Lhe prevlous page so we know
whaL label Lo puL on Lhe back buLLon
Addlng Lhls feaLure Louches on mosL of Lhe !avaScrlpL we've
wrlLLen so far ln Lhls chapLer so l'll go over Lhe enLlre new
verslon of phone.s llne by llne (see Lxample 3
Lxpandlng Lhe exlsLlng !avaScrlpL example Lo lnclude supporL
for a back buLLon") 1he resulL wlll look llke llgure 2 lL
wouldn'L be an lhone app wlLhouL a glossy lefLarrow back
buLLon"
Adding supporI lor back buIIon:
var hst = j,
var startur1 = 'ndex.htm1',
${document).ready{1uncton{){
1oadage{startur1),
)),
1uncton 1oadage{ur1) {
${'body').append{'<dv
d="progress">loadng...<,dv>'),
scro111o{,),
1 {ur1 == startur1) {
var e1ement = ' header u1',
) e1se {
var e1ement = ' content',
)
${'contaner').1oad{ur1 + e1ement, 1uncton{){
var tt1e = ${'h').htm1{) || 'ue11o!',
${'h').htm1{tt1e),
${'h').remove{),
${'.1e1t8utton').remove{),
hst.unsh1t{{'ur1':ur1, 'tt1e':tt1e)),
1 {hst.1ength > ) {
${'header').append{'<dv
c1ass="1e1t8utton">'+hstj.tt1e+'<,dv>'),
${'header .1e1t8utton').c1ck{1uncton{){
var thsage = hst.sh1t{),
var prevousage = hst.sh1t{),
1oadage{prevousage.ur1),
)),
)
${'contaner a').c1ck{1uncton{e){
var ur1 = e.target.hre1,
1 {ur1.match{,onathanstark.com,)) {
e.prevent0e1au1t{),
1oadage{ur1),
)
)),
${'progress').remove{),
)),
)

1.Cn Lhls llne l'm lnlLlallzlng a varlable named hst as an
empLy array Slnce l've deflned lL ouLslde of any funcLlons lL
exlsLs ln Lhe global scope and wlll be avallable everywhere
ln Lhe page noLe LhaL l dldn'L use Lhe full word hstory as
my varlable name because LhaL ls a predeflned ob[ecL
properLy ln !avaScrlpL and should be avolded ln your own
code
. ere l'm deflnlng Lhe relaLlve u8L of Lhe remoLe page Lo
load when Lhe user flrsL vlslLs phone.htm1 ?ou mlghL
recall from earller examples LhaL l [usL checked for ur1 ==
unde1ned Lo handle Lhe flrsL page load buL ln Lhls
example we are golng Lo use Lhe sLarL page ln a few places
1herefore lL makes sense Lo deflne lL globally
3. 1hls llne and Lhe nexL make up Lhe documenL ready
funcLlon deflnlLlon noLe LhaL unllke prevlous examples l'm
passlng Lhe sLarL page Lo Lhe 1oadage{) funcLlon
4. Cn Lo Lhe 1oadage{) funcLlon 1hls llne and Lhe nexL are
verbaLlm from prevlous examples
5. 1hls 1...e1se sLaLemenL deLermlnes whlch elemenLs Lo
load from Lhe remoLe page lor example lf we wanL Lhe
sLarL page we grab Lhe u1s from Lhe header oLherwlse we
grab Lhe conLenL dv
6.Cn Lhls llne Lhe u8L parameLer and Lhe approprlaLe source
elemenL are concaLenaLed as Lhe flrsL parameLer passed Lo
Lhe load funcLlon As for Lhe second parameLer l'm passlng
an ooooymoos fooctloo (an unnamed funcLlon LhaL ls
deflned lnllne) dlrecLly As we go Lhrough Lhe anonymous
funcLlon you'll noLlce a sLrong resemblance Lo Lhe
hacklnks{) funcLlon whlch Lhls anonymous funcLlon
has replaced lor example Lhe followlng Lhree llnes are
ldenLlcal Lo prevlous examples
7. Cn Lhls llne l'm removlng Lhe .1e1t8utton ob[ecL from
Lhe page (1hls mlghL seem welrd because l haven'L yeL
added lL Lo Lhe page we'll be addlng lL a couple sLeps
down)
8. ere l'm uslng Lhe bullLln unsh1t meLhod of Lhe
!avaScrlpL array Lo add an ob[ecL Lo Lhe beglnnlng of Lhe
hst array 1he ob[ecL l'm addlng has Lwo properLles ur1
and tt1e whlch are Lhe Lwo pleces of lnformaLlon we
need Lo supporL Lhe back buLLon dlsplay and behavlor
9. Cn Lhls llne l'm uslng Lhe bullLln 1ength meLhod of Lhe
!avaScrlpL array Lo flnd ouL how many ob[ecLs are ln Lhe
hlsLory array lf Lhere ls only one ob[ecL ln Lhe hlsLory array
lL means LhaL Lhe user ls on Lhe flrsL page and Lherefore we
don'L need Lo dlsplay a back buLLon owever lf Lhere ls
more Lhan one ob[ecL ln Lhe hst array we need Lo add a
buLLon Lo Lhe header
10. nexL l'm addlng LhaL .1e1t8utton l menLloned
earller 1he LexL of Lhe buLLon wlll be Lhe same as Lhe LlLle
of Lhe page before Lhe currenL page whlch ls whaL l'm
accesslng wlLh Lhe hstj.tt1e code !avaScrlpL arrays
are zerobased so Lhe flrsL lLem ln Lhe array (Lhe currenL
page) has an lndex of ln oLher words lndex ls Lhe
currenL page lndex ls Lhe prevlous page lndex 2 ls Lhe
page before LhaL and so on
11. ln Lhls block of code l'm blndlng an anonymous
funcLlon Lo Lhe cllck handler of Lhe back buLLon 8emember
cllck handler code execuLes when Lhe user cllcks noL when
Lhe page loads So afLer Lhe page loads and Lhe user cllcks
Lo go back Lhe code lnslde Lhls funcLlon wlll run
1. 1hls llne and Lhe nexL use Lhe bullLln sh1t meLhod
of Lhe array Lo remove Lhe flrsL Lwo lLems from Lhe hst
array and Lhe lasL llne ln Lhe funcLlon sends Lhe u8L of Lhe
prevlous page Lo Lhe 1oadage{) funcLlon
13. 1he remalnlng llnes were copled exacLly from prevlous
examples so l won'L rehash Lhem here
14. 1hls ls Lhe u8L maLchlng code lnLroduced earller ln Lhls
chapLer 8emember Lo replace
somnathbaneree.com wlLh parL of your webslLe's
domaln or hosLname or none of Lhe local llnks wlll be
hl[acked and loaded lnLo Lhe page

now LhaL we have our back buLLon all LhaL remalns ls Lo preLLy
lL up wlLh some CSS (see Lxample 3 Add Lhe followlng Lo
lphonecss Lo beauLlfy Lhe back buLLon wlLh a border lmage") l
sLarL off by sLyllng Lhe LexL wlLh 1ont-weght text-a1gn
1ne-heght co1or and text-shadow l conLlnue by
placlng Lhe dv preclsely where l wanL lL on Lhe page wlLh
poston top and 1e1t 1hen l make sure LhaL long LexL on
Lhe buLLon label wlll LruncaLe wlLh an elllpsls uslng max-wdth
whte-space over11ow and text-over11ow llnally l
apply a graphlc wlLh border-wdth and -webkt-border-
mage unllke my earller border lmage example Lhls lmage has
a dlfferenL wldLh for Lhe lefL and rlghL borders because Lhe
lmage ls made asymmeLrlcal by Lhe arrowhead on Lhe lefL slde
<<<<<<<lig .8 Screen ShoI ol iPhone>>>>>>>

Add Lhe followlng llne Lo phone.css Lo beauLlfy back buLLon
header dv.1e1t8utton {
1ont-weght: bo1d,
text-a1gn: center,
1ne-heght: 8px,
co1or: whte,
text-shadow: rgba{,,,.6) px -px px,
poston: abso1ute,
top: 7px,
1e1t: 6px,
max-wdth: Spx,
whte-space: nowrap,
over11ow: hdden,
text-over11ow: e11pss,
border-wdth: 8px 4px,
-webkt-border-mage: ur1{mages,back_button.png)
8 4,
)

8y defaulL Moblle Safarl brlefly dlsplays a LranslucenL gray box
over cllckable ob[ecLs LhaL have been Lapped (llgure 37 8y
defaulL Moblle Safarl dlsplays a LranslucenL gray box over
cllckable ob[ecLs LhaL have been Lapped") Slnce our back
buLLon ls noL recLangular Lhls effecL looks a llLLle lame buL
removlng lL ls easy and makes Lhe app look much beLLer
Moblle Safarl supporLs a properLy called -webkt-tap-
hgh1ght-co1or LhaL allows you Lo change Lhe defaulL Lo
whaLever color you llke l wanL Lo remove Lhe hlghllghL
compleLely whlch l've done here by seLLlng Lhe Lap hlghllghL Lo
a fully LransparenL color (see Lxample 32 Add Lhe followlng
Lo lphonecss Lo remove Lhe defaulL Lap hlghllghL from Moblle
Safarl")


<<<<<<<lig .8 Screen ShoI ol iPhone>>>>>>>

Add Lhe followlng Lo lhonecss
header dv.1e1t8utton {
1ont-weght: bo1d,
text-a1gn: center,
1ne-heght: 8px,
co1or: whte,
text-shadow: rgba{,,,.6) px -px px,
poston: abso1ute,
top: 7px,
1e1t: 6px,
max-wdth: Spx,
whte-space: nowrap,
over11ow: hdden,
text-over11ow: e11pss,
border-wdth: 8px 4px,
-webkt-border-mage: ur1{mages,back_button.png)
8 4,
ceTkittaphighlightcolor: rgTa
)

ln Lhe case of Lhe back buLLon Lhere can be aL leasL a second or
Lwo of delay before Lhe conLenL from Lhe prevlous page appears
1o avold frusLraLlon l wanL Lhe buLLon Lo look cllcked Lhe lnsLanL
lL's Lapped ln a deskLop browser Lhls would be a slmple process
you'd [usL add a declaraLlon Lo your CSS uslng Lhe :actve
pseudoclass Lo speclfy an alLernaLe sLyle for Lhe ob[ecL LhaL was
cllcked l don'L know wheLher lL's a bug or a feaLure buL Lhls
approach does noL work on Lhe lhone Lhe :actve sLyle ls
lgnored
l Loyed around wlLh comblnaLlons of :actve and :hover
whlch broughL me some success wlLh nonA[ax apps owever
wlLh an A[ax app llke Lhe one we are uslng here Lhe :hover sLyle
ls sLlcky (le Lhe buLLon appears Lo remaln cllcked" even afLer
Lhe flnger ls removed)
lorLunaLely Lhe flx ls preLLy slmple l use [Cuery Lo add Lhe
class c1cked Lo Lhe buLLon when Lhe user Laps lL l've opLed
Lo apply a darker verslon of Lhe buLLon lmage Lo Lhe buLLon ln
Lhe example (see llgure 38 lL's a subLle dlfference buL Lhe
cllcked back buLLon ls a blL darker Lhan Lhe defaulL sLaLe" and
Lxample 33 Add Lhe followlng Lo lphonecss Lo make Lhe
back buLLon look cllcked Lhe momenL Lhe user Laps lL") ?ou'll
need Lo make sure you have a buLLon lmage called
back_button_c1cked.png ln Lhe mages subfolder See
Lhe secLlon called Addlng 8aslc 8ehavlor wlLh [Cuery" for Llps
on flndlng or creaLlng your own buLLon lmages

Add Lhe followlng llne Lo phone.css Lo beauLlfy back buLLon
and make Lhe back buLLon look cllcked Lhe momenL Lhe user Laps
lL
header dv.1e1t8utton {
1ont-weght: bo1d,
text-a1gn: center,
-webkt-border-mage:
ur1{mages,back_button_c1cked.png) 8 4,
)

WlLh Lhe CSS ln place l can now updaLe Lhe porLlon of
phone.s LhaL asslgns Lhe cllck handler Lo Lhe back buLLon
llrsL l add a varlable e Lo Lhe anonymous funcLlon ln order Lo
capLure Lhe lncomlng cllck evenL 1hen l wrap Lhe evenL LargeL
ln a [Cuery selecLor and call [Cuery's addC1ass{) funcLlon Lo
asslgn my cllcked CSS class Lo Lhe buLLon


${'header .1e1t8utton').c1ck{1uncton{e){
e.target.addClassclicked
var thsage = hst.sh1t{),
var prevousage = hst.sh1t{),
1oadage{prevousage.ur1),
)),


lcon lor Home Screen
opefully users wlll wanL Lo add an lcon for your web app
(called a Web Cllp lcon") Lo Lhelr home screens 1hey do Lhls
by Lapplng Lhe plus buLLon aL Lhe boLLom of Lhe Safarl wlndow
8y defaulL Lhe lhone wlll creaLe Lhls lcon by Lhumbnalllng Lhe
currenL page (lncludlng poslLlon and zoom) and applylng
rounded corners and a glossy effecL (llgure 32 SLep 4 a 37
37 plxel lmage wlll show up on Lhe home screen")

1o cusLomlze Lhe home screen lmage Lhe cool klds provlde a
cusLom Web Cllp lcon 1he slmplesL way Lo do Lhls ls Lo speclfy a
slngle lcon for your enLlre slLe by uploadlng a flle named app1e-
touch-con.png Lo your web rooL 1he flle should be 37 plxels
square and wlLhouL gloss or rounded corners because Lhe lhone
wlll add Lhese auLomaLlcally lf you don'L wanL Lhe lhone Lo add
effecLs Lo your Web Cllp lcon change Lhe name of Lhe flle Lo
app1e-touch-con-precomposed.png
ln some cases you may wanL Lo provlde a Web Cllp lcon for a
page LhaL ls dlfferenL from Lhe resL of your slLe ?ou can do Lhls by
addlng one of Lhe followlng llnes Lo Lhe head secLlon of Lhe
phone.htm1 (replaclng myCustom1con.png wlLh Lhe absoluLe
or relaLlve paLh Lo Lhe lmage)
<1nk re1="app1e-touch-con" hre1="myCustom1con.png" ,>

<1nk re1="app1e-touch-con-precomposed"
hre1="myCustom1con.png" ,>

lull Screen Mode
leel llke reclalmlng a quarLer of Lhe avallable verLlcal space from
Moblle Safarl (4 plxels Lo be preclse)? Add Lhe followlng llne Lo
Lhe head secLlon of Lhe Lrafflc cop" 1ML documenL
phone.htm1 and your web app wlll dlsplay ln full screen mode
when launched from Lhe Web Cllp lcon
<meta name="app1e-mob1e-web-app-capab1e" content="yes" ,>
l would've Lold you abouL Lhls feaLure earller buL lL's only useful
once you have hl[acked all of your hyperllnks wlLh A[ax As soon as
a user cllcks on a nonhl[acked llnkone LhaL acLually navlgaLes Lo
a new pageMoblle Safarl wlll launch and load Lhe page
normally 1hls behavlor ls perfecL for Lhe example we've been
worklng wlLh because exLernal llnks (Amazon 1wlLLer lacebook
eLc) wlll open ln Safarl

Changing Ihe SIaIus Bar
Cnce you've added Lhe app1e-mob1e-web-app-capab1e
meLa Lag you have Lhe opLlon Lo conLrol Lhe background color of
Lhe 2plxel sLaLus bar aL Lhe Lop of Lhe screen uslng Lhe app1e-
mob1e-web-app-status-bar-sty1e meLa Lag 1he normal
gray Safarl sLaLus bar ls Lhe defaulL or you can change lL Lo b1ack
(see llgure 33 lull screen mode glves you abouL 23 more
screen real esLaLe and allows you Lo cusLomlze Lhe appearance of
Lhe sLaLus bar") ?ou can also seL lL Lo b1ack-trans1ucent
whlch makes lL parLlally LransparenL and addlLlonally removes lL
from Lhe documenL flow ln oLher words your conLenL wlll be
shlfLed up by 2 plxels and behlnd Lhe sLaLus bar when Lhe page
flrsL loads so you mlghL have Lo poslLlon your header a llLLle lower
Lo compensaLe
<meta name="app1e-mob1e-web-app-status-bar-sty1e" content="b1ack" ,>

Providing a CusIom SIarIup raphic
When an app ls launched ln full screen mode Lhe user ls
presenLed wlLh a screenshoL of Lhe app whlle Lhe flrsL page ls
loadlng l'm noL a fan of Lhls because lL looks llke Lhe app ls ready
Lo be lnLeracLed wlLh when ln reallLy Lapplng a llnk wlll do
noLhlng lurLhermore Lhe screenshoL ls based on Lhe lasL page
from Lhe user's prevlous vlslL scrolled Lo wherever he lefL off
noL very aLLracLlve
lorLunaLely Moblle Safarl allows us Lo deflne a sLarLup graphlc
LhaL wlll be dlsplayed whlle Lhe page ls loadlng 1o add a cusLom
sLarLup graphlc creaLe a 32px 46px nC flle and place lL ln
Lhe same dlrecLory wlLh phone.htm1 nexL add Lhe followlng
llne Lo Lhe head secLlon of phone.htm1 (you'd replace
myCustomStartup6raphc.png wlLh Lhe absoluLe or relaLlve
paLh Lo your lmage)

<1nk re1="app1e-touch-startup-mage"
hre1="myCustomStartup6raphc.png" ,>

1he nexL Llme we launch our app from Lhe Web Cllp lcon Lhe
defaulL loadlng behavlor wlll Lake place whlle Lhe new cusLom
graphlc ls downloaded Cn Lhe subsequenL launch Lhe cusLom
sLarLup graphlc wlll be dlsplayed (llgure 34 rovldlng a cusLom
sLarLup graphlc for an app launched ln full screen mode")
Android
ere ls androldcss
body {
background-co1or: ddd, ,* 8ackground co1or *,
co1or: , ,* Ioreground co1or used 1or text *,
1ont-1am1y: ue1vetca,
1ont-sze: 4px,
margn: , ,* ^mount o1 negatve space around the outsde o1 the body *,
paddng: , ,* ^mount o1 negatve space around the nsde o1 the body *,
)
header h {
margn: ,
paddng: ,
)
header h a {
background-co1or: ccc,
border-bottom: px so1d 666,
co1or: ,
dsp1ay: b1ock,
1ont-sze: px,
1ont-weght: bo1d,
paddng: px ,
text-a1gn: center,
text-decoraton: none,
)
header u1 {
1st-sty1e: none,
margn: px,
paddng: ,
)
header u1 1 a {
background-co1or: IIIIII,
border: px so1d ,
co1or: ,
dsp1ay: b1ock,
1ont-sze: 7px,
1ont-weght: bo1d,
margn-bottom: -px,
paddng: px px,
text-decoraton: none,
)
content, sdebar {
paddng: px,
)

1ooter {
dsp1ay: none,
)

Igure -6. 1ndentng text 1rom the edge
s1he content n the 1ooter o1 ths page s basca11y a rehash o1 the
navgaton e1emen
t{the u1 e1ement wth the 10 nav) at the top o1 the page, so you can
remove the 1oote
r1rom the ^ndrod verson o1 the page by settng the dsp1ay to none, as
1o11ows
:1ooter
{ dsp1ay : none
,
)
header h a {
text-shadow: px px px 111,
background-mage: -webkt-gradent{1near, 1e1t top, 1e1t bottom,
1rom{ccc), to{)),
)

header u1 1:1rst-ch1d a {
-webkt-border-top-1e1t-radus: 8px,
-webkt-border-top-rght-radus: 8px,
)
header u1 1:1ast-ch1d a {
-webkt-border-bottom-1e1t-radus: 8px,
-webkt-border-bottom-rght-radus: 8p
)

All LexL on Androld ls rendered uslng a cusLom fonL named urold
1he urold fonL famlly was speclflcally bullL for moblle devlces has
excellenL characLer seL supporL and conLalns Lhree varlanLs urold
Sans urold Sans Mono and urold Serlf 1herefore speclfylng a
fonL famlly of elveLlca as we've done here wlll only have an
effecL on devlces oLher Lhan Androld now leL's aLLack Lhe header
dlv LhaL conLalns Lhe maln home llnk (le Lhe logo llnk) and Lhe
prlmary and secondary slLe navlgaLlon 1he flrsL sLep ls Lo formaL
Lhe logo llnk as a cllckable LlLle bar Add Lhe followlng Lo Lhe
androldcss flle


AnimaIions

lhone apps have some anlmaLlon characLerlsLlcs LhaL add
conLexL and meanlng for Lhe user lor example pages sllde lefL
as you drlll down Lhrough llnks and sllde rlghL as you navlgaLe
back ere we wlll Lo add characLerlsLlc behavlors llke slldlng
and page fllp 1hese changes and A[ax and full screen mode
wlll make Lhe web app almosL lndlsLln gulshable from a naLlve
appllcaLlon

Tools Io use
uownload [C1ouch from hLLp$$[qLouch com$

Index.html
1he 1ML here baslcally amounLs Lo a head wlLh a LlLle and a
body wlLh chlldren all dlvs
1heses dlv become a panel ln Lhe appllcaLlon lnslde each panel
dlv Lhere ls a dlv wlLh a class of Loolbar 1hls Loolbar class ls
speclflcally predeflned ln Lhe [C1ouch Lhemes Lo sLyle an elemenL
llke a LradlLlonal lhone too|bar 1hls unordered llsL Lag has Lhe
class edgetoedge 1he edgeLoedge class Lells [C1ouch Lo sLreLch
Lhe llsL all Lhe way from lefL Lo rlghL ln Lhe vlewable area Cn Lhls
llne Lhere ls an ll LhaL conLalns a llnk wlLh lLs href polnLlng aL Lhe
AbouL panel lncludlng Lhe arrow class Lo Lhe ll ls opLlonal dolng
so wlll add a chevron Lo Lhe rlghL slde of Lhe lLem ln Lhe llsL 1he
Loolbar elemenLs each conLaln a slngle h elemenL LhaL wlll
become Lhe panel LlLle Cn Lhls llne Lhere ls a llnk wlLh Lhe classes
buLLon and back whlch Lell [C1ouch Lo make Lhe buLLon look and
acL llke a back buLLon


?ou wlll need Lo download [C1ouch from hLLp$$[qLouchcom unzlp lL and move Lhe [qLouch and Lhemes
dlrecLorles lnLo Lhe same dlrecLory as your 1ML documenL ?ou wlll also need Lo go lnLo Lhe [qLouch
dlrecLory and rename Lhe [Cuery !avaScrlpL flle (such as [query32mln[s) Lo [query[s


We are including the jqtouch.css Iile. This Iile deIines some structural design rules that are
very speciIic to handling animations, orientation, and other iPhone- speciIic stuII. This Iile is
required and there should be no reason Ior you to edit it.

Including the CSS Ior the 'jqt theme, which comes with jQTouch. The classes used in the
HTML correspond to CSS selectors in this document.

jQTouch comes with two themes available by deIault. You can also make your own by
duplicating a deIault theme and making changes to it, or writing a new one Irom scratch.

jQTouch requires jQuery. jQTouch comes with its own copy oI jQuery.

In the script block we initialize the jQTouch object and send in two property values: icon and
statusBar.

jQTouch exposes several properties to customize the behavior and appearance oI your app.
In this case, icon tells jQTouch where to look Ior the custom Web Clip icon, and statusBar
controls the color oI the 20px strip at the top oI the app in Iull screen mode.

So quickly you have an app which slides in and out, does a Iull screen, have a custom logo
and even do a page Ilip (Try the settings inside time sheet).






I1on 8eav|or o nan very eas||y stom|ze








Appendix A.
l lor a qulck and Lhorough crash course ln CSS Lry c55 locket
kefeteoce by Lrlc Meyer (C'8ellly)
ll [Cuery ls avallable aL hLLp$$[querycom

lll 8ead more abouL Lhe uocumenL Cb[ecL Model here
hLLp$$enwlklpedlaorg$wlkl$uocumenL_Cb[ecL_Model
lI1o learn more on dvbased layouLs check ouL eslqoloq
wltb web 5tooJotJs by !effrey Zeldman (new 8lders
ress)
I[C1ouch from hLLp$$[qLouchcom$
Il8eference Lo !avaScrlpL evenL
hLLp$$wwww3schoolscom$hLmldom$dom_ob[_evenLasp

You might also like