Вы находитесь на странице: 1из 272

.

-
OReilly
c .

.
.
.
.
. , .
.

32.988.02
004.738.5
.
96 -. .: , 2015. 272 .: . (-
OReilly).
ISBN 978-5-496-01226-3
-,
HTML, JavaScript . -
- ,
, , ,
.
, ,
. -,
.
12+ ( 29 2010 . 436-)

ISBN 978-1449370190 . Authorized Russian translation of the English edition Learning Web App Development
(ISBN 9781449370190) 2014 Semmy Purewal. This translation is published and sold
by permission of OReilly Media, Inc., the owner of all rights to publish and sell the same.
ISBN 978-5-496-01226-3 , 2015
, , 2015

OReilly. .

.

, , , -
. , ,

, .

, 192102, -, . (. ), . 3, , . 7.
034-2014, 58.11.12
, .
19.09.14. 70100/16. . . . 21,930. 1000. 0000.

. 180004, , . , 34.

............................................................................................12
........................................................................................................12
..................................................................................................12
1. .................................................................................20
2. ............................................................................................43
3. ..................................................................................................68
4. ............................................................................... 108
5. .................................................................................................. 155
6. .............................................................................................. 185
7. .............................................................................. 217
8. ........................................................................................ 234
9. ...................................................................................... 248

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Safari Books Online. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Sublime Text. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Sublime Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
UNIX . . . . . . . . . . . . . . . . . . . . 26
Git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Sublime Text. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Emacs Vim. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
UNIX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
GitHub. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
7

2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
, HTML!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
<p>: a. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
, ... !. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
. . . . . . . . . . . . . . . . . . . . 50
HTML . . . . . . . . . . . . . . . . 51
Amazeriffic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
. . . . . . . 57
. . . . . . . . . . . . . . . . . 58
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
(FAQ) Amazeriffic. . . . . . . . . . . . . . . . . 67
HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
, CSS!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
clear. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
CSS Lint . . . . . . . . . . . . . . 91
Chrome Developer Tools. . . . . . . . . . . . . 93
Amazeriffic!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
. . . . . . . . . . . . . . . . . . . . . . 104
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
CSS-. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Amazeriffic. . . . . . . . . . . . . . . . 106
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
. . . . . . . . . . . . . . . . . . . . . 107

4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
, JavaScript!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .108
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .129
JavaScript Chrome JavaScript Console . . . . . . . . . . . . . . . . . 129
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
JSLint . . . . . . . . . . . . . . . 137
Amazeriffic. . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
FizzBuzz. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
. . . . . . . . . . . . . . . . . . . . . . . . . . . 151
(Project Euler). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
, JavaScript!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
9

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
. . . . . . . . . . . . . . . . . . . . . . . . . . 159
JSON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
JSON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
. . . . . . . . . . . . . . . . . . . . . . . 161
getJSON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
JSON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Flickr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Amazeriffic. . . . . . . . . . . . . . . . . . . 168
map. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
. . . . . . . . . . . . . . . . . . . . . . 171
. . . . . . . . . . . . . 174
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
- Flickr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
. . . . . . . . . . . . . . . . . . . . . . . . . . 181
API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Virtual Box Vagrant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
SSH. . . . . . . . . . . . . 188
, Node.js!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
, HTTP!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Express. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Express NPM. . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Express . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
. . . . . . . . . . . . . . . . . . . . . . . . . . 196
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Twitter. . . . . . . . . . . . . . . . . . . . . . . . 199
Twitter API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
10

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Twitter . . . . . . . . . . . . . . . . . . . . . . 203
Express. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Amazeriffic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
. . . . . . . . . . . . . . . . . . . . . . . . . 208
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Node.js. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
JSHint CSS Lint NPM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212
API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
SQL -SQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Redis. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Redis . . . . . . . 219
Redis package.json . . . . . . . . . . . . . . . 220
Redis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Redis . . 222
mget . . . . . . . . . . 224
MongoDB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
MongoDB
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Mongoose. . . . . . . . . . . . . . . . . . . . . . . . . . 228
Amazeriffic. . . . . . . . . . . . . . . . . . . . . . . . 231
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
. . . . . . . . . . . . . . . . . 233

8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
Cloud Foundry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
. . . . . . . . . . . . . . . . . . . . . 235
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .236
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Cloud Foundry. . . . . . . . . . . . . . . . . . . . . . . 240
11

package.json. . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Redis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
MongoDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247

9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .248
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
. . . . . . . . . . . . . . . . . . . . . . . . . . 249
AJAX . . . . . . . . . . . . . . . . . . . . . . . 251
. . . . . . . . . . . . . . . . . . . . . . . 253
AJAX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
HTTP, CRUD REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
jQuery . . . . . . . 260
HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
. . . . . . . . . . . . . . 262
Amazeriffic . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
. . . . . . . . . . . . . . . . . . . . . . . . . . 264
. . . . . . . . . . . . . . . . . . . . . . 264
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
ToDo. . . . . . . . . . . . . . . . . . . 267
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
. . . . . . . . . . . . . . . . . . . . . . . . . . . 270
. . . . . . . . . . . 271
EJS Jade. . . . . . . . . . . . . . . . . . . 272
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Ruby on Rails. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272

,
vinitski@minsk.piter.com ( , ).
!
http://www.piter.com
.


10
- JavaScript. -
, ,
. -
-, .

2008 ,
,
. , ,
, -
. , , ,
, -
:
-.
, , . ,
, ,
().
, -? , , -

, -
. - HTML
CSS, .
13

, , -
, ()
1, Ruby on Rails. , -
, -
, .
, - ,
.
? , -
, -
! ,
, ,
. , ,
,
Model View Controller,
, .
- ,
, , -
, . ,
,
, .

- -
. Ruby on Rails, ,
, ,
. , ,
, , , .
, -
.
, Ruby on Rails.
, 2011
<font>!
, , -
. -
Node.js ( JavaScript ) ,
,
, . ,
Ruby on Rails,
.
, -
.

1
, ,
.
. .
14

, - , -
JavaScript. ( -
),
(HTML, CSS, jQuery, Javascript),
(Node.js, HTTP, ), (Cloud Foundry)
(, MVC, DRY).
JavaScript,
, ,
, .


Git, , Git, .
, GitHub, -
. GitHub ,
, Git.
jQuery, -
.
, Twitter Bootstrap Zurb Foundation
3. Backbone
Ember, . Rails
.
Express, ()
. -
, , .
, -
, .
MongoDB - , -
Node.js JavaScript -
. , Redis, .
Cloud Foundry , ,
( Heroku Nodejitsu), ,
-
. -
.


, , -
, .
,
.
15

,
, -
, .
, ,
Rails.
,
-.
,
if-else, , . , ,
- - -
. ,
Khan Academy Code Academy -
.
, -
,
- , , (14-
) .


- . ,
, , . ,
, -
. , ,
, , -
. , GitHub -
. ,
http://www.github.com/semmypurewal/LearningWebAppDev. -
,
.
, .
, .
, , . -

, .


14- , 23
34 . ,
,
JavaScript, jQuery, AJAX Node.js. , ,
16

,
,
.
, - ,
,
. , -
, ,
,
( ). -
, .
(, ,
, ),
.


, GitHub,
, . ,
http://learningwebappdev.com.

. , Twitter
(@semmypurewal) ,
me@semmy.me, . -
issues GitHub,
. , .


,
. ,
-
. , -
-
.
,
Google Chrome. ,
Internet Explorer. , ,
Internet Explorer 10+ -
.
JavaScript,
. ,
, ,
17

Java/C++.
, JSON
JavaScript. , $
, jQuery. ,
.


.

.

URL, , -
.


, , , , ..

, -
.

, ,
.

.
18


( , ..) -
http://www.github.com/semmypurewal/LearningWebAppDev.
, .
, .
, -
. , -
-
. -
.
.
, .
, ,
, ,
permissions@oreilly.com.

Safari Books Online


Safari Books Online , -

.
, , -
Safari Books Online
, , -
.
Safari Books Online
, . -
,
, OReilly Media,
Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que,
Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann,
IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-
Hill, Jones & Bartlett, Course Technology .
Safari Books Online .


, , , :
OReilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
19

800-998-9938 (in the United States or Canada)


707-829-0515 (international or local)
707-829-0104 (fax)
-, -
, . http://oreil.ly/
learning-web-app.
, -
, bookquestions@oreilly.com.
, ,
http://www.oreilly.com.
Facebook: http://facebook.com/oreilly.
Twitter: http://twitter.com/oreillymedia.
YouTube: http://www.youtube.com/oreillymedia.


-
. , -
, , -
.

, , - .
!
-
, OReilly.
-
.

. -
. - -
.
, , , , , ,
, , , -
. -
. !
, -
, -
, .
.
1

- , -
. ,
,
, . , -
, , !
-
, , -
. ,
( ) .
, .
, ,
- . 2
, HTML.
, , -
, .


, , .
,
, -
, .
,
, . ,
, ,
,
.
, ,
Microsoft Word Google
Docs. , .
, -
. ,
21

, ,
, .

(Integrated Development Environments, IDE), Eclipse, Visual Studio XCode.
, , ,
, -
. ,
.
? -
- . -
(Graphical User
Interface, GUI). , -
, , ,
. ,
.
,
-
. -
TextMate, Sublime Text Coda.
(
, ).
, ,
, -
. -
,
. Emacs (.1.1)
Vim (.1.2).

. 1.1. HTML, Emacs


22 1.

. 1.2. HTML, Vim

,
Sublime Text,
Emacs Vim. --
, ,
.

Sublime Text
Sublime Text ( Sublime)
, -. ,
-, -
Windows, Mac OS Linux. ,
.
, -
.
Sublime, http://www.sublimetext.com
Download .
. ( ) Sublime Text 3
-, .
.

Sublime Text
Sublime Text ,
.1.3.
23

. 1.3. Sublime Text,

, .
FileNew. Ctrl+N Windows Linux
Command+N Mac OS. Hello, World!
, .1.4.
Sublime, Preferences
Color Scheme. ,
. - -
,
.
Font Preferences, .

. 1.4. Sublime Hello, world!


24 1.

, , , Sublime untitled Hello,


world!, . , -
, , ,
, . -
. ,
- , ,
,
.
hello,
, .1.5.

. 1.5. Sublime Solarized (light)


hello

,
.
(_) ,
.

, Sublime, -
, -
. , , ,
edit save edit.
, . -
.


,
. ,
25

. , , -
, .
, - .
,
. , -
, .
,
, ,
.
,
, . , ,
- . , -
, , - ,
. -
, -
.
, ,
. ,
, . ,
, .
.
, ,
( ), -
. ,
.
, .
,
. -
Subversion, Mercurial, Perforce, CVS. --
-
Git.

Git
Git Windows, Mac OS.
Windows msysgit, GitHub
(.1.6). Google Code
GitHub. , -
, Git .
Mac OS Git for OS X Istaller
(.1.7). , , -
.
, Mac OS Snow Leopard (10.5), -
Mountain Lion (10.8).
26 1.

. 1.6. msysgit

. 1.7. Git for OS X

Linux, Git
.

UNIX
Git ,
.
27

, , , -
UNIX.
, ,
, -
. ,
,
. , , -
Finder Mac OS Windows.

, -
. ,
(). , -
: -
, , , -
, Emacs Vim. ,
-
.
Windows, Git
Bash, msysgit project,
. Git Bash , UNIX Windows
Git. Git Bash -
. Mac OS, -
Terminal, Utilities Applications.
Linux, ,
, , , -
Terminal, . -
Mac OS .1.8.

. 1.8. Mac OS
28 1.

, .
- , Mac OS Windows,
, , - .
, .
Mac OS :
Last login: Tue May 14 15:23:59 on ttys002
hostname $ _

?
, , ,
- . , ,
: ?
. pwd,
print working directory ( ( )).
:
hostname $ pwd
/Users/semmy

pwd, ls,
list the content of the current directory ( -
). ,
. Mac OS :
hostname $ ls
Desktop Downloads Movies Pictures
Documents Library Music

, ls Finder -
. ,
, , -
. , , -
pwd .


, ,
, .
, -
.
: -
cd, change directory ( ). ,
, Documents, :
hostname $ cd Documents

, , -
ls:
29

hostname $ ls
Projects

Documents,
Projects (). , ,
Projects . , -
Documents. , ,
pwd, :
hostname $ pwd
/Users/semmy/Documents

, ? -
(Back),
. , -
, . cd
(..) , -
:
hostname $ cd ..
hostname $ pwd
/Users/semmy
hostname $ ls
Desktop Downloads Movies Pictures
Documents Library Music


,
, . -
mkdir, make directory ( ):
hostname $ ls
Desktop Downloads Movies Pictures
Documents Library Music
hostname $ mkdir Projects
hostname $ ls
Desktop Downloads Movies Pictures
Documents Library Music Projects
hostname $ cd Projects
hostname $ ls
hostname $ pwd
/Users/semmy/Projects

-
, , ,
ls. mkdir Projects.
ls, , . cd, -
Projects, ls, .
, , , -
30 1.

ls . , , -
pwd, ,
Projects.
UNIX ,
. -
. ,
.


- ( ) -
. ,
.
. -
, ,
.

. UNIX -
, -
. , , Home ()
: Documents ( ), Pictures ( ) Music (
). Pictures . Documents
Projects () (. 1.9).

. 1.9. ,
31

, -
. (
), , -
.
, -
, , ,
.
,

, .
.

Git
,
, Git.

Git
, Git -
. -
, ,
-
, .
(, , ):
hostname $ git config --global user.name "Semmy Purewal"
hostname $ git config --global user.email semmy@semmy.me
! ,
, ,
Git.
Git.
Projects, :
hostname $ pwd
/Users/semmy
hostname $ cd Projects
hostname $ pwd
/Users/semmy/Projects
Chapter1 ( 1)1 -
, , . :

1
Git
. , ,
UTF-8 latin1. http://habrahabr.ru/post/74839/,

. . .
32 1.

hostname $ mkdir Chapter1


hostname $ ls
Chapter1
hostname $ cd Chapter1
hostname $ pwd
/Users/semmy/Projects/Chapter1

Git
Chapter1, -
Git git init. Git ,
:
hostname $ pwd
/Users/semmy/Projects/Chapter1
hostname $ git init
Initialized empty Git repository in /Users/semmy/Projects/Chapter1/.git/1

ls, , Git
, , !
.git, , ,
(.), . , -
ls c (all ), :
hostname $ ls -a
. .. .git

, ,
. ( )
( ).
, .git,
, Git :
hostname $ ls .git
HEAD config hooks objects
branches description info refs

,
. ,
a ls.


Sublime Text (
, ). ,
. ,
Open Sublime .

1
: Git /Users/semmy/Projects/Chap-
ter1/.git. . .
33

,
.1.10.

. 1.10. Sublime Chapter1

Chapter1, (
Command- Mac OS) Chapter1 -
, New File . ,
, , , -
Chapter1. index.html.
,
Hello, World! (.1.11).

. 1.11. Sublime index.html


34 1.

, Git.
, :
hostname $ pwd
/Users/semmy/Projects/Chapter1
hostname $ ls
index.html

git status :
hostname $ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# index.html1

! , -
Untracked files ( ). ,
, .
, index.html (committed)
Git.

2
index.html.
, , Git,
, git add:
hostname $ git add index.html

, .
. , , git status
:
hostname $ git status
# On branch master
#

1
: -. .
( "git add <file>..."
): index.html. . .
2
(commit) ,
. ,
, ,
. ()
. ,
: ,
, . . .
35

# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: index.html1
#

. , index.html
Changes to be commited (,
).

. git commit m -
, .
:
hostname $ git commit -m "Initial commit"
[master (root-commit) 147deb5] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 index.html2


.
, , - . git status
index.html, , -
. -
, , , :
hostname $ git status
# On branch master
nothing to commit (working directory clean)3

m -
. , , ,
Vim (
). , (:),
q! Enter, .

index.html . , -
: Goodbye, World! (, !). ,

1
: -. . :
( "git rm --cached <file>..." ). : index.html. . .
2
: [master (root-commit) 147deb5] . 1
, 1 (+). 100644 index.html. . .
3
: -: (
). . .
36 1.

. ,
git status :
hostname $ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.html1
#
no changes added to commit (use "git add" and/or "git commit -a")

: Git , index.html ,
. ,
git add , git commit,
.
, , git status ,
.
:
hostname $ git add index.html
hostname $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
hostname $ git commit -m "Add second line to index.html"
[master 1c808e2] Add second line to index.html
1 file changed, 1 insertion(+)2


-
. ,
, -
. .
, git log:

1
: -: .
( git add <file> ) (
"git checkout -- <file>..." ) : index.
html. . .
2
: -: : (
"git rm --cached <file>..." ). : index.html. hostname $ git commit
m index.html. 1 , 1 (+).
. .
37

hostname $ git log


commit 1c808e2752d824d815929cb7c170a04267416c04
Author: Semmy Purewal <semmy@semmy.me>
Date: Thu May 23 10:36:47 2013 -0400
Add second line to index.html
commit 147deb5dbb3c935525f351a1154b35cb5b2af824
Author: Semmy Purewal <semmy@semmy.me>
Date: Thu May 23 10:35:43 2013 -0400
Initial commit
Git, UNIX,
.
.


, ,

. , , -
. , -
,
.
Git ,
, .
, , ,
.
, , , Git
. :
Git, ,
. -
, . Git
.1.12.
, , , ,
. , Git
,
. -
, : , -
Goodbye, World!
. Git -
.

.
? , Git
. -
. .1.13
Git, .
38 1.

. 1.12. Git

. 1.13. Git

Git ,
, -
-. ,
Git, -
.

, , .
-, ,
39

, -
, .
Firefox, Safari Chrome.
,
. Google
Chrome.
Chrome. Windows, Mac OS Linux,
Google Chrome, -. ,
, , . -
Chrome , ,
.1.14.

. 1.14. Chrome


- -
. -
: ,
. Sublime Text ,
. Git
.
Chrome -.
,
. .1.1 1.2,
Git
.
40 1.

1.1. UNIX

pwd
ls
ls -a ,
cd [dir] [dir]
mkdir [dir] [dir]

1.2. Git

git init
git status
git add [file(s)] (-) [file(s)]
git commit m [msg] -
[msg ]
git log

.
, , -
. : , , , -
, ,
. , ,
, -
!

, ,
, .
Git UNIX.
, , -
.
1. .
2. .
3. index.html
.
4. Git .
5. .
?
: .
41

,
.

Sublime Text
, ,
, . -
Sublime ,
, .
Sublime.

Emacs Vim
- -
. , -
,
. Emacs Vim , -
,
. ,
, , , Vim --
(, : Emacs).
GNU Emacs,
. OReilly
Emacs Vim, Learning the vi and Vim Editors ( vi
Vim) , ,
Learning GNU Emacs ( GNU Emacs) ,
, , .
,
:
;
, ;
;
;
;
.
, ,
.

UNIX
UNIX,
, , . ,
42 1.

, ,
, .
Google, : cp, mv,
rm, rmdir, cat less. .

Git
Git . -
. , Pro Git (Apress, 2009)
, Git. -
,
, , -
.
.
, .
,
Git.

GitHub
GitHub -, Git.
(open source), . -
Git, $7 . -
Git GitHub.
GitHub GitHub
Git.
Git, GitHub. , .
2


: HTML CSS.
, , -
HTML CSS ,
.
.
HTML CSS, , -
4, JavaScript .
,
.

, HTML!
HTML, Hyper Text Markup Language ( -
), , -
( ) --
. ?
.
Chapter2 ( 2)
Projects. , mkdir.
Sublime Text File -
. hello.html . -
, :
<!doctype html>
<html>
<head>
<title> -</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
44 2.


, , ,
. -
Hello, World!. , <html>
<head>, , .
, -
.
, Open File
( ) File (). .2.1.

. 2.1. hello.html, Chrome

,
. Chrome
Command+O, Mac. Windows Ctrl+O.

, , .
- ,
Hello, World! .

<p>: a
, Lorem ipsum
,
, HTML! 45

. - Lorem
ipsum1:
<!doctype html>
<html>
<head>
<title> -</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.</p>
</body>
</html>

, .
,
Chrome. ,
(.2.2).

. 2.2. hello.html, Chrome

1
lorem ipsum,
. , UTF-8,
. . .
46 2.

, Ctrl+R Windows
Command+R Mac OS.

--
. , ,
, .

HTML.
<!-- -->. , -
:
<!doctype html>
<html>
<head>
<title> </title>
</head>
<body>
<!-- -->
<h1>Hello, World!</h1>
<!-- -->
<p> , , - h1,
!</p>
</body>
</html>

,
, . -
HTML , , -
HTML .

, ... !
,
?
<h1>, <h1>, <h2>, <h3>, <h4>, <h5> <h6>.

. -
<h1>, -
:
<!doctype html>
<html>
<head>
<title> </title>
, HTML! 47

</head>
<body>
<!-- -->
<h1> !</h1>
<!-- ,

-->
<p> </p>
<h2> </h2>
<p> - </p>
</body>
</html>

HTML- <a>, anchor ()


.
,
-. , HTML
href, , -
. href :
<!doctype html>
<html>
<head>
<title> </title>
</head>
<body>
<!--
href ,
-->
<p> <a href="http://www.google.com"></a> Google!</p>
<p>
<a href="http://www.example.com">

</a>
</p>
<p>

<a href="http://www.facebook.com">www.facebook.com</a>
</p>
</body>
</html>

- , .2.3.
,
, href.
-
, . -
? , , ! <ol> <ul>
(ordered) (unordered) -
:
48 2.

. 2.3. <a>

<!doctype html>
<html>
<head>
<title> </title>
</head>
<body>
<h1> !</h1>
<!-- ul -->
<ul>
<li>
<a href="http://www.google.com"></a> Google!
</li>
<li>
<a href="http://www.example.com">

</a>
</li>
<li>

<a href="http://www.facebook.com">
www.facebook.com
</a>
</li>
</ul>
<!-- -->
<h3> </h3>
<ol>
<li> ol</li>
, HTML! 49

<li> li</li>
<li> ol</li>
</ol>
</body>
</html>


.2.4.

. 2.4.


, . -
, HTML-.
-, , , , , , -
. , HTML
.
, , - .
, <head> <body> <html>, <h1> <p>,
, <body>. -
, , -
. HTML .
, : ,
HTML- -
, , .
,
50 2.

. Lorem ipsum
, .

,

. Windows Linux -
Ctrl+Tab , Ctrl+R -
. Mac OS Command+Tab Command+R.

HTML ,
(Document Object Model (DOM)). DOM
, HTML, -
, JavaScript. HTML -
DOM , .
HTML ,
DOM. , -
, . ,
, . HTML:
<!doctype html>
<html>
<head>
<title>!</title>
</head>
<body>
<h1>!</h1>
<div>
<ol>
<li> </li>
<li> </li>
<li> </li>
</ol>
<p> </p>
<p> <span></span> .</p>
</div>
<ul>
<li> <span>1</span></li>
<li> <span>2</span></li>
<li> <span>3</span></li>
</ul>
</body>
</html>
HTML 51

, ,
: . ,
: ,
. , span -
, li. ,
<span> , -
, . ,
.

. ,
DOM!
, DOM
JavaScript. -
(.2.5).
DOM. ,
:
DOM, , ,
, , .
, , -
, .
html, ul
body. ul head,
, head
ul . ul
( li), li
span.
,
DOM .

HTML

, HTML-
. <html>, -
</html>. DOM,
.
, -
. , HTML-, -
,
:
<!doctype html>
<html>
<head>
52

. 2.5. , DOM
2.
HTML 53

<title> -</title>
</head>
<body>
<h1>!</h1>
<nav>
<div></div>
<div></div>
<div> </div>
</nav>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmodtempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, <span>quis
nostrud exercitation</span> ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim <span>ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate <span>velit esse cillum dolore eu
fugiat</span> nulla pariatur.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</p>
</body>
</html>

HTML- , ,
. , , .
? ! , -
. , <span>,
. ,
. ,
HTML-.
, , -
. -
Java C++, , ,
. , ,
. HTML ,
,
, .
,
, <span> ?
, ,
, HTML. HTML-
.
-
. W3Cs Markup
Validation Service validator.w3.org. ,
.2.6.
54 2.

. 2.6. W3Cs Markup Validation Service

, , Validate by Direct Input. , -


HTML- .
Check.
Lorem ipsum, .
, - .2.7.

. 2.7. W3C HTML Lorem ipsum


HTML 55

HTML, , , ,
. , HTML5.
HTML5 ,
, .
-
. ,
, HTML--
.

, .
,
span , .2.8.

. 2.8. W3C HTML

, . -
, , ,
. .2.9 , .
- HTML-,
. ,
HTML .
, .
56 2.

. 2.9. W3C HTML

Amazeriffic
HTML --
. :
, , -
HTML .


Amazeriffic, amazing
terrific . , , ,
, -
. Amazeriffic
( , ).
, ,
HTML, . ,
, .2.10.
, HTML . , ,
( ,
), ,
HTML .
.
Amazeriffic 57

. 2.10. Amazeriffic,

, ,
. -
,
, . ,
, ,
, .
.2.11 , -
. ,
. ,
, DOM,
, HTML-.
. , ,
, , , , -
, , , -
. - .

,
. , -
, . .2.12
.
58 2.

. 2.11. Amazerrific,


, ( ,
), HTML, ,
. ,
, .
- , .
, 1, Projects -
( Mac OS Linux) Documents ( -
Windows). Trminal application
Mac OS Git Bash Windows. cd:
hostname $ cd Projects

, Amazeriffic.
? ! mkdir:
hostname $ pwd
/Users/semmy/Projects
hostname $ mkdir Amazeriffic

,
, , -
cd:
Amazeriffic

. 2.12. Amazeriffic
59
60 2.

hostname $ ls
Amazeriffic
hostname $ cd Amazeriffic

, ( -
pwd).
. Git git
init:
hostname $ git init
Initialized empty Git repository in /Users/semmy/Projects/Amazeriffic/.git/

,
, - ! Sublime,
Amazeriffic, , -
.
HTML-,
New File. -
, , index.html.
, . -
Hello, World!, - -
.
, , Chrome
. , Hello, World!.
HTML- . -
Hello, World! index.html :
<!doctype html>
<html>
<head>
<title>Amazeriffic</title>
</head>
<body>
<h1>Amazeriffic</h1>
</body>
</html>

. ,
.2.13.
, .
. , -
index.html:
hostname $ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
Amazeriffic 61

. 2.13. Amazeriffic

#
# index.html1
hostname $ git add index.html
hostname $ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: index.html2
hostname $ git commit -m "Add default index.html to repository."
[master (root-commit) fd60796] Add default index.html to the repository.
1 file changed, 10 insertions(+)
create mode 100644 index.html3
, . -
. ,
, , .
, , index.html.

1
: -. .
( "git add <file>..."
): index.html. . .
2
: -. .
( "git rm cached <file>" ):
index.html. . .
3
: 1 , 10 (+). 100644 in
dex.html. . .
62 2.

index.html , , -
git status. , git commit.
, git commit, .
- -
. , , -
, .
body. HTML
. <header> <footer> ,
, <main>
, :
<!doctype html>
<html>
<head>
<title>Amazeriffic</title>
</head>
<body>
<header>
<h1>Amazeriffic</h1>
</header>
<main>
</main>
<footer>
</footer>
</body>
</html>
: <h1>, Amazeriffic,
. , -
.
,
, , .
: HTML -
, nav. <header>:
<header>
<h1>Amazeriffic</h1>
<nav>
<a href="#"></a> |
<a href="#"></a> |
<a href="#"></a>
</nav>
</header>

: nav , |.
, Enter,
. Shift, .
Amazeriffic 63

nav <a>. , <a>


href, ,
, .
, #
, .
<header>,
Git. git status,
. git add git commit
- , .


<header> <main>. -
, , .
, , .
, .
,
. (<h2> <h3>),
, <h1>. <p>,
. , <ul>, -
, <li> .
, : <img>,
. , <img>
. , HTML5
, (void). -
- , , -
.
, , <img> alt.
. -
, -
.

http://www.learningwebappdev.com/
lightbulb.png. ,
, index.html.

<main>
:
<h2>Amazeriffic !</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<h3> Amazeriffic?</h3>
<ul>
64 2.

<li> </li>
<li> </li>
<li> </li>
</ul>
<img src="lightbulb.png" alt=" ">

,
. ,
Git, .


, , .
, ,
. , .
, HTML -
. , HTML -
, <div> <span>, -
, .
div span .
:
. , <div>,
class, .
, class , -
<div> <span>.
, <ul>
. HTML
:
<footer>
<div class="contact">
<h5> </h5>
<p>Amazeriffic!</p>
<p>555 50- </p>
<p>, 28801</p>
</div>
<div class="sitemap">
<h5> </h5>
<ul>
<li><a href="#"></a></li>
<li><a href="#"> </a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
</ul>
</div>
</footer>
65

HTML-, HTML--
, , Git
.
3, -
.



HTML. HTML ,
,
(Document Object Model (DOM)). DOM -
.
DOM
. DOM
, : ,
.
,
HTML.
, .2.1.
,
<div>. <div> class,
.
2.1. HTML

<html> HTML-
<head>
<body> ,
<header>
<h1> ( )
<h2>
<h3>
<main>
<footer> ( )
<a> ,
<ul> , ()
<ol> , ()
<li> ()
<div>


Amazeriffic .
, . :
66 2.

- , -
HTML GitHub.

HTML,
. , ,
.
1. Chrome, .
2. index.html , <!doctype> , <html> , <head>
<body>.
3. <p>, Hello, World!.
4. Chrome , (
, ).
5. Git .
6. <body> <header>, <main> <footer>.
7. , Chrome.
8. HTML-.
9. index.html Git.


HTML-.
4 5:
<!doctype html>
<html>
<head>
</head>
<body>
<h1>!</h1>
<h2 class="important">Hi again</h2>
<p class="a"> </p>
<div class="relevant">
<p class="a"></p>
<p class="a"></p>
<p></p>
<p></p>
<p class="a"></p>
<p class="a"></p>
<p></p>
</div>
</body>
</html>
67

(FAQ) Amazeriffic
Amazeriffic (
), .
, ,
. Lorem ipsum (, ,
).
faq.html. -
href <a>, faq.html.
, ,
, . -
index.html faq.html.

HTML
Mozilla Developer Network
documentation .
HTML.
.
3

HTML- -
. -
.
, ,
HTML-
(Cascading Style Sheets (CSS)). ,
CSS,
, .

, CSS!
, HTML-, -
.
hapter3 ( 3) Projects.
Sublime Text Chapter3 , -
. HTML-
index.html:
<!doctype html>
<html>
<head>
<title> -</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1> !</h1>
<p> .</p>
</body>
</html>

HTML h1 p,
body. , , ,
<head>. <link> ,
.
, CSS! 69

style.css Sublime -
. :
body {
background: lightcyan;
width: 800px;
margin: auto;
}
h1 {
color: maroon;
text-align: center;
}
p {
color: gray;
border: 1px solid gray;
padding: 10px;
}

CSS.
body - (lightcyan) , ,
h1, - (maroon). ,
body 800 auto,
body . ,
, p,
.
, CSS , HTML
. , .3.1 , HTML
CSS.

. 3.1. index.html, Chrome

CSS, ,
.3.2.
70 3.

. 3.2. index.html, Chrome

index.html style.css ,
, .3.1.
HTML
CSS,
, . CSS

!


CSS , -
, -
DOM ( ,
HTML-). , -
, , , -
. ,
, ( ,
), , :
body {
width: 800px;
background: lightcyan;
color: #ff0000;
}

, DOM body.
body, HTML,
. -
body, , .
, CSS! 71

: width (), -
background (), color ().

CSS .
CSS . .
(09 AF).
, , -
. RGB.

CSS ,
- ,
. , , -
HTML.

CSS . HTML, -
CSS , -
. ,
:
/* body */
body {
width: 800px; /* body 800 */
background: lightcyan; /* - */
color: #ff0000; /* */
}

. -
, ,
, .
CSS, ,
, , ,
. , ,
, .
CSS, -
.
, .

,
HTML . -
, , , span.
, , -
, :
72 3.

<div>
<span></span> .
<a href="http://www.example.com"></a> .
</div>

body index.html,
, .3.3.

. 3.3.

, . ,
, ,
. , ,
p, nav, main div:
<div>
<div></div> .
<a href="http://www.example.com"></a> .
</div>

(.3.4).

. 3.4. ,
, CSS! 73

,
.
, :
(padding), (border) (margin).

, . -
.
.3.5.

. 3.5. , DOM

,
, .
margin_border_padding.html:
<!doctype html>
<html>
<head>
<title> 3 , </title>
<link href="margin_border_padding.css" rel="stylesheet" type="text/css">
</head>
<body>
<div>
<p> , DIV</p>
</div>
</body>
</html>

margin_border_padding.css,
HTML . Sublime, -
margin_border_padding.html Chrome:
74 3.

body {
background: linen;
width: 500px;
margin: 200px auto;
}
div {
border: 5px solid maroon;
text-align: center;
padding: 5px;
}
p {
border: 2px dashed blue;
}

, ,
.3.6.

. 3.6. ,

, ( div, p)
, . ,
HTML CSS, . -
padding, border margin , ,
.

CSS .
,
. ,
HTML:
75

<body>
<h1>!</h1>
<p> .</p>
<p> .</p>
</body>

,
CSS:
h1 {
background: black;
color: white;
}
p {
color: red;
margin: 10px;
padding: 20px;
}

h1, p. -
.
.

2 , class <div>,
. -
DOM. , HTML -
:
<body>
<h1>!</h1>
<p class="first"> .</p>
<p class="second"> .</p>
</body>


:
h1 {
background: black;
color: white;
}
p.first {
color: red;
margin: 10px;
padding: 20px;
}

p.ruleset
p, .
76 3.

( ), -
:
.first {
color: red;
margin: 10px;
padding: 20px;
}

2 , DOM -
<a>:
<body>
<a href="http://www.example.com">Click Me!</a>
</body>

, -
DOM, CSS. , CSS,
:
a {
color: cornflowerblue;
}

,
. CSS
:
a {
color: cornflowerblue;
}
a:visited {
color: tomato;
}

visited CSS a.
, ,
, . ,
.
CSS
, .
hover a.
,
, :
a {
color: cornflowerblue;
text-decoration: none; /* */
}
77

a:visited {
color: tomato;
}
a:hover {
text-decoration: underline;
}


DOM
. , , HTML:
<body>
<h1>!</h1>
<div class="content">
<ol>
<li> <span class="number"></span></li>
<li> <span class="number"></span></li>
<li> <span class="number"></span></li>
</ol>
<p> <span></span> .</p>
<p> <span> </span> .</p>
</div>
<ul>
<li> <span class="number">1</span></li>
<li> <span class="number">2</span></li>
<li> <span class="number">3</span></li>
</ul>
</body>

HTML- , , .
,
. ,
(ol), :
ol {
border: 5px solid darksalmon;
border-radius: 10px;
}

, -
. :
li {
color: brown;
}

-
, .
li :
78 3.

ol li {
color: brown;
}
,
. ,
li, div content:
.content li {
color: brown;
}
, -
. first-child,
:
li:first-child {
background: yellow;
}
, -
ntn-child:
li:nth-child(2) {
background: orange;
}


,
HTML? , , p -
greeting:
<p class="greeting"> !</p>
,
:
p {
color: yellow;
}
p.selected {
color: green;
}
? -
, , -
. () -
. , - :
p {
color: yellow;
}
79

p {
color: green;
}

, CSS -
. , .
, .

, .
?
- , DOM
, - . , -
, color body, , -
body ( , ),
. CSS
DOM
:
body {
background: yellow;
}
/**
* h1 body,
*
*/
h1 {
color: red;
}
/**
* h2 body,
* ,
*
*/
h2 {
background: green;
}

CSS- . ,
.
( , ,
):
body {
margin: 0;
padding: 0;
}
/**
80 3.

* h1 body,
*
*/
h1 {
}


, DOM.
, , -
. -

. float.
, , -
HTML .
DOM float left
right. ( ,
, )
- , -
, . , HTML:
<body>
<main>
<nav>
<p><a href="link1"> 1</a></p>
<p><a href="link2"> 2</a></p>
<p><a href="link3"> 3</a></p>
<p><a href="link4"> 4</a></p>
</nav>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur.
</p>
</main>
</body>

nav p main. -
p , ,
( ).
(.3.7).
HTML CSS:
main {
width: 500px;
margin: auto;
81

. 3.7. CSS

background: gray;
}
nav {
/* , -
*/
/* border: 3px solid black; */
width: 200px;
float: right;
}
p {
margin: 0; /* */
}
.3.8.

. 3.8.
82 3.

, 200
, . ,
nav -
. p div, nav.
,
. !

, ,
, .
. p , -
.
CSS:
main {
width: 500px;
margin: auto;
background: gray;
}
nav {
width: 100px;
float: right;
}
/* p, nav */
nav p {
margin: 0;
padding: 0;
}
p {
margin: 0; /* */
float: left;
width: 400px;
}
, , ,
, . , , , -
, ,
. div
overflow auto:
main {
width: 500px;
margin: auto;
background: gray;
overflow: auto;
}
, .3.9.
, -
, 500, -
div. , - , ,
83

, . ,
p . ,
20 , - .3.10.

. 3.9.

. 3.10.

, main .
,
( 10). CSS
:
84 3.

main {
width: 500px;
margin: auto;
background: gray;
overflow: auto;
}
nav {
width: 100px;
float: right;
}
p {
margin: 0; /* p */
padding: 10px;
float: left;
width: 380px; /* 400 2*10 = 380 */
}

clear

. HTML.
, -
.
<body>
<nav>
<p><a href="link1"> 1</a></p>
<p><a href="link2"> 2</a></p>
<p><a href="link3"> 3</a></p>
<p><a href="link4"> 4</a></p>
</nav>
<main>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur.
</p>
</main>
<footer>
<p> </p>
</footer>
</body>

CSS- nav -
,
85

DOM.
(. 3.11):
* {
margin: 0;
padding: 0;
}
nav {
float: left;
background:darkgray;
}
main {
background:lightgray;
}
footer {
background:gray;
}

. 3.11. : main,

, , .
, .
clear. footer
, , , -
, clear. CSS
:
footer {
background:gray;
clear: both; /* 'clear: left'*/
}

.3.12
, .
-
CSS, -
.
86 3.

. 3.12. , clear


-
, , -
. - ,
, -
. Google , -
.
Google Fonts (.3.13).
.
, Denk One.
Google Fonts, -
. , Quick-use ( -
) ,
Add to Collection.
, -
. <link> head HTML.
, <link>
:
<head>
<title>Amazeriffic</title>
<!-- -->
<link href="http://fonts.googleapis.com/css?family=Denk+One"
rel="stylesheet" type="text/css">
<link href="style.css" rel="stylesheet" type="text/css">
</head>
87

. 3.13. Google Fonts1

HTML ('), (") -


. -
, Google -
. ,
, .

- .
CSS. , Denk
One h1, font-family:
h1 {
font-family: 'Denk One', sans-serif;
}

(
<link>), ,
, . , ,
: Denk One, , ,
sans-serif, -
.

1
, Script:Cyrillic
( , Latin).
, , , , , .
. .
88 3.

( color
) , ?
, ,
.
,
.
, -
body , .
, CSS .
em:
body {
font-size: 100%; /* */
}
h1 {
font-size: xx-large; /* */
}
h2 {
font-size: x-large;
}
.important {
font-size: larger; /* ,
*/
}
.onePointTwo {
font-size: 1.2em; /* 1,2 */
}

100% -
, , -
. CSS -large
x-large ( x-small xx-small),
. ,
larger smaller,
.
,
em ( ) ,
. ,
body , , 12, -
1,5em 18.
, -
. , -
.
: -
, em -
, .
89

1,2 -
. .3.14 ,
.

. 3.14.


, CSS,
.
, -
? ,
CSS, -
. CSS (CSS reset) -
. .
CSS ? .
-. , , ,
. -
.
(*), . ,
,
.
, -
, .
, ,
. ,
CSS, , -
.
, -
link HTML.
reset.css
HTML:
90 3.

<head>
<title> 8 CSS</title>
<link rel="stylesheet" type="text/css" href="reset.css">
<link rel="stylesheet" type="text/css" href="style.css">
</head>

, , . HTML:
<body>
<h1> </h1>
<h3> </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.</p>
</body>

.3.15 , Chrome
.

. 3.15.

, h1 h3 .
p .
.
reset.css , HTML.
<head> HTML :
CSS Lint 91

<head>
<title> 8 CSS</title>
<link href="reset.css" rel="stylesheet" type="text/css">
</head>
, , .3.16.

. 3.16. ,

,
. , ,
: CSS ,
. , -
CSS-, -
, , (, ,
) .

CSS Lint

HTML, ,
CSS. ,
?
body {
background: lightblue;
width: 855px;
margin: auto;
h1 {
background: black;
color: white;
}
p {
color: red;
margin: 10px
padding: 20px;
}
92 3.

, ,
! , body
. .
, , , . ,
p. margin
.
HTML-, CSS Lint ,
. - W3C HTML,
- .
http://csslint.net ( .3.17),
CSS.

. 3.17. CSS Lint

CSS Lint , HTML,


2, ,
. ,
LINT! . -
. , Disallow universal selector (
) Performance (-
). ,
- CSS,
Lint .
CSS Lint ,
. , ,
, Google,
Chrome Developer Tools 93

. ,
CSS!


Chrome Developer
Tools
,
, . CSS
, , ,
. , Chrome -
, CSS,
HTML.
margin_border_padding.html Chrome.
View, Developer Developer Tools1. -
Chrome. -
Elements , -
.3.18.

. 3.18. Chrome,
margin_border_padding.html

1
: Chrome Tools (
)Developer Tools ( )
Ctrl+Shift+I. . .
94 3.

- HTML- ,
.
, , ,
HTML. , ,
, .
HTML-, , -
. -
HTML, ,
.
HTML, Elements,
HTML, , ,
, HTML-, .
2,
(, ), HTML,
Elements, , Chrome. ,
HTML-, <p> <html>, <header> <body>,
Chrome Elements
(.3.19). , - ,
Chrome, , .

. 3.19. div ,

CSS, HTML-
. div, .
Styles , ,
, ,
Amazeriffic! 95

. , - -
. - CSS,
, , -
. ,
Chrome, .3.19.
! ,
- .
, ,
CSS-. ,
, Sublime CSS.
, , , -
, . Elements
. , -
. ,
Chrome , -
HTML- CSS-.

Amazeriffic!
.
, Amazeriffic.
HTML, , :
<!doctype html>
<html>
<head>
<title>Amazeriffic</title>
</head>
<body>
<header>
<h1>Amazeriffic</h1>
<nav>
<a href="#"></a> |
<a href="#"></a> |
<a href="#"></a>
</nav>
</header>
<main>
<h2>Amazeriffic !</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<h3> Amazeriffic?</h3>
<ul>
<li> </li>
<li> </li>
<li> </li>
</ul>
<img src="lightbulb.png" alt=" ">
96 3.

</main>
<footer>
<div class="contact">
<h5> </h5>
<p>Amazeriffic!</p>
<p>555 50- </p>
<p>, 28801</p>
</div>
<div class="sitemap">
<h5> </h5>
<ul>
<li><a href="#"></a></li>
<li><a href="#"> </a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
</ul>
</div>
</footer>
</body>
</html>
, Git Amazeriffic.
, Amazeriffic
cd :
hostname $ cd Projects/Amazeriffic
ls, ,
git log, , 2. -
:
hostname $ ls
index.html
hostname $ git log
commit efeb5a9a5f80d861119f5761df789f6bde0cda4f
Author: Semmy Purewal <semmy@semmy.me>
Date: Thu May 23 1:41:52 2013 -0400
Add content and structure to footer
commit 09a6ea9730521ed1effd135a243723a2745d3dc5
Author: Semmy Purewal <semmy@semmy.me>
Date: Thu May 23 12:32:17 2013 -0400
Add content to main section
commit f90c9a6bd896d1a303f6c3647a7475d6de9c4f9e
Author: Semmy Purewal <semmy@semmy.me>
Date: Thu May 23 11:45:21 2013 -0400
Add content to header section
commit 1c808e2752d824d815929cb7c170a04267416c04
Author: Semmy Purewal <semmy@semmy.me>
Date: Thu May 23 10:36:47 2013 -0400
Add skeleton of structure to Amazeriffic
commit 147deb5dbb3c935525f351a1154b35cb5b2af824
Amazeriffic! 97

Author: Semmy Purewal <semmy@semmy.me>


Date: Thu May 23 10:35:43 2013 -0400
Initial commit1
CSS-. -
reset.css, HTML .
( ) .
style.css, CSS.
, CSS- HTML,
:
<head>
<title>Amazeriffic</title>
<link rel="stylesheet" type="text/css" href="reset.css">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
Chrome.
- . , .3.20.

. 3.20. HTML Amazeriffic, CSS

1
: ,
main, header,
Amazeriffic, . . .
98 3.

Git:
hostname $ git add reset.css
hostname $ git add style.css
hostname $ git add index.html
hostname $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
# new file: reset.css
# new file: style.css
#
hostname $ git commit -m "Add reset.css and style.css, link in index.html"
[master b9d4bc9] Add reset.cssand style.css, link in index.html
3 files changed, 142 insertions(+), 2 deletions(-)
create mode 100644 reset.css
create mode 100644 style.css

Amazeriffic. ,
. ,
. ,
.
, -
.
, ,
. ,
-
. .3.21 3.22 Amazeriffiic
.
,
CSS, -
. -, -
.
, , -
, .
CSS.
, ( header, main footer)
width. , -
, . style.css
, :
header, main, footer {
min-width: 855px;
}
Amazeriffic! 99

. 3.21. Amazeriffic 1250650

. 3.22. Amazeriffic 800575


100 3.

min-width , ,
855 , . -
.
, .
, -
. ,
, header main -
.
body, -
. , ,
, body style.css . -
, body HTML- header, main, footer.
, -
:
body {
background: #f9e933;
}
header, main, footer {
min-width: 855px;
}

, , -
header main . ,
header main -
, min-width. ,
,
:
header {
background: white;
}
main {
background: white;
}

.3.23.

<main> Safari
. ,
main, display:
block;.

, - , -
Git. .
style.css.
add, .
Amazeriffic! 101

. 3.23. Amazeriffic c ()

? -
855.
, , 3 (
2:1 ). 855/3= 285,
.
. max-width -
main, header footer, body 855 ,
body auto.
, , .
, , , , -
,
- . ,
.
? , DOM
div, . ,
header main ,
855. HTML ,
102 3.

header, main footer conteiner,


. , div
header:
<header>
<div class="container">
<h1>Amazeriffic</h1>
<nav>
<a href="#"></a> |
<a href="#"></a> |
<a href="#"></a>
</nav>
</div>
</header>
,
855 . ,
:
body {
background: #f9e933;
}
header, main, footer {
min-width: 855px;
}
header .container, main .container, footer .container {
max-width: 855px;
margin: auto;
}
header {
background: white;
}
main {
background: white;
}
, , -
! -
Git.
, Git -
.


, , .
, , ,
285,
570. overflow auto,
, flow
.
Amazeriffic! 103

, :
header {
background: white;
overflow: auto;
}
header h1 {
float: left;
width: 570px;
}
header nav {
float: right;
width: 285px;
}
header - , -
h1 nav. footer main .
, , , , -
div ,
.
. -
, .
- :
header, , .
Git.
CSS Lint ( HTML-, HTML),
.
, .3.24.

. 3.24. Amazeriffic
104 3.

, ,
, CSS CSS Lint,
Git.


Google. -
Ubuntu Droid Sans. (<h1>, <h2>, <h3> <h4>)
Ubuntu, Droid Sans.
link HTML- -
CSS.
Git.
, 100%,
, -
, .
, -
HTML CSS Lint, -
. , Git.


, ,
.
. Chrome Developer Tools.
. -
, .
hover a.


CSS, -
. CSS ,
DOM.
: -
DOM, ,
, - -
. -
.
CSS
DOM CSS-.
DOM .

CSS float. CSS ,
105

.
, ,
, . ,
.
CSS Lint ,
CSS. ,
Chrome.


Amazeriffic , . -
, .

. ,
, .
1. style.css, -
, -
-.
2. style.css HTML- <head> ,
, .
3. style.css index.html Git.
4. header, main
footer , , .
5. .

CSS-
HTML
selectorpractice.html:
<!doctype html>
<html>
<head>
</head>
<body>
<h1>Hi</h1>
<h2 class="important"> </h2>
<p class="a"> </p>
<div class="relevant">
<p class="a"></p>
<p class="a"></p>
<p></p>
106 3.

<p></p>
<p class="a"></p>
<p class="a"></p>
<p>seventh</p>
</div>
</body>
</html>

CSS link. CSS


:
* {
color: red;
}

. ,
CSS-. * -
,
:
<h1>;
<h2> ;
relevant;
relevant;
relevant;
relevant;
;
;
;
relevant a;
(: ).
Mozilla (Mozilla developer documentation) -
. -
, .
, , -
.

Amazeriffic
2, (FAQ)
Amazeriffic. style.css faq.html -
,
. , -
. ,
main.
107


CSS . ,
.
CSS.
W3C. -
, CSS.


CSS, , .
,
, . ,
- - -
.
CSS , -
.
Mozilla . .
, CSS- -
. Twitter
Bootstrap, Zurbs Foundation.
CSS ,
Amazeriffic .
.
4

, -. -
, , - .
.
.
-
, .
- JavaScript -
, , jQuery
JavaScript, DOM (
). , JavaScript,
.

, JavaScript!
. , Projects
Chapter4. , Example1, Sublime.
: index.html, style.css app.js. index.html:
<!doctype html>
<html>
<head>
<title> </title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1> </h1>
<p> </p>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="app.js"></script>
</body>
</html>

, <script> -
body. link, script
, JavaScript! 109

HTML, script, ,
JavaScript. : <link>, <script>
.
<script> body, head :
, DOM-
HTML-. <script> , JavaScript
. -
,
, -
.
<script> -
jQuery, .
jQuery http://code.jquery.com . , -
jQuery . -
( -
Google Fonts ).
, .
script app.js,
JavaScript. .
CSS, ,
, . -
CSS Lint, .
* {
margin: 0;
padding: 0;
}

app.js .
. ,
, index.html .
var main = function () {
"use strict";
window.alert("hello, world!");
};
$(document).ready(main);

, JavaScript -
hello, world! (.4.1).
,
JavaScript. ,
, , :
, main,
;
main jQuery ,
HTML .
110 4.

. 4.1.

(strict), -
JavaScript, -
. main.
Hello, world! .


JavaScript - . -
, - ,
. -
, -
.
Example2 Chapter4.
Git Sublime. ,
(index.html, style.css app.js).
, ,
, .
,
Git.

, .
.4.2.
111

. 4.2.

, : header,
footer main. ,
HTML :
<!doctype html>
<html>
<head>
<title> </title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<header>
</header>
<main>
<!-- : css,
, , CSS -->
<section class="comment-input">
</section>
<section class="comments">
</section>
</main>
<footer>
</footer>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="app.js"></script>
</body>
</html>

HTML, -
Git. header footer
112 4.

main .4.2. , , ,
<h1>, <h2> <h3>
. .
comment-input HTML <input>. input
. -
<input> comment-input. -
:
<section class="comment-input">
<p> :</p>
<input type="text">
</section>

.comments .
. ,
:
<section class="comments">
<p> !</p>
<p> !</p>
<p> .</p>
<p> !</p>
</section>

, button +.
, ,
JavaScript. , <button>
<input>. , comment-input, :
<section class="comment-input">
<p>Add Your Comment:</p>
<input type="text"><button>+</button>
</section>

, Git, -
.

. CSS,
.
CSS, .
855,
. .
.
, , .
CSS ntn-child
even () odd (). , , -
lavender gainsboro, CSS:
113

.comments p:nth-child(even) {
background: lavender;
}
.comments p:nth-child(odd) {
background: gainsboro;
}
, ,
CSS.
, border-radius,
.
,
. , -
, Git, -
. , , -
Git.

.
, Git.


: +,
. app.js
:
var main = function () {
"use strict";
$(".comment-input button").on("click", function (event) {
console.log("Hello, World!");
});
};
$(document).ready(main);

Chrome, . Console
() . ,
+, Hello, World!, .
, ,
Git.
? DOM,
$. ,
$ CSS ! . jQuery
DOM CSS,
, JavaScript.
, button, .
, Hello, World!
114 4.

.
: +, Hello, World! .
, Hello, World! -
.
, , console.log
jQuery, DOM :
var main = function () {
"use strict";
$(".comment-input button").on("click", function (event) {
$(".comments").append("<p> </p>");
});
};
$(document).ready(main);

, , , ,
: . -
, jQuery ( $)
, CSS, -
HTML-. , ,
.

DOM
,
.
, . -
DOM, :
var main = function () {
"use strict";
$(".comment-input button").on("click", function (event) {
var $new_comment = $("<p>");
$new_comment.text(" ");
$(".comments").append($new_comment);
});
};
$(document).ready(main);

, ,
: .
, .
$new_comment , ,
jQuery, , $ .
jQuery,
.
jQuery , ,
, :
var $new_comment = $("<p>").text("this is a new comment");
115

jQuery , , -
,
.
, -
, . , , ,
input, .comment-input jQuery.
, CSS! :
$(".comment-input input");

CSS, .comment-input, -
input.
, .
, , . ,
jQuery ,
. val value ().
, :
$(".comment-input input").val();

! , -

. , :
var main = function () {
"use strict";
$(".comment-input button").on("click", function (event) {
var $new_comment = $("<p>"),
comment_text = $(".comment-input input").val();
$new_comment.text(comment_text);
$(".comments").append($new_comment);
});
};
$(document).ready(main);

,
val:
var $new_comment = $("<p>").text($(".comment-input input").val());

. ,
- , ,
. - ,
, ,
, Chrome ,
- . ,
- .
,
Git .
116 4.

. , ,
,
, .


, , , , , ,
!
, -
.
, : -
, jQuery DOM
p. - / -
, CSS.
, , -
. ,
, , .
, ,
! , ,
, .
, - ,
Elements Chrome.
Chrome Elements.
main .
, , -
, , .
? , -
, - .
if:
$(".comment-input button").on("click", function (event) {
var $new_comment;
if ($(".comment-input input").val() !== "") {
$new_comment = $("<p>").text($(".comment-input input").val());
$(".comments").append($new_comment);
}
})

!== ,
, , , , .
, if , ,
, .
, Git.


,
, .
117

, ,
. :
jQuery val, , -
. ,
, val:
$(".comment-input input").val("");
,
:
$(".comment-input button").on("click", function (event) {
var $new_comment;
if ($(".comment-input input").val() !== "") {
var $new_comment = $("<p>").text($(".comment-input input").val());
$(".comments").append($new_comment);
$(".comment-input input").val("");
}
});

Enter
, ,
Enter .
, , .
?
, -
. :
$(".comment-input input").on("keypress", function (event) {
console.log("hello, world!");
});

-
. ,
, . ,
:
, button.
, , Hello, World!
Chrome ,
- . , -
,
Enter. , -
, ,
. ?
:
$(".comment-input input").on("keypress", function (event) {
console.log(" keyCode " + event.keyCode);
});
118 4.

, keyCode .
camelCase ( , ):
, , ,
, .
+ keyCode
, keyCode. ,
keyCode, .
, - , -
keyCode, . ,
keyCode Enter. ,
if , Enter:
$(".comment-input input").on("keypress", function (event) {
if (keyCode === 13) {
console.log(" " + event.keyCode);
}
});

keyCode Enter. -
, ,
:
$(".comment-input input").on("keypress", function (event) {
var $new_comment;
if (event.keyCode === 13) {
if ($(".comment-input input").val() !== "") {
var $new_comment = $("<p>").text($(".comment-input input").val());
$(".comments").append($new_comment);
$(".comment-input input").val("");
}
}
});


, .
:
. , jQuery
, jQuery fadeIn.
, , ,
. DOM
hide. :
$(".comment-input button").on("click", function (event) {
var $new_comment;
if ($(".comment-input input").val() !== "") {
$new_comment = $("<p>").text($(".comment-input input").val());
$new_comment.hide();
$(".comments").append($new_comment);
119

$new_comment.fadeIn();
$(".comment-input input").val("");
}
});

. ,
.
,
Enter, , , -
.


( ) app.js :
var main = function () {
"use strict";
$(".comment-input button").on("click", function (event) {
var $new_comment;
if ($(".comment-input input").val() !== "") {
$new_comment = $("<p>").text($(".comment-input input").val());
$new_comment.hide();
$(".comments").append($new_comment);
$new_comment.fadeIn();
$(".comment-input input").val("");
}
});
$(".comment-input input").on("keypress", function (event) {
var $new_comment;
if (event.keyCode === 13) {
if ($(".comment-input input").val() !== "") {
$new_comment = $("<p>").text($(".comment-input input").val());
$new_comment.hide();
$(".comments").append($new_comment);
$new_comment.fadeIn();
$(".comment-input input").val("");
}
}
});
};
$(document).ready(main);

, , , . , , -
, , -
, ,
. -
, DRY, Dont Repeat Yourself ( ).
, -
: , , -
? :
120 4.

var main = function () {


"use strict";
var addCommentFromInputBox = function () {
var $new_comment;
if ($(".comment-input input").val() !== "") {
$new_comment = $("<p>").text($(".comment-input input").val());
$new_comment.hide();
$(".comments").append($new_comment);
$new_comment.fadeIn();
$(".comment-input input").val("");
}
};
$(".comment-input button").on("click", function (event) {
addCommentFromInputBox();
});
$(".comment-input input").on("keypress", function (event) {
if (event.keyCode === 13) {
addCommentFromInputBox();
}
});
};
$(document).ready(main);

,
.
.
, : -
, !

jQuery
, , , - !
jQuery.
, .
jQuery :
DOM;
DOM;
AJAX.
, . -
, jQuery ,
.


, -
. HTML, CSS
jQuery 121

JavaScript. , - -
.
HTML
; , : stylesheets (
), images ( ), javascripts ( ). ,
, .

. , HTML:
<!doctype html>
<html>
<head>
<link href="stylesheets/reset.css" rel="stylesheet">
<link href="stylesheets/style.css" rel="stylesheet">
</head>
<body>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="javascripts/app.js"></script>
</body>
</html>

: ,
, .

,
JavaScript. HTML CSS,
JavaScript .
: .
, ,
, CSS:
// ,
var a = 5; // ,
/* , ,
. , CSS. */

, jQuery
CSS. CSS
jQuery. , jQuery -
, :
$("*"); //
$("h1"); // h1
122 4.

$("p"); //
$("p .first"); // 'first'
$(".first"); // 'first'
$("p:nth-child(3)"); // ,

jQuery CSS .
jQuery ,
CSS . , CSS -
jQuery ( , .,
). -
, jQuery , CSS,
DOM
JavaScript. , -
jQuery.

DOM
DOM,
. jQuery .

DOM
DOM.
, HTML:
<body>
<h1> !h1>
<main>
</main>
<footer>
</footer>
</body>

, main footer . -
, .4.3.

. 4.3. DOM jQuery


jQuery 123

, $,
. ,
, :
// , jQuery , $
var $newUL = $("<ul>"); //
var $newParagraphElement = $("<p>"); //

, ,
HTML-. ,
:
$newParagraphElement.text(" ");

DOM
HTML:
<p> </p>

ul p DOM,
, ,
jQuery (.4.4).

. 4.4. ul p , DOM

, ,
, append jQuery. ,
footer,
:
$("footer").append($newParagraphElement);
124 4.

, , -
! .4.5.

. 4.5. DOM , p

DOM
, . , li
ul, :
// ,
var $listItemOne = $("<li>").text(" ");
var $listItemTwo = $("<li>").text(" ");
var $listItemThree = $("<li>").text(", ");
// ul,
$newUL.append($listItemOne);
$newUL.append($listItemTwo);
$newUL.append($listItemThree);
, -
(.4.6).
,
main.
, !
$("main").append($newUL);
DOM , .4.7.
DOM, jQuery -
. , -
,
:
jQuery 125

. 4.6. DOM, ul,

. 4.7. DOM, ,

var $footerFirstChild = $("<p>").text(" !");


$("footer").prepend($footerFirstChild);
126 4.

, appendTo prependTo,
:
//
$footerFirstChild.appendTo($("footer"));

Chrome
, DOM ,
.

DOM
, jQuery
. remove ,
DOM :
// ,
//
$("ul li:first-child").remove();

-
empty jQuery. , , ,
, :
//
//
$newUL.empty();

, fadeIn ,
. ,
fadeOut slideUp, ,
DOM!
// DOM
$("footer p").fadeOut();

fadeOut DOM, .
remove,
. ,
, , .



, . , -
on. ,
dbclick, ,
:
$(".button").on("dblclick", function () {
alert("! !");
});
jQuery 127

--
(event-driven) (asynchronous) .
? , , -
:
console.log(" ");
console.log(" ");
console.log(" ");

, , -
, ,
. - :
console.log(" ");
$("button").on("click", function () {
console.log(" , - ");
});
console.log(" ");

,
. ready, , DOM
. setTimeout -
, -
:
// jQuery, ,
// DOM .
// main
$(document).ready(function () {
console.log(" , ");
});
// , JavaScript,
//
setTimeout(function () {
console.log(" 3 ");
}, 3000);
// - ,
//
console.log(" ");

- ,
, , ,
setTimeout ready, . -
, . , -
, jQuery slideDown ,
- :
var main = function () {
"use strict";
// div
var $content = $("<div>Hello, World!</div>").hide();
128 4.

// body
$("body").append($content);
// 2
$content.slideDown(2000);
};
$(document).ready(main);

,
, . ,
- :
var main = function () {
"use strict";
// div
var $content = $("<div>Hello, World!</div>").hide();
var $moreContent = $("<div>Goodbye World!</div>").hide();
// body
$("body").append($content);
// 2
$content.slideDown(2000);
// body
$("body").append($moreContent);
//
$moreContent.fadeIn();
}
$(document).ready(main);

. , Goodbye,
World! ,
Hello, World!. , .
, .
, , , slideDown .
, , ,
! , jQuery

,
. , ,
:
var main = function () {
"use strict";
// div
var $content = $("<div>Hello, World!</div>").hide();
var $moreContent = $("<div>Goodbye, World!</div>").hide();
// body
$("body").append($content);
// 2 ,
// ,
//
$content.slideDown(2000, function () {
JavaScript 129

// body
$("body").append($moreContent);
//
$moreContent.fadeIn();
});
};
$(document).ready(main);

, . -
, ,
:
$("footer p").fadeOut(1000, function () {
// , p
//
$("footer p").remove();
});


Node.js,
.

JavaScript

HTML CSS, jQuery, -
DOM.
-
. JavaScript
,
-.
JavaScript.
.
, , .

JavaScript
Chrome JavaScript Console
, ,
JavaScript. JavaScript -
Chrome!
-
, (
). Console
. , ,
.4.8.
130 4.

. 4.8. JavaScript Chrome

JavaScript. ,
, Enter :
5+2;
//=> 7
Math.random();
//=> 0.3896130360662937
console.log("hello, world!");
//=> hello, world!

7, 7.
0 1.
hello, world!, , -
: undefined ( ). : Chrome -
. console.log - -
, , Chrome
, .
JavaScript
Console . -, -
(, if for),
Enter Shift+Enter. -
:
var number = 5;
if (number >= 3) {
console.log(" 3!");
JavaScript 131

}
//=> 3!

, , -
( ,
).


JavaScript . ,
(, ,
..). Java C++, -
:
//
var message = " !";
//
var count = 1;
var pi = 3.1415;
//
var isFun = true;
console.log(message);
//=> !
console.log(pi);
//=> 3.1415
console.log(isFun);
//=> true

,
. , -
. ,
:
var main = function () {
"use strict";
var message = "hello, world!",
count = 1,
pi = 3.1415,
isFun = true;
console.log(message);
};

. , C++
Java, . ,
,
(
):
132 4.

//
// sayHello
var sayHello = function () {
console.log("hello, world!");
}
// , sayHello
sayHello();
//=> "hello, world!"
, JavaScript .

. -
return:
// add,
// : num1 num2,
// :
//
var add = function (num1, num2) {
// sum
var sum = num1 + num2;
//
return sum;
}
// add 5 2
add(5,2);
//=> 7

, JavaScript
,
.
,
. , main -
ready jQuery:
// main
var main = function () {
"use strict";
console.log("hello, world!");
};
// main , DOM
$(document).ready(main);

++ , , -
. ,
, Java , -
.
,
. ,
.
JavaScript 133

, ,
if. , -
, :
var count = 101;
if (count > 100) {
console.log(" count 100");
}
//=> the count is bigger than 100
count = 99;
if (count > 100) {
console.log(" count 100");
}
//=>

else - , :
var count = 99;
if (count > 100) {
console.log(" count 100");
} else {
console.log(" count 100");
}
//=> count 100

-
. if else if:
var count = 150;
if (count < 100) {
console.log(" count 100");
} else if (count <= 200) {
console.log(" count 100 200 ");
} else {
console.log(" count 200");
}
//=> count 100 200

, . -
&& ( ), || ( ) ! ()
( 2, | -
Enter Shift,
, ):
// , **
if (cardRank === "" || cardRank === "" || cardRank === "") {
console.log(" !");
} else {
console.log(" !");
}
134 4.

// ,
if (cardRank === "" && cardSuit === "") {
console.log(" !");
} else {
console.log(" , ");
}
// , **
// !
if (!(cardRank === "ace" && cardSuit === "")) {
console.log(" !");
}

JavaScript , ,
true false,
. .

- . ,
, 100 . , -
:
console.log(0);
console.log(1);
console.log(2);
// ...
console.log(99);
console.log(100);

! ,
100 :
var num; // ,
// 101 ,
for (num = 0; num <= 100; num = num + 1) {
console.log(num);
}

, ,
. for.
for . ,
for. (initialization
statement), (continuation condition) -
(update statement). , ,
. ,
. ,
JavaScript 135

.
( ).
for -
100:
var i;
// : i 0
// : , i 100
// : 2 i
// : i
// , ,
// 98
for (i = 0; i < 100; i = i + 2) {
console.log(i);
}
// : i 0
// : , i 100
// : 2 i
// i, 2 0
// , 0 98
for (i = 0; i < 100; i = i + 1) {
if (i%2 === 0) {
console.log(i);
}
}

(%), -
. , 5%2 1, 5/2 2
1 . ,
2 ( ). ,
. , -
, -
(. FizzBuzz ).
while dowhile Java C++, , JavaScript
. ,
for ( forEach ).

, .
JavaScript.
,
. :
var greetings = ["", "", "", "", ""];
//

: -
, , .
136 4.

, .
, :
var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];

-
. -
0 1 ,
:
console.log(greetings[1]);
//=> ''
console.log(greetings[0]);
//=> ''
console.log(primes[4]);
//=> 11
console.log(greetings[4]);
//=> ''

:
greetings[3] = ""; // "" ""

, ?
length
for:
var index;
for (index = 0; index < greetings.length; index = index + 1) {
console.log(greetings[index]);
}

, JavaScript, -
, Java. JavaScript , ,
. forEach, -
:
// forEach loop
//
greetings.forEach(function (element) {
console.log(element);
});

, -
, index, . ,
.
forEach JavaScript
C++ Java. -,
. -,
, - . ,
.
push:
JSLint 137

//
var cardSuits = [];
cardSuits.push("");
console.log(cardSuits);
//=> [""]
cardSuits.push("");
console.log(cardSuits);
//=> ["", ""]
cardSuits.push("");
console.log(cardSuits);
//=> ["", "", ""]
cardSuits.push("");
console.log(cardSuits);
//=> ["", "", "", ""]
JavaScript ,
push. .
,
.
.
-
.

JSLint

HTML CSS, JavaScript, -
, .
, . ,
:
cardRank = "";
if (cardRank = "") {
console.log(" !");
} else {
console.log(" !");
}
//=> !
.
Google Chrome JavaScript ,
. cardRank :
cardRank = "";
if (cardRank = "") {
console.log(" !");
} else {
console.log(" !");
}
//=> !
138 4.

- . , if
, -
1. ,
(truthy) ,
, - :
= () === ().
, :
if (cardRank === "") {
console.log(" !");
} else {
console.log(" !");
}

. ,
CSS Lint JavaScript, JSLint.
JSLint .4.9.

. 4.9. JSLint

1
truthy falsy ,

. Habrahabr
. . .
JSLint 139

JSLint , .
, .4.10.

. 4.10. JSLint

, , ,
. JavaScript
,
. var.
, -
:
var cardRank = "";

, , -
. , . ,
.
console,
. var
, . JSLint,
console, alert... .
CSS Lint, JSLint -
, JavaScript, , .
- -
, (
Google), ,
JavaScript .
140 4.

Amazeriffic
. Amazeriffic

. , .
, (.4.11).

. 4.11. ,

,
(.4.12).

. 4.12. ,
Amazeriffic 141

,
(.4.13).

. 4.13.

Git , -

. , Git -
.
,
. ( HTML CSS)
. scripts stylesheets
.


main, .
HTML- :
<main>
<div class="container">
<div class="tabs">
<a href=""><span class="active"></span></a>
<a href=""><span></span></a>
<a href=""><span></span></a>
142 4.

</div>
<div class="content">
<ul>
<li> </li>
<li> </li>
<li> </li>
<li> LinkedIn</li>
<li> </li>
<li> </li>
</ul>
</div>
</div>
</main>
main,
3.
:
.tabs a span {
display: inline-block;
border-radius: 5px 5px 0 0;
width: 100px;
margin-right: 10px;
text-align: center;
background: #ddd;
padding: 5px;
}
: display -
inline-block. , span
(width), ,
. inline-block ,
span width, 100. -
, .
, .
,
, :
.tabs a span.active {
background: #eee;
}

JavaScript! , -
jQuery /javascripts/app.js script
body HTML.
app.js :
var main = function () {
"use strict";
Amazeriffic 143

console.log("hello, world!");
};
$(document).ready(main);

, , , ,
hello, world! JavaScript. .


, . ,
:
var main = function () {
"use strict";
$(".tabs a:nth-child(1)").on("click", function () {
//
$(".tabs span").removeClass("active");
//
$(".tabs a:nth-child(1) span").addClass("active");
// ,
$("main .content").empty();
// false,
return false;
});
$(".tabs a:nth-child(2)").on("click", function () {
$(".tabs span").removeClass("active");
$(".tabs a:nth-child(2) span").addClass("active");
$("main .content").empty();
return false;
});
$(".tabs a:nth-child(3)").on("click", function () {
$(".tabs span").removeClass("active");
$(".tabs a:nth-child(2) span").addClass("active");
$("main .content").empty();
return false;
});
};

, , DRY (
) . -
- . -
, . . .


, - ,
! , -
? ! ,
. .
, .
:
144 4.

var main = function () {


"use strict";
var makeTabActive = function (tabNumber) {
// tabNubmer
var tabSelector = ".tabs a:nth-child(" + tabNumber + ") span";
$(".tabs span").removeClass("active");
$(tabSelector).addClass("active");
};
$(".tabs a:nth-child(1)").on("click", function () {
makeTabActive(1);
return false;
});
$(".tabs a:nth-child(2)").on("click", function () {
makeTabActive(2);
return false;
});
$(".tabs a:nth-child(3)").on("click", function () {
makeTabActive(3);
return false;
});
};

, return false makeTabActive,


. -
, false,
.


, , ,
, . . -
, : 1, 2, 3.
for, ,
! .

makeTabActive, .
:
var main = function () {
"use strict";
var tabNumber;
for (tabNumber = 1; tabNumber <= 3; tabNumber++) {
var tabSelector = ".tabs a:nth-child(" + tabNumber + ") span";
$(tabSelector).on("click", function () {
$(".tabs span").removeClass("active");
$(this).addClass("active");
return false;
});
}
};
Amazeriffic 145


forEach
, ! jQuery ,
.
span , (click) :
var main = function () {
"use strict";
$(".tabs a span").toArray().forEach(function (element) {
//
$(element).on("click", function () {
$(".tabs a span").removeClass("active");
$(element).addClass("active");
$("main .content").empty();
return false;
});
});
};

, jQuery, DOM,
jQuery. jQuery, -
$().

, . , ,
, , , , (, -
, ), ,
.


. main .content
- , .
, , .tabs . -
, .tabs, , -
- . - ,
span,
.
.4.14.
, jQuery -
jQuery , parent. -
, . jQuery
is, -
jQuery. , ,
. :
146 4.

. 4.14. span,

// , jQuery $me
//
if ($me.parent().is(":first-child")) {
console.log(" !!");
} else {
console.log(" .");
}
:nth-child,
:
var main = function () {
"use strict";
$(".tabs a span").toArray().forEach(function (element) {
//
$(element).on("click", function () {
// jQuery,
// ,
//
var $element = $(element);
$(".tabs a span").removeClass("active");
$element.addClass("active");
$("main .content").empty();
if ($element.parent().is(":nth-child(1)")) {
console.log(" !");
} else if ($element.parent().is(":nth-child(2)")) {
console.log(" !");
} else if ($element.parent().is(":nth-child(3)")) {
console.log(" !");
}
return false;
});
});
};
Amazeriffic 147

JavaScript Chrome, -
, !
- !


.
.
main,
:
var main = function () {
"use strict";
var toDos = [
" ",
" ",
" ",
" ",
" ",
" "
];
//... ,
};

, , , ,
. , -
, . ()
, , () -
.
,
, -
. :
ul,
li . ,
,
for.
forEach.
:
$(element).on("click", function () {
var $element = $(element),
$content;
$(".tabs a span").removeClass("active");
$element.addClass("active");
$("main .content").empty();
if ($element.parent().is(":nth-child(1)")) {
console.log(" !");
} else if ($element.parent().is(":nth-child(2)")) {
$content = $("<ul>");
148 4.

toDos.forEach(function (todo) {
$content.append($("<li>").text(todo));
});
$("main .content").append($content);
} else if ($element.parent().is(":nth-child(3)")) {
console.log(" !");
}
})
,
. , , -
HTML, ! (trigger)
, main,
. :
$(".tabs a:first-child span").trigger("click");
, index.html
.
- input
button, ,
. DOM -
jQuery HTML.
. DOM,
, ToDo -
Push.
Git.


, -
jQuery JavaScript. jQuery ,
DOM ,
. - -
-,
. -
.
JavaScript ,
. - -

, , if if-else, -
.
, -
.
JSLint , CSS Lint HTML Validator,
JavaScript.
.
149

.
1. javascripts .js.
2. JS app.js.
hello, world!,
. main,
jQuery document.ready.
3. jQuery HTML
<body>.
4. Chrome , .
5. HTML Git.

jQuery
jQuery -
, , -
. http://plugins.jquery.com
, . , -
. ,
, , ,
.
colorbox. -
. -
.

jQuery
HTML selectorpractice.html:
<!doctype html>
<html>
<head>
</head>
<body>
<h1></h1>
<h2 class="important"> </h2>
<p> </p>
<div class="relevant"> //relevant (.)
<p class="a">first</p>
<p class="a">second</p>
150 4.

<p>third</p>
<p>fourth</p>
<p class="a">fifth</p>
<p class="a">sixth</p>
<p>seventh</p>
</div>
</body>
</html>

app.js . -
<script>, jQuery -
body:
var main = function () {
"use strict;"
$("*").css("color","red");
};
$(document).ready(main);

css jQuery.
CSS -
DOM . ,
. , -
<h1>, :
$("h1").css("color","red");

, -
jQuery . ,
, :not :gt.
1. h2 .
2. .
3. .
4. .
5. .
6. , .
7. .
8. , .
9. , .

FizzBuzz
, , -
FizzBuzz. ,

? (Why Cant Programmers Program?).
151

, , ,
.
: ,
1 100. , 3, Fizz, ,
5, Buzz. , 3, 5,
FizzBuzz.
for,
, . if-
else .
, -
- , ,
-
. , - -
, -
. - , , , ,
- . -
.


.
: -
, -
.
.
: , -
.
:
var sum = function (nums) {
var sumSoFar = 0,
i;
// ,
for (i = 0; i < nums.length; i++) {
sumSoFar = sumSoFar + nums[i];
}
// , ,
// sumSoFar
//
return sumSoFar;
};
sum([1,2,3,4]);
//=> 10
forEach:
var sum = function (nums) {
var sumSoFar = 0;
152 4.

// use a forEach loop


nums.forEach(function (value) {
sumSoFar = sumSoFar + value;
});
return sumSoFar;
};
sum([1,2,3,4]);
//=> 10

forEach , -
i. , -
,
. ,
, reduce,
:
var sum = function (nums) {
return nums.reduce(function (sumSoFar, value) {
return sumSoFar + value;
}, 0);
};
sum([1,2,3,4]);
//=> 10

reduce, -
, .
,
. , , ,
?
sum(5);
//=> TypeError!
sum("hello, world");
//=> TypeError!

,
. , , , ,
.
, -
.
1. , ,
.
2. , ,
.
3. , , true,
, false .
4. , , true,
, false .
153

5. , :
true, , false
. , :
arrayContains(["", ""], "");
//=> true
arrayContains(["", ""], "");
//=> false
arrayContains(["", "", ""], "");
//=> true

6. , , true -
, :
arrayContainsTwo(["a","b","a","c"], "a");
//=> true
arrayContainsTwo(["a","b","a","c"], "b");
//=> false
arrayContainsTwo(["a","b","a","c","a"], "a");
//=> true

,
arrayContainsThree, , .
, . ,
true, n ,
n :
arrayContainsNTimes(["a","b","a","c","a"], "a", 3);
//=> true
arrayContainsNTimes(["a","b","a","c","a"], "a", 2);
//=> true
arrayContainsNTimes(["a","b","a","c","a"], "a", 4);
//=> false
arrayContainsNTimes(["a","b","a","c","a"], "b", 2);
//=> false
arrayContainsNTimes(["a","b","a","c","a"], "b", 1);
//=> true
arrayContainsNTimes(["a","b","a","c","a"], "d", 0);
//=> true

(Project Euler)
(Project Euler).
,
. -
. , , -
, ,
.
IT- , -
.
154 4.

JavaScript
JavaScript , . -
, -
. , .
( ,
!).
, ,
JavaScript ,
. -
.
JavaScript: The Good Parts (OReilly, 2008),
JavaScript . ,
Effective JavaScript (Addison-Wesley, 2012) -
JavaScript
.
-
JavaScript, Maintanable JavaScript
(OReilly, 2012). - -
JavaScript, Functional JavaScript
(OReilly, 2013), , .
5


-. , -
, , -
. ,
, ,
.
-,
,
.
.
, JavaScript, JSON (JavaScript
Object Notation) AJAX (Asynchronous JavaScript And XML
). Node.js,
.

, JavaScript!
, -
JavaScript . , ,
- ,
++ Java, .

, - JavaScript
, , .
, ,
, .
.


. -
: (, , )
156 5.

( 2 10, , , ).
- .
JavaScript.
,
, ,
:
var cardOneSuit = "",
cardOneRank = "",
cardTwoSuit = "",
cardTwoRank = "",
cardThreeSuit = "",
cardThreeRank = "",
// ...
cardFiveSuitRank = "";
, , .
, , , ,
! , .
?
, :
var cardHandSuits = ["", "", "", "", ""],
cardHandRanks = ["", "", "", "", ""];
, :

. , -
, , -
, , .
, !
, -
. ,

(.). :
// "" 2 (two)
// (hearts)
var cardOne = { "rank":"", "suit":"" };
// cardOne
console.log(cardOne.rank);
//=>
// cardOne
console.log(cardOne.suit);
//=>
, . , -
suit rank cardOne:
//
cardOne.rank = "";
, JavaScript! 157

cardOne.suit = "";
console.log(cardOne);
//=> Object {rank: "", suit: ""}

, ,
:
//
var card = {};
//
card.rank = "";
console.log(card);
//=> Object {rank: ""}
//
card.suit = "";
console.log(card);
//=> Object {rank: "", suit: ""}

, ,
!
//
var cards = [];
//
cards.push( {"rank": "", "suit":""} );
cards.push( {"rank": "", "suit":""} );
cards.push( {"rank": "", "suit":""} );
cards.push( {"rank": "", "suit":""} );
cards.push( {"rank": "", "suit":""} );
//
console.log(cards[0]);
//=> Object {rank: "", suit: ""}
console.log(cards[2]);
//=> Object {rank: "", suit: ""}

,
:
//
//
var cards = [
{"rank": "", "suit":""},
{"rank": "", "suit":""},
{"rank": "", "suit":""},
{"rank": "", "suit":""},
{"rank": "", "suit":""}
]


, JavaScript
, .
158 5.

,
:
//
var s = {};

(.):
s.name = "";

, , -
,
:
s.age = 36; // ,
s.friends = [ "", "", "", "" ]; //
s.dog = { "name":"", "breed":" " };
/ */
console.log(s.age);
//=> 36
console.log(s.friends[1]);
//=> ""
console.log(s.dog);
//=> Object {name: "", breed: " "}
console.log(s.dog.name);
//=> ""

, , , -
, :
var g = {
"name": "",
"age": 36,
"friends": ["", "", "", ""],
"dog": {"name":"", "breed":" " }
}
console.log(g.name);
//=> ""
console.log(g.friends[2]);
//=> ""
console.log(g.dog.breed);
//=> " "

null,
:
var b = {
"name": "",
"age" : 45,
"friends" : [ "", "" ],
"dog" : null
}
159

. null
, :
// currentPerson g
var currentPerson = g;
// ... - currentPerson
// currentPerson null
currentPerson = null;

null , -
6, . , -
null ,
.
, -
. ,
, JavaScript -
, . , ,
, jQuery:
// DOM
var $headerTag = $("h1");
// $headerTag , ,
// fadeOut
$headerTag.fadeOut();

-
( - ), ,
, . -

-.


-,
. , -
Twitter.
Facebook.
,
. , - -
, JSON, , JavaScript,
, JSON!

JSON
JSON , JavaScript (
, ).
, , -
160 5.

, JavaScript, -
. AJAX -
, , -
!
, , JSON
, JavaScript:
{
"rank":"",
"suit":""
}
,
JSON , -
! JavaScript ,
.
JavaScript JSON,
. , Google Chrome
:
// JSON
var jsonString = '{"rank":"", "suit":""}'
// JSON.parse
var card = JSON.parse(jsonString);
console.log(card.rank);
//=> "ten"
console.log(card.suit);
//=> ""

, jsonString
. , JavaScript , -
, JSON .
, .

JSON
stringify:
console.log(JSON.stringify(card));
//=> {"rank":"ten","suit":""}
, , JSON
, ,
.

AJAX
AJAX Asynchronous JavaScript And XML (
JavaScript XML, , , ).
161

, JSON, XML HTML.


, XML - ,
JSON AJAX.
,
. AJAX
-.
( ) -
Google , Gmail, 10
! , , , ,
. ,
, . AJAX.

JSON
, , . AJAX . -
. CSS -
. ,
, Hello, World! c
h1 main. script
jQuery CDN ( 4), <script>,
app.js JavaScript.
javascripts :
var main = function () {
"use strict";
console.log("Hello, World!");
}
$(document).ready(main);

Chrome JavaScript.
, , Hello, World!.

cards. aceOfSpades.json,
JavaScript:
{
"rank" : "",
"suit" : ""
}

-
AJAX, .


JavaScript . -
, ,
162 5.

, . ,
, , ,
!
,
.
, JavaScript. JSON
: AJAX -
JSON, . ,
, -
Chrome.

. ,
, , -
.

Chrome , .
, Mac,
:
hostname $ open -a Google\ Chrome --args --allow-file-access-from-files

Windows, , -
, run , -
:
%userprofile%\AppData\Local\Google\Chrome\Application\chrome.exe
allow-file-access-from-files

, Chrome
, . ,

,
. , .

getJSON
Chrome
, JSON
. , jQuery,
getJSON. JavaScript, jQuery
, :
var main = function () {
"use strict";
// getJSON JSON,
// JSON.parse
$.getJSON("cards/aceOfSpades.json", function (card) {
163

//
console.log(card);
});
};
$(document).ready(main);

, , Chrome (
), , .
, , -
JavaScript:
var main = function () {
"use strict";
console.log("Hello, World!");
$.getJSON("cards/aceOfSpades.json", function (card) {
//
var $cardParagraph = $("<p>");
//
$cardParagraph.text(card.rank + " of " + card.suit);
// main
$("main").append($cardParagraph);
});
}
$(document).ready(main);

JSON
JSON. ,
, .
, hand.json:
[
{ "suit" : "", "rank" : "" },
{ "suit" : "", "rank" : "" },
{ "suit" : "", "rank" : "" },
{ "suit" : "", "rank" : "" },
{ "suit" : "", "rank" : "" }
]

getJSON :
var main = function () {
"use strict";
console.log("Hello, World!");
$.getJSON("cards/aceOfSpades.json", function (card) {
//
var $cardParagraph = $("<p>");
//
$cardParagraph.text(card.rank + " of " + card.suit);
// main
$("main").append($cardParagraph);
164 5.

});
$.getJSON("cards/hand.json", function (hand) {
var $list = $("<ul>");
// hand ,
// forEach
hand.forEach(function (card) {
//
//
var $card = $("<li>");
$card.text(card.rank + " of " + card.suit);
$list.append($card);
});
// main
$("main").append($list);
});
};
$(document).ready(main);

card forEach
JSON. , -
JSON.
JavaScript, , -
.

,
.5.1.

. 5.1. AJAX
Flickr 165

?
, . , -
, ,
. ?
, , .
.
, ! , ,
, Flickr.

Flickr
, CSS. Sublime -
Chapter5, Projects.
Flickr. javascripts stylesheets, -
app.js style.css. , app.js Hello, World!
JavaScript. index.html,
-.
! , !
, , - -
.
,
.
HTML-:
<!doctype html>
<html>
<head>
<title> Flickr</title>
<link rel="stylesheet" href="stylesheets/style.css">
</head>
<body>
<header>
</header>
<main>
<div class="photos">
</div>
</main>
<footer>
</footer>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="javascripts/app.js"></script>
</body>
</html>

jQuery,
http://api.jquery.com. ,
166 5.

. JavaScript -
Flickr, Yahoo! .
, :
http://api.flickr.com/services/feeds/photos_public.gne?tags=dogs&format=json.
JSON. , ,
:
jsonFlickrFeed({
"title": "Recent Uploads tagged dogs",
"link": "http://www.flickr.com/photos/tags/dogs/",
"description": "",
"modified": "2013-10-06T19:42:49Z",
"generator": "http://www.flickr.com/",
"items": [
{
"title": "Huck and Moxie ride stroller",
"link": "http://www.flickr.com/photos/animaltourism/10124023233/",
"media": {"m":"http://bit.ly/1bVvkn2"},
"date_taken": "2013-09-20T09:14:25-08:00",
"description": "...description string...",
"published": "2013-10-06T19:45:14Z",
"author": "nobody@flickr.com (animaltourism.com)",
"author_id": "8659451@N03",
"tags": "park dog beagle dogs brooklyn ride stroller prospect hounds"
},
{
"title": "6th Oct Susie: \"You know that thing you\'re eating?\"",
"link": "http://www.flickr.com/photos/cardedfolderol/10123495123/",
"media": {"m":"http://bit.ly/1bVvbQw"},
"date_taken": "2013-10-06T14:47:59-08:00",
"description": "...description string...",
"published": "2013-10-06T19:14:22Z",
"author": "nobody@flickr.com (Cardedfolderol)",
"author_id": "79284220@N08",
"tags": "pets dogs animal mammal canine"
},
{
"title": "6th Oct Susie ready to leave",
"link": "http://www.flickr.com/photos/cardedfolderol/10123488173/",
"media": {"m":"http://bit.ly/1bVvpXJ"},
"date_taken": "2013-10-06T14:49:59-08:00",
"description": "...description string...",
"published": "2013-10-06T19:14:23Z",
"author": "nobody@flickr.com (Cardedfolderol)",
"author_id": "79284220@N08",
"tags": "pets dogs animal mammal canine"
}
]
});
Flickr 167

, , , -
.
, items,
. , media,
m, . 2
, HTML- <img>
.
.
main, URL ,
jQuery getJSON , :
var main = function () {
"use strict";
// ,
//
//
var url = "http://api.flickr.com/services/feeds/photos_public.gne?" +
"tags=dogs&format=json&jsoncallback=?";
$.getJSON(url, function (flickrResponse) {
//
console.log(flickrResponse);
});
};
$(document).ready(main);

, , , , Flickr
-
. , -
.
, -
URL . , -
forEach:
$.getJSON(url, function (flickrResponse) {
flickrResponse.items.forEach(function (photo) {
console.log(photo.media.m);
});
});

, URL
! --
DOM. , jQuery
attr, . ,
src <img>:
$.getJSON(url, function (flickrResponse) {
flickrResponse.items.forEach(function (photo) {
// jQuery
var $img = $("<img>");
// URL,
168 5.

// Flickr
$img.attr("src", photo.media.m);
// img
// main.photos
$("main .photos").append($img);
});
});

, , Flickr!
URL - ( dog
), ! , -
jQuery:
$.getJSON(url, function (flickrResponse) {
flickrResponse.items.forEach(function (photo) {
// jQuery
//
var $img = $("<img>").hide();
// URL,
//
$img.attr("src", photo.media.m);
// main
// photos,
$("main .photos").append($img);
$img.fadeIn();
});
});


. ,
, .


Amazeriffic
, JavaScript JSON,
-
Amazeriffic.
.
, . -
JSON , -
.
Amazeriffic Chapter4 Chapter5.
: .
JSON, .
todos.json ( ,
index.html):
Amazeriffic 169

[
{
"description" : " ",
"tags" : [ "", "" ]
},
{
"description" : " ",
"tags" : [ "", "" ]
},
{
"description" : " ",
"tags" : [ "", "" ]
},
{
"description" : " ",
"tags" : [ "" ]
},
{
"description" : " ",
"tags" : [ "", "" ]
},
{
"description" : " ",
"tags" : [ "", "" ]
}
]

, JSON
, .
, .
, jQuery,
JSON. , main, , -
, , getJSON -
main. docu
ment.ready, getJSON, main
:
var main = function (toDoObjects) {
"use strict";
// main !
};
$(document).ready(function () {
$.getJSON("todos.json", function (toDoObjects) {
// main toDoObjects
main(toDoObjects);
});
});

: ,
. ,
170 5.

, . ,
, map.

map
map ,
. Chrome :
//
var nums = [1, 2, 3, 4, 5];
// map
//
var squares = nums.map(function (num) {
return num*num;
});
console.log(squares);
//=> [1, 4, 9, 16, 25]
, num*num,
. -
, , :
//
var names = [ "", "", "", "", "" ];
// ,
//
var capitalizedNames = names.map(function (name) {
//
var firstLetter = name[0];
//
// , 1
return firstLetter.toUpperCase() + name.substring(1);
});
console.log(capitalizedNames);
//=> ["", "", "", "", ""]
, ,
!
, , map,
:
var main = function (toDoObjectss) {
"use strict";
var toDos = toDoObjects.map(function (toDo) {
//
//
return toDo.description;
});
// !
// ...
};
$(document).ready(function () {
Amazeriffic 171

$.getJSON("todos.json", function (toDoObjects) {


// main
main(toDoObjects);
});
});
, , , -
.


.
() , .
index.html -
:
<div class="tabs">
<a href=""><span class="active"></span></a>
<a href=""><span></span></a>
<a href=""><span></span></a>
<a href=""><span></span></a>
</div>
-
. () , . -
, -
, , ,
. , , , ,
.
, , else-if -
, , .
, :
} else if ($element.parent().is(":nth-child(3)")) {
//
console.log(" ");
} else if ($element.parent().is(":nth-child(4)")) {
$input = $("<input>"),
$button = $("<button>").text("+");
$button.on("click", function () {
toDos.push($input.val());
$input.val("");
});
$content = $("<div>").append($input).append($button);
}


, , , ,
. .5.2.
172 5.

. 5.2.

,
, .
, .
, , , JSON -
. , toDoObjects -
, :
[
{
"name": "",
"toDos": [" "]
},
{
"name": "",
"toDos": [" ", " "]
},
{
"name": "",
"toDos": [" ", " "]
},
{
Amazeriffic 173

"name": "",
"toDos": [" ", "
"," ", " "]
},
{
"name": " ",
"toDos": [" "]
},
{
"name": "",
"toDos": [" "]
}
]

, toDoObjects -
map forEach!
-
. (
) -
organizedByTag:
} else if ($element.parent().is(":nth-child(3)")) {
//
console.log(" ");
var organizedByTag = [
{
"name": "",
"toDos": [" "]
},
{
"name": "",
"toDos": [" ", " "]
},
/* .. */
];
}

, -
.content, .
h3 ul li . ul li
, , .
h3 style.css, ,
:
} else if ($element.parent().is(":nth-child(3)")) {
//
console.log(" ");
var organizedByTag = [
/* ..*/
]
organizedByTag.forEach(function (tag) {
174 5.

var $tagName = $("<h3>").text(tag.name),


$content = $("<ul>");
tag.toDos.forEach(function (description) {
var $li = $("<li>").text(description);
$content.append($li);
});
$("main .content").append($tagName);
$("main .content").append($content);
});
}

.
, , ,
,
. .
.



,
, -
. organizeByTags,
, , :
[
{
"description" : " ",
"tags" : [ "", "" ]
},
{
"description" : " ",
"tags" : [ "", "" ]
},
/* .. */
]

, :
[
{
"name": "",
"toDos": [" "]
},
{
"name": "",
"toDos": [" ", " "]
},
/* .. */
]
Amazeriffic 175

,
:
} else if ($element.parent().is(":nth-child(3)")) {
//
console.log(" ");
var organizedByTag = organizeByTag(toDoObjects);
}


Chrome, ,
.
JavaScript,
, . -
, , .
, -
HTML, - . -
, , -
, HTML ,
:
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="test.js"></script>

, index.html test.js
:
var toDoObjects = [
{
"description" : " ",
"tags" : [ "", "" ]
},
{
"description" : " ",
"tags" : [ "", "" ]
},
/* etc */
];
var organizeByTags = function (toDoObjects) {
console.log("organizeByTags ");
};
var main = function () {
"use strict";
var organizeByTags = function () {
console.log("organizeByTags ");
};
organizeByTags(toDoObjects);
};
$(document).ready(main);
176 5.

organizeByTag ,
, .
, , -
. , , ,
, , . ,
.
, , -
. , -
, , .


. ,
, -
forEach. , -
map
, .
.
indexOf, . , -
, Chrome:
var nums = [1, 2, 3, 4, 5];
nums.indexOf(3);
//=> 2
nums.indexOf(1);
//=> 0
nums.indexOf(10);
//=> -1

: , -
( 0). -
, 1. :
var msgs = ["hello", "goodbye", "world"];
msgs.indexOf("goodbye");
//=> 1
msgs.indexOf("hello");
//=> 0
msgs.indexOf("HEY!");
//=> -1

, -
:
var organizeByTags = function (toDoObjects) {
//
var tags = [];
// toDos
toDoObjects.forEach(function (toDo) {
//
Amazeriffic 177

toDo.tags.forEach(function (tag) {
// ,
//
if (tags.indexOf(tag) === -1) {
tags.push(tag);
}
});
});
console.log(tags);
};

, .
, !
map:
var organizeByTags = function (toDoObjects) {
/* , */
var tagObjects = tags.map(function (tag) {
// ,
//
var toDosWithTag = [];
toDoObjects.forEach(function (toDo) {
// ,
// indexOf is ** -1
if (toDo.tags.indexOf(tag) !== -1) {
toDosWithTag.push(toDo.description);
}
});
// ,
//
return { "name": tag, "toDos": toDosWithTag };
});
console.log(tagObjects);
};

, ,
main , ! ,
, -
- .

, ,
, ,
? ,
.
, .5.3.
178 5.

. 5.3.

, .
, ,
.
, ,
, :
} else if ($element.parent().is(":nth-child(4)")) {
var $input = $("<input>"),
$button = $("<span>").text("+");
$button.on("click", function () {
toDos.push($input.val());
$input.val("");
});
$content = $("<div>").append($input).append($button);
}

, .5.3,
.
$button .
, , -
. , , split
(),
. ,
Chrome:
var words = "hello,world,goodbye,world";
//
179

var arrayOfWords = words.split(",");


console.log(arrayOfWords);
//=> ["hello","world","goodbye","world"]
arrayOfWords[1];
//=> "world"
arrayOfWords[0];
//=> "hello"

, , ,
.
, toDos
toDoObjects. ,
top ( DRY -
, ),
:
} else if ($element.parent().is(":nth-child(4)")) {
var $input = $("<input>").addClass("description"),
$inputLabel = $("<p>").text("Description: "),
$tagInput = $("<input>").addClass("tags"),
$tagLabel = $("<p>").text("Tags: "),
$button = $("<span>").text("+");
$button.on("click", function () {
var description = $input.val(),
//
tags = $tagInput.val().split(",");
toDoObjects.push({"description":description, "tags":tags});
// toDos
toDos = toDoObjects.map(function (toDo) {
return toDo.description;
});
$input.val("");
$tagInput.val("");
});
}


: JavaScript, JSON
AJAX. JavaScript
.
,
(.).
JSON JavaScript,
. JSON -

() . , - (
Flickr, Twitter Facebook) API
180 5.

, (
) JSON.
,
, , -
AJAX. --
. jQuery AJAX,
, -
getJSON.


- Flickr
, -
, Flickr,
. .
setTimeout,
4. ,
. , ,
ello, World! 5 . -
:
// "hello, world!" 5
setTimeout(function () {
console.log("hello, world!");
}, 5000);

, ,
( ), . ,
. ,
,
.
, -
:
var messages = [" ", " ", "", ""];

HTML:
<body>
<div class="message"></div>
</body>

main app.js :
var main = function () {
var messages = [" ", " ", "", ""];
var displayMessage = function (messageIndex) {
// DOM
181

var $message = $("<p>").text(messages[messageIndex]).hide();


//
//
//
$(".message").empty();
// messageIndex DOM
$(".message ").append($message);
//
$message.fadeIn();
setTimeout(function () {
// 3 displayMessage
messageIndex = messageIndex + 1;
displayMessage(messageIndex);
}, 3000);
};
displayMessage(0);
}
$(document).ready(main);
, 3.
, , : , -
undefined, .
, if ,
, , , 0.

, , --
. <blink>, HTML,
.

. , AJAX
Flickr, DOM
(img p). img -
src, Flickr.
, ,
, - -
, . ,
,
. -
!



, , -
. ,
, . ,
182 5.

.
:
;
;
;
, ,
( ), ;
;
- ;
;
- , ;
- -,
.
, , . -
, , ,
, , -
. JavaScript, ,
.
, -
, . -
, .
, ,
,
.
, :
var hand = [
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" }
];

. -
, .
, ? -
, 4! -
, , , ,
containsNTimes, : ,
.
, -
:
183

//
containsNTimes(["","","","",""], "", 2);
//=> true

, ! -
.
//
containsNTimes(["","","","",""], "", 3);
//=> false

,
.
map, :
// "hand" ,
hand.map(function (card) {
return card.rank;
});
//=> ["","","","",""]

map ,
containsNTimes, ,
:
var handRanks,
result;
handRanks = hand.map(function (card) {
return card.rank;
});
// 'true'
result = containsNTimes(handRanks, "two", 2);

, , -
forEach , :
//
var ranks = ["","","","","","","",
"","","","","",""];
var containsPair = function (hand) {
// , ,
//
var result = false,
handRanks;
//
handRanks = hand.map(function (card) {
return card.rank;
});
//
ranks.forEach(function (rank) {
if (containsNTimes(handRanks, rank, 2)) {
//
result = true;
184 5.

}
});
// true, ,
// false,
return result;
};


(, containsThreeOfAKind
). -
, . -
, .
, :
( containsPair, -
!), 4.
-
(
11, 12, 13, 14).
, , ,
, ,
4.
, , .
, - , -
-, ( 10).

API
, , Flickr ,
API. ,
API , Flickr.
Programmable Web API. , -
jQuery getJSON,
JSONP. API, JSONP,
.
API, ,
URL , API
AJAX.
6

,
-.
JSON AJAX. -
!
-
, HTTP Node.js. , Node.js
( !) ,
- JavaScript.


,
, , Windows,
Mac OS Linux .
, VirtualBox
Vagrant .
Vagrant
. ,
.
. ,
Vagrant VirtualBox -
.
, .
-, :
Node.js
( ),
, MongoDB Redis, -
.
, , . -
,
Node.js, Redis MongoDB. , Vagrant
, Windows,
186 6.

Mac OS Linux. , -
.
, VirtualBox
.
-.

Virtual Box
Vagrant
VirtualBox.
4.2.18. http://www.virtualbox.org
(.6.1), Downloads -
. , -
,
.

. 6.1. VirtualBox

Vagrant (
1.4). , http://www.vagran
tup.com (.6.2), Downloads
.
, VirtualBox.
Virtual Box Vagrant 187

. 6.2. Vagrant

Windows, ,
, .
, ( cmd -
) vagrant version:
C:\Users\semmy>vagrant --version
Vagrant version 1.4.0

, . ,
vagrant .


, Git node-
dev-bootsrap GitHub. , -
Git, , .
Windows, git-bash.
Projects node-dev-
bootstrap :
hostname $ git clone https://github.com/semmypurewal/node-dev-bootstrap Chapter6

Chapter6, node-dev-
bootstrap . vagrant up:
hostname $ cd Chapter6
hostname $ vagrant up
188 6.

Windows, , -
, vboxheadless . -
, .

, Vagrant .
. .

SSH
, . ?
, SSH ( Secure Shell),
.
Mac OS Linux, , -
SSH. Windows, -
SSH.
:
hostname $ vagrant ssh

Mac OS, .
Windows, .
, Vagrant ( ,
127.0.0.1 2222). SSH, -
, PuTTY,
PuTTY. PuTTY .6.3.

. 6.3. ( ) PuTTY
Virtual Box Vagrant 189

PuTTY, , Vagrant,
Host Name Port (.6.4). Open
(). PuTTY -
. Vagrant.

. 6.4. PuTTY

, Node.js!
, -
, . ,
- -
, , ls:
vagrant $ ls
app postinstall.sh

postinstall.sh. -
, ,
app :
vagrant $ cd app
vagrant $ ls
server.js

server.js. , -
, node:
vagrant $ node server.js
Server listening on port 3000
190 6.

Server listening on port 3000 (


3000) - ,
. , Chrome localhost:3000
. ,
Hello, World!. , .6.5.

. 6.5. Node , Chrome

: ,
Ctrl+C. , , exit:
vagrant $ exit
logout
Connection to 127.0.0.1 closed.

PuTTY Windows,
. ,
, .
MacOS, .
, vagrant halt:
hostname $ vagrant halt
[default] Attempting graceful shutdown of VM..1

,
- , .
.
vagrant up.

, Vagrant, -
, vagrant destroy.
, vagrant up . -
vagrant halt.

1
: . . .
191


,
, .


,
. -
, .
, - -
. FTP- ,
(File Transfer Protocol), .
FTP- , FTP- -
. .6.6.

. 6.6.

-
-,
.
-, , ( ) , -
, -
HTTP (Hypertext Transfer Protocol).
HTML- -
,
( , ,
).
HTTP, : , , -
.
192 6.

HTTP
, . , HTML,
CSS JavaScript, ,
. , ,
, ,
AJAX.


HTTP- (
). -
, -
, ,
, -
. .
, .
.
,
, . -
, ( , -
SSH, , ). -
,

.
, ,
(). .
, .


, .
, -
, , .
. Chrome .
. , , -
, Sublime. , -
, .
Git. Git . Git -
-. Mac OS Linux, ,
Windows git-bash.
Vagrant. , Vagrant ,
Git. , vagrant
up vagrant halt , git commit.
, HTTP! 193

SSH. ,
. Windows, PuTTY
git-bash , vagrant
ssh . Mac OS, -
.
-
. . 6.7, , ,
.

. 6.7. Windows git-bash, PuTTY Chrome

, HTTP!
, -
- -, . ,
,
( ), -

.
Sublime app Chapter6.
server.js, :
var http = require("http"),
server;
server = http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("Hello, World!");
});
server.listen(3000);
console.log("Server listening on port 3000");
194 6.


, console.log,
, JSON, ,
UI .
? ,
HTTP, ! , HTTP
HyperText Transfer Protocol ( ), -
, www (World Wide Web ). ,
, Apache Nginx
HTTP ,
-. HTTP- : -
Hello, World!.
jQuery -
, -
, ,
( ). req ,
HTTP, , res ,
HTTP, . req.writeHead
HTTP, , res.
end , Hello, World!.
3000 (
localhost 3000). console.log
, .

Express
! ? -
HTTP .
, ,
http Node.js. - ,
-
API, .
require, http -
http.
http , ,
HTTP-,
. HTML CSS ,
.
, Node.js, , ,
! Express http , -
,
, , HTML, CSS JavaScript
.
Express 195

, Node
Express, .
http, , -
Node, , . Express
, ,
, http.
, Node ,
Node Package Manager (NPM) Node.
, .

Express NPM
NPM . -
app Express. Sublime
. , ,
Vagrant SSH Express. npm install
express:
vagrant $ ls
app postinstall.sh
vagrant $ cd app
vagrant $ ls
Express server.js
vagrant $ cd Express
vagrant $ npm install express

NPM Virtual Box Windows.


Express,
npm install express no-bin-links .

NPM Express
. ? ,
, node_modules.
:
vagrant $ pwd
/home/vagrant/app/Express
vagrant $ ls
server.js node_modules
vagrant $ ls node_modules
express

Express
, Express , Express.
Express , server.js
:
196 6.

var express = require("express"),


http = require("http"),
app;
// http- Express
// 3000
app = express();
http.createServer(app).listen(3000);
//
app.get("/hello", function (req, res) {
res.send("Hello, World!");
});
app.get("/goodbye", function (req, res) {
res.send("Goodbye, World!");
});

,
. -, -
HTTP , Express -
. -, res.send res.write res.end.
, , , : , hello goodbye.
, , ,
.
, , node server.js Express
. , , localhost:3000,
. , ,
'Cannot GET /'. localhost:3000/hello localhost:3000/
goodbye, , . -
.
, hello goodbye URL -
, . , , Express
. , localhost:3000
, ,
server.js :
app.get("/", function (req, res) {
res.send(" !");
});

( Ctrl+C) , -
localhost:3000, ! Express -
,
.


, .
, HTML-?
Express 197

, . , , -
:
app.get("/index.html", function (req, res) {
res.send("<html><head></head><body><h1>Hello, World!</h1></body></html>");
});

, HTML-, -
, , .
, Express -
. HTML, CSS
JavaScript , !
, , -
.
app client.
server.js :
var express = require("express"),
http = require("http"),
app = express();
//
//
// (. )
app.use(express.static(__dirname + "/client"));
// HTTP- Express
http.createServer(app).listen(3000);
//
app.get("/hello", function (req, res) {
res.send("Hello, World!");
});
app.get("/goodbye", function (req, res) {
res.send("Goodbye, World!");
});

Windows -
, , , , . -
path,
.
GitHub, , - , -
.

app.use
. , , ,
(client),
. , index.html client
localhost:3000/index.html,
198 6.

. , ,
.

,
client, Express? ,
, .
-
.

, , -
client. , ( -
), client,
Express.
node
server.js. HTML index.html,
localhost:3000/index.html ,
CSS JavaScript!


, .
client, Express
server.js. /
.
, , -
. ,
AJAX JSON -
. ,
, Twitter API.


Twitter API
. , .
, vagrant up app,
Chapter6. SSH .
Windows, PuTTY, Mac OS
Linux, vagrant ssh.
app Twitter. -
, , ,
, ( app Projects)
Sublime.
199

Twitter
API Twitter, ,
, Twitter. ,
Twitter, . ,
!
Twitter,
Create a new application ( ) .
, , .6.8. -
.

. 6.8. , Twitter

, - .
, , ,
(,, www.example.com). URL
.

, ,
, Consumer key ( ) Consumer
secret ( ). API,
. ,
Create my access token ( ).
, , .
credentials.json,
. JSON,
Twitter (
, ):
200 6.

{
"consumer_key": "your consumer key here",
"consumer_secret": "your consumer secret here",
"access_token_key": "your access token key here",
"access_token_secret": "your access token secret here"
}

, ,
Git , -
. . Git
.gitignore ,
.

Twitter API
ntwitter NPM:
vagrant $ mkdir Twitter
vagrant $ cd Twitter
vagrant $ npm install ntwitter
vagrant $ ls node_modules
express ntwitter
tweet_counter.js, -
, Twitter API. , -
ntwitter ,
http . credentials.json,
Node, , , express ntwitter,
NPM. ./
Node :
var ntwitter = require("ntwitter"),
credentials = require("./credentials.json"),
twitter;
// twitter
twitter = ntwitter(credentials);
// twitter ,
//
twitter.stream(
//
"statuses/filter",
// ,
{ "track": ["awesome", "cool", "rad", "gnarly", "groovy" }1, //.

1
, , , , .

. . .
201

// , ,
function(stream) {
stream.on("data", function(tweet) {
console.log(tweet.text);
});
}
);
, node tweet_counter
, , -
! ,
, Ctrl+C, .

?
. . -,
ntwitter
credentials.json. twitter
ntwitter -
. twitter, -
.
, stream twitter.
. , -
( ). ,
( -
, ,
). , , ,
, .
stream ,
( DOM jQuery). ,
, (data), ,
. , ? !
, Twitter .


,
. ,
. ,
, , ,
. , , , -
.
, :
var ntwitter = require("ntwitter"),
credentials = require("./credentials.json"),
twitter,
202 6.

counts = {};
counts.awesome = 0;
counts.cool = 0;
counts.rad = 0;
counts.gnarly = 0;
counts.groovy = 0;
, ,
.

indexOf
Twitter, ,
text tweet , . ,
, indexOf, ,
. ,
! indexOf
1, .
, JavaScript Chrome :
var tweet = " ! , 140 ."
// indexOf ,
tweet.indexOf("");
//=> 10
tweet.indexOf("");
//=> 0
tweet.indexOf("");
//=> 32
tweet.indexOf("");
//=> 56
tweet.indexOf("");
//=> -1
// : indexOf !
tweet.indexOf("");
//=> -1
, indexOf , , -
, 1.
console.log :
function(stream) {
stream.on("data", function(tweet) {
if (tweet.indexOf("awesome") > -1) {
// awesome
counts.awesome = counts.awesome + 1;
}
});
}

setInterval
, , console.log?
. -
203

, , . ,
setInterval :
//
setInterval(function () {
console.log("awesome: " + counts.awesome);
}, 3000);
setTimeout, ,
setInterval , . -
, ,
.
awesome 3 .
awesome,
twitter.js :
var ntwitter = require("ntwitter"),
credentials = require("./credentials.json"),
twitter,
counts = {};
// twitter
twitter = ntwitter(credentials);
//
counts.awesome = 0;
twitter.stream(
"statuses/filter",
{ "track": ["awesome", "cool", "rad", "gnarly", "groovy"] },
function(stream) {
stream.on("data", function(tweet) {
if (tweet.indexOf("awesome") > -1) {
// awesome
counts.awesome = counts.awesome + 1;
}
});
}
);
// 3
setInterval(function () {
console.log("awesome: " + counts.awesome);
}, 3000);
, node tweet_counter.js,
.

Twitter
, , ,
- HTTP,
. . -
,
. .
204 6.

,
, HTTP (, -
, ). ,
.
, -
Node.js: , -
, .
? ,
. module.exports,
, .
counts, -
. tweet_counter.js -
:
module.exports = counts;

, ,
JavaScript, . -

Express
, Express :
var express = require("express"),
http = require("http"),
app = express();
//
app.use(express.static(__dirname + "/client"));
// HTTP- Express
http.createServer(app).listen(3000);
//
app.get("/hello", function (req, res) {
res.send("Hello, World!");
});
,
, JSON:
var express = require("express"),
http = require("http"),
tweetCounts = require("./tweet_counter.js"),
app = express();
//
app.use(express.static(__dirname + "/client"));
205

// HTTP- Express
http.createServer(app).listen(3000);
//
app.get("/counts.json", function (req, res) {
// res.json JSON
res.json(tweetCounts);
});
, app -
node app. ,
3,
localhost:3000/counts.json, JSON !
JSON ? ,
AJAX!


, , ,
index.html, styles/style.css javascripts/app.js,
.
client , client -
cp. app :
vagrant $ node app.js
javascript/app.js hello, world, ,
localhost:3000/index.html , Hello, World!,
JavaScript, .
, app.js
counts.json jQuery getJSON:
var main = function () {
"use strict";
$.getJSON("/counts.json", function (wordCounts) {
// "wordCounts" ,
// counts.json,
// Express
console.log(wordCounts);
});
}
$(document).ready(main);
, getJSON counts.json,
Express, .
, counts.

. , !
DOM -
jQuery DOM.
:
206 6.

var main = function () {


"use strict";
var insertCountsIntoDOM = function (counts) {
// DOM
};
// : insertCountsIntoDOM
// , getJSON
$.getJSON("counts.json", insertCountsIntoDOM);
}
$(document).ready(main);

? , -

setInterval, -
:
var main = function () {
"use strict";
var insertCountsIntoDOM = function (counts) {
// DOM
};
// counts 5
// DOM
setInterval(function () {
$.getJSON("counts.json", insertCountsIntoDOM);
}, 5000);
}
$(document).ready(main);

,
, . -,
, ,
AJAX.

Amazeriffic
,
Amazeriffic , -
, JSON, -
.
Git, , .


Chapter5/app, Amazeriffic.
, , -
. .
client Amazeriffic 5.
Amazeriffic 207

5
, . ,
todo.json . ,
,
. -
, mv, move ():
hostname $ mv client/todos.json client/todos.OLD.json

Git
Git, . -
, Git . -
:
hostname $ git init
Initialized empty Git repository ...


, . -
, Express.
Amazeriffic npm:
vagrant $ pwd
/home/vagrant/app/Amazeriffic
vagrant $ npm install express


, ,
-
. ,
, .
, -
.
JSON :
var express = require("express"),
http = require("http"),
app = express(),
toDos = {
//
// todos.OLD.json
};
app.use(express.static(__dirname + "/client"));
http.createServer(app).listen(3000);
//
// todos.json 5
208 6.

app.get("todos.json", function (req, res) {


res.json(toDos);
});


, , app.js Node:
vagrant $ node app.js
,
Chrome localhost:3000/index.html !
localhost:3000 , -
index.html, , ,
.
, ,
. , ,
, .
, , -
.



. ,
. -
jQuery
getJSON. , jQuery ,
JSON,
.
HTTP -
post. post Express.
post, :
app.post("/todos", function (req, res) {
console.log(" !");
//
res.json({"message":" !"});
});

get, ,
get call. ,
, , -
get. JavaScript , -
, . , -
.
:
Amazeriffic 209

// main,
// toDoObjects
$button.on("click", function () {
var description = $input.val(),
tags = $tagInput.val().split(",");
toDoObjects.push({"description":description, "tags":tags});
//
$.post("todos", {}, function (response) {
//
console.log(" !");
console.log(response);
});
// toDos
toDos = toDoObjects.map(function (toDo) {
return toDo.description;
});
$input.val("");
$tagInput.val("");
});
$.post ,
, ( ),
, . -
, , ,
, .
, .
, post , .
, ,
.
URL-
Express, JSON, jQuery, JavaScript,
:
var express = require("express"),
http = require("http"),
app = express()
toDos = {
// ...
};;
app.use(express.static(__dirname + "/client"));
// Express
// JSON
app.use(express.urlencoded());
app.post("/todos", function (req, res) {
// req.body
var newToDo = req.body;
console.log(newToDo);
toDos.push(newToDo);
//
res.json({"message":" !"});
});
210 6.

, ,
. .
, -
:
$button.on("click", function () {
var description = $input.val(),
tags = $tagInput.val().split(","),
//
newToDo = {"description":description, "tags":tags};
$.post("todos", newToDo, function (result) {
console.log(result);
//
//
toDoObjects.push(newToDo);
// toDos
toDos = toDoObjects.map(function (toDo) {
return toDo.description;
});
$input.val("");
$tagInput.val("");
});
});
, -
JavaScript.
toDo .
,
, -
, !


-
Node.js. Node.js ,
JavaScript. , HTTP,
, .
Node.js, , .
, - , -
module.exports.
require.
NPM Node.js Package Manager ( Node.js)
Node.js,
Node.js. , Express -
NPM. Express http Node.js,
HTTP. , -
HTML, CSS JavaScript.
211

, -
.
VirtualBox Vagrant.
-,
. ,
(, ) (
Node.js, ).
, : -
HTTP post c jQuery, -
post Express.


Node.js
Node.js Vagrant.
, Vagrant -
, 7 8. -
Node.js , , -

. http://nodejs.org/download, -
.
.
,
, JSHint, CSS Lint HTML5.

JSHint CSS Lint NPM


4 JSLint ,
JavaScript. -
, http://jslint.com,
. ,
.
, Node.js ,
NPM ,
, JSHint. JSHint
JSLint . -
NPM. -
g, NPM, .
, JSHint
-
node_modules:
hostname $ sudo npm install jshint -g
212 6.

Mac OS Linux sudo . Windows


.

, JSHint -
. , test.js:
var main = function () {
console.log("hello, world");
}
$(document).ready(main);

, , , -
main. JSHint :
hostname $ jshint test.js
test.js: line 3, col 2, Missing semicolon.1
1 error

, JSHint .
JSHint ,
:
hostname $ jshint test.js
hostname $
JSHint (
, ) ,
. , JSHint , -
. -
http://jshint.com/docs.
NPM CSS Lint
, CSS
:
hostname $ sudo npm install csslint g
HTML .
HTML,
.


Twitter. -
. ,
tweet_counter.js :

1
: test.js: 3, 2, . . .
213

counts.awesome = 0;
counts.cool = 0;
counts.rad = 0;
counts.gnarly = 0;
counts.groovy = 0;
ntwitter :
{ "track": ["awesome", "cool", "rad", "gnarly", "groovy"] },
, , ,
:
if (tweet.indexOf("awesome") > -1) {
// awesome
counts.awesome = counts.awesome + 1;
}
if (tweet.indexOf("cool") > -1) {
// cool
counts.cool = counts.cool + 1;
}
? - ,
! ? -
tweet_
counter:
var trackedWords = ["awesome", "cool", "rad", "gnarly", "groovy"];

, -
:
{ "track": trackedWords };

JavaScript
(map) , -
.
:
// awesome
// (dot)
counts.awesome = 0;
counts.awesome = counts.awesome + 1;
// awesome
//
counts["awesome"] = 0;
counts["awesome"] = counts["awesome"] + 1;

, -
JavaScript ( JSLint -
). -
:
var word = "awesome";
214 6.

counts[word] = 0;
counts[word] = counts[word] + 1;
, ? , -
:
//
var counts = {};
trackedWords.forEach(function (word) {
counts[word] = 0;
});

. forEach -
, , - . ,
, -
!
, -
. , -
,
. ,
- :
var tweetCounter = require("./tweet_counter.js"),
counts;
// , tweetCounter
//
counts = tweetCounter(["hello", "world"]);
, counts:
var setUpTweetCounter = function (words) {
// counts
// ntwitter
//
// ...
//
return counts;
}
module.exports = setUpTweetCounter;
, -
. , , ,
, . -
, !

API
, API
Express. Express,
/hand. , -
215

, JSON,
. , :
[
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" }
]

API null ( 5), -


, :
{
"handString":"",
"error": null
}

, (
), , , .
error null, , .
, - (, -
),
handString null :
{
"handString": null,
"error": " !"
}

Node.js, 5. -
Express-:
var poker = require("./poker.js");
:
var hand = [
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" },
{ "rank":"", "suit":"" }
]
var hasPair = poker.containsPair(hand);
// hasPair true
? poker
:
var poker = {};
poker.containsPair = function (hand) {
216 6.

// ...
}
poker.containsThreeOfAKind = function (hand) {
// ...
}
module.exports = poker;
poker , -
. ,
containsNTimes , :
var poker = {},
containsNTimes; //
// "" ,
// poker
containsNTimes = function (array, item, n) {
// ...
};
poker.containsPair = function (hand) {
// ... containsNTimes
}
poker.containsThreeOfAKind = function (hand) {
// ... containsNTimes
}
// ,
module.exports = poker;

,
,
, API. , ,
, :
app.post("/hand", function (req, res) {
var result = poker.getHand(req.body.hand);
res.json(result);
});

, ,
jQuery.
,
!
7


Node.js,
AJAX. , , -
Twitter
.
, -
, , Node.js.
, , -
. ,
, , , ,
. ,
, - .
,
, . -

-SQL. , Redis MongoDB, -
, Node.js.

SQL
-SQL
, , , SQL (
sequel1), Structured Query Language (-
). , ,
. -
,
. ,

1
, , . . .
218 7.

, -
.
, .
, ,
, ,
, ,
, . ,
.
, -
, .

-
. , -SQL
(NoSQL), : , ,
.
,
, , -
.

Redis
Redis -SQL. -
, . -
, ,
( Redis , -
).
Redis , , -
, JavaScript
.
(, , ..),
.
, ,
( ),
.
,
. Redis ,
Twitter Node.js.
,
,
. ,
Redis .
Redis 219

Redis

,
node-dev-bootstrap Projects, Chapter7. ,
, 6.
, ,
.
, :
hostname $ cd Projects/Chapter7
hostname $ vagrant up
...vagrant build stuff...
hostname $ vagrant ssh
, -
Redis. redis-cli -
Redis:
vagrant $ redis-cli
redis 127.0.0.1:6379>
Redis , set.
awesome 0:
redis 127.0.0.1:6379> set awesome 0
OK
, Redis . -
get:
redis 127.0.0.1:6379> get awesome
"0"
, . ,
,
, . , , Redis
incr ( increment ), :
redis 127.0.0.1:6379> incr awesome
(integer) 1
redis 127.0.0.1:6379> incr awesome
(integer) 2
redis 127.0.0.1:6379> get awesome
"2"
incr 1 , -
( awesome).
Redis, exit.
(set, get, incr) , ,
, Redis
220 7.

, . ,
Redis,
.7.1.

Redis package.json
, , -
,
Node.js .

. 7.1. Redis

Twitter , -
Twitter Chapter6/app Chapter7/app. cp

.
Node.js Redis, -
node-redis. -
npm ntwitter. , ,
,
. package.json, -
, -
.
app package.json
:
Redis 221

{
"name": "tutorial",
"description": "a tutorial on using node, twitter, redis, and express",
"version": "0.0.1",
"dependencies": {
"ntwitter": "0.5.x",
"redis": "0.8.x"
}
}

NPM package.json,
. , npm init,
.

, , -
( Node.js node-redis,
redis NPM). 8,
Cloud Foundry.
package.json . ,
,
:
vagrant $ cd app
vagrant $ npm install

Redis
tweet_counter.js,
. Twitter
app. , , ,
, .
Redis:
var ntwitter = require("ntwitter"),
redis = require("redis"), // redis
credentials = require("./credentials.json"),
redisClient,
twitter,
//
counts = {};
twitter = ntwitter(credentials);
// Redis
client = redis.createClient();
//
counts.awesome = 0;
twitter.stream(
222 7.

"statuses/filter",
{ track: ["awesome", "cool", "rad", "gnarly", "groovy"] },
function(stream) {
stream.on("data", function(tweet) {
if (tweet.text.indexOf("awesome") >= -1) {
//
client.incr("awesome");
counts.awesome = counts.awesome + 1;
}
});
}
);
module.exports = counts;

incr , -
Redis. Redis

.
. -
,
awesome Redis, , setInterval , , -
. , ,
, Redis, (
Ctrl+C), redis-cli. -
get ,
awesome:
vagrant $ redis-cli
redis 127.0.0.1:6379> get awesome
(integer) "349"

Redis,
. flushall redis-cli.


Redis
, ,
, count. -
,
, Redis. get,
, . , Node, get
, :
Redis 223

var ntwitter = require("ntwitter"),


redis = require("redis"), // Redis
credentials = require("./credentials.json"),
redisClient,
counts = {},
twitter;
twitter = ntwitter(credentials);
client = redis.createClient();
//
client.get("awesome", function (err, awesomeCount) {
// ,
if (err !== null) {
console.log("ERROR: " + err);
//
return;
}
//
// , Redis, ,
//
counts.awesome = parseInt(awesomeCount,10) || 0;
twitter.stream(
"statuses/filter",
{ track: ["awesome", "cool", "rad", "gnarly", "groovy"] },
function(stream) {
stream.on("data", function(tweet) {
if (tweet.text.indexOf("awesome") >= -1) {
//
client.incr("awesome");
counts.awesome = counts.awesome + 1;
}
});
}
);
});
module.exports = counts;

, get : err
awesomeCount? err -
error, - .
, null. , ,
, ,
.
- .
.
, -
awesomeCount. Redis , -
,
JavaScript. parseInt,
, Redis.
224 7.

, parseInt, radix , -
, . , parseInt
NaN, , Not a Number, .
, || JavaScript .
, ,
false, 0 NaN. , .
, awesomeCount,
, 0 . ,
awesome . -
, -
Redis.

mget

get ,
, , -
? , mget .
:
client.mget(["awesome", "cool"], function (err, results) {
if (err !== null) {
console.log("ERROR: " + err);
return;
}
counts.awesome = parseInt(results[0], 10) || 0;
counts.cool = parseInt(results[1], 10) || 0;
}

mget ,
.
Redis , -
, JSON.
JSON, , -
JSON. MongoDB .

MongoDB
MongoDB ( Mongo) ,
, . Mongo -
,
JSON ( MongoDB
BSON, JSON).
,
JavaScript!
MongoDB 225

Mongo ,

. , ! Mongo
Amazeriffic
.

MongoDB

Redis, Mongo ,
.
Mongo, mongo :
vagrant $ mongo
MongoDB shell version: 2.4.7
connecting to: test
>

,
.

Redis Mongo ,
Mongo JavaScript! ,
card () :
> var card = { "rank":"", "suit":"" };
> card
{ "rank" : "", "suit" : "" }
>
. ,
.
Enter Mongo , , .
Mongo JavaScript:
> var clubs = [];
> ["", "", "", ""].forEach(
... function (rank) {
... cards.push( { "rank":rank, "suit":"" } )
... });
> clubs
[
{
"rank" : "",
"suit" : ""
},
{
226 7.

"rank" : "",
"suit" : ""
},
{
"rank" : "",
"suit" : ""
},
{
"rank" : "",
"suit" : ""
}
]

, Mongo
JavaScript Chrome. ,
. Mongo ,
JSON. -
. MongoDB -
show dbs:
> show dbs
local 0.03125GB

.
use:
> use test
switched to db test

(: test).
,
db. ,
save . , Mongo .
, , :
> show collections;
> db.cards.save(card);
> show collections;
cards
system.indexes

, cards ,
. find,
, , :
> db.cards.find();
{ "_id" : ObjectId("526ddeea7ba2be67c95558d8"),"rank":"","suit":"" }

rank () suit () _id,


. MongoDB
.
MongoDB 227

,
, save.
clubs (), :
> db.cards.save(clubs);
> db.cards.find();
{ "_id" : ObjectId("526ddeea7ba2be67c95558d8"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558d9"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558da"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558db"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558dc"),"rank":"","suit":"" }

:
>hearts = [];
> ["", "", "", ""].
... forEach(function (rank)
... { hearts.push( { "rank":rank, "suit":"" } )
... });
> db.cards.save(hearts);
> db.cards.find();
{ "_id" : ObjectId("526ddeea7ba2be67c95558d8"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558d9"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558da"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558db"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558dc"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558de"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558df"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558e0"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558e1"),"rank":"","suit":"" }

,
, JSON,
. ,
twos:
> var twos = db.cards.find({"rank":""});
> twos
{ "_id" : ObjectId("526ddeea7ba2be67c95558d9"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558de"),"rank":"","suit":"" }

:
> var aces = db.cards.find({"rank":""});
> aces
{ "_id" : ObjectId("526ddeea7ba2be67c95558d8"),"rank":"","suit":"" }

, remove
:
> db.cards.remove({"rank":""});
> db.cards.find();
{ "_id" : ObjectId("526ddeea7ba2be67c95558da"),"rank":"","suit":"" }
228 7.

{ "_id" : ObjectId("526ddeea7ba2be67c95558db"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddeea7ba2be67c95558dc"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558df"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558e0"),"rank":"","suit":"" }
{ "_id" : ObjectId("526ddf0f7ba2be67c95558e1"),"rank":"","suit":"" }
, remove -
:
> db.cards.remove();
> db.cards.find();
>
Redis MongoDB (.7.2),
. -
,
MongoDB, .

. 7.2. MongoDB

, ,
Mongo Node.js .
Node.js, Mongoose.

Mongoose
Mongoose Node.js, .
MongoDB , node-redis
MongoDB 229

Redis. , Mongoose
, -
. -
Mongoose Amazeriffic.


. ,
, MongoDB -
save find .
Mongoose ,
. , , -
.
, , .
JavaScript :
var CardSchema = mongoose.Schema({
"rank" : String,
"suit" : String
});

, . -
:
var Card = mongoose.model("Card", CardSchema);

. ,
, .
comments ()
:
var BlogPostSchema = mongoose.Schema({
title: String,
body : String,
date : Date,
comments : [ String ]
});

? , -
, JavaScript new. ,
1:
var c1 = new Card({"rank":"", "suit":""})

,
:
var c2 = { "rank":"", "suit":"" };

, Mongoose
:
230 7.

//
c1.save(function (err) {
if (err !== null) {
//
console.log(err);
} else {
console.log(" !");
}
});

,
find .
find MongoDB
MongoDB. , ,
:
Card.find({}, function (err, cards) {
if (err !== null) {
console.log(": " + err);
//
return;
}
// , ,
Cards.forEach(function (card) {
//
console.log (card.rank + " of " + card.suit);
});
});

- (
), . , ,
:
Card.find({"suit" : " "}, function (err, cards) {
cards.forEach(function (card) {
//
card.suit = "";
//
card.save(function (err) {
if (err) {
//
console.log(err);
}
});
});
});

, ,
remove :
Card.remove({ "rank":"", "suit":"" }, function (err) {
if (err !== null) {
MongoDB 231

//
console.log(err);
}
});


Mongoose: , , .
Mongoose -! .

Amazeriffic
Amazeriffic (
) Chapter7. package.json, -
Mongoose:
{
"name": "amazeriffic",
"description": "The best to-do list app in the history of the world",
"version": "0.0.1",
"dependencies": {
"mongoose": "3.6.x"
}
}

, npm install mongoose.


server.js :
var express = require("express"),
http = require("http"),
// mongoose
mongoose = require("mongoose"),
app = express();
app.use(express.static(__dirname + "/client"));
app.use(express.urlencoded());
// Amazeriffic Mongo
mongoose.connect('mongodb://localhost/amazeriffic');

, ,
:
// Mongoose
var ToDoSchema = mongoose.Schema({
description: String,
tags: [ String ]
});
var ToDo = mongoose.model("ToDo", ToDoSchema);
//
http.createServer(app).listen(3000);

-
:
232 7.

app.get("/todos.json", function (req, res) {


ToDo.find({}, function (err, toDos) {
// !
res.json(toDos);
});
});
, post
. , -
, 2, :
app.post("/todos", function (req, res) {
console.log(req.body);
var newToDo = new ToDo({"description":req.body.description,
"tags":req.body.tags});
newToDo.save(function (err, result) {
if (err !== null) {
console.log(err);
res.send("ERROR");
} else {
// , ,
//
ToDo.find({}, function (err, result) {
if (err !== null) {
//
res.send("ERROR");
}
res.json(result);
});
}
});
});
. -
, ,
, - .


. -
,
-SQL, Redis MongoDB.
Redis .
. node-redis -
Redis , .
MongoDB , -
. ,
JavaScript. ,
Mongo
JavaScript, .
233

Mongoose Node.js,
MongoDB, , .
, - , -
.


API
,
API, -
( , - .).
Express , Redis
Mongo. , , -
, API, . -
.
, get, -
JSON, .
get , .
- ,
-
JSON .
, images -
.


, .
-
, SQL.
Coursera -
. , ,
!
, (
- ) :
(Database Systems: The Complete, Prentice Hall, 2008). -
- , , -
, .
, (
-SQL),
(Seven Databases in Seven Weeks, Pragmatic Bookshelf, 2012). Mongo Redis,
, PostgreSQL Riak.
,
.
8

- -
, , ,
, . -

.
:
IP-, -
, , .
,
- (Platforms-as-a-Service PaaS),
.
, , ?
, -
-
. PaaS -
-,
-. ,
PaaS ,
.
, -
PaaS, Cloud Foundry. Cloud
Foundry,
PaaS, Heroku Nodejitsu.

Cloud Foundry
Cloud Foundry PaaS, VMWare.
, -
http://cloudfoundry.com (.8.1).
60,
- .
235

. 8.1. Cloud Foundry1

, http://www.cloudfoundry.com.
60 ,
.
, .

, , cf. -

Ruby - RubyGems. cf node-dev-
bootstrap,
!
, Chapter8 node-dev-bootstrap,
. ,
SSH.

1
, ,
, URL.
, Cloud Foundry,
. . .
236 8.

server.js,
node-dev-bootstrap, .
package.json, Cloud Foundry
, .
-
Node.js, :
{
"name":"sp_example",
"description": " Cloud Foundry!"
}

server.js,
node-dev-bootstrap. -
, :
Cloud Foundry ,
. , Cloud Foundry -
, PORT.
process.env.PORT Node.js:
var http = require("http"),
// PORT ,
// , ,
// 3000
port = process.env.PORT || 3000;
var server = http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end(" Cloud Foundry!");
});
server.listen(port);
console.log(" " + port);

||, 7.
: process.env.port , -
, , 3000. ,
,
, Cloud Foundry.



, . , package.json
,
Cloud Foundry.
, cf,
. ,
, server.js.
237

API Cloud Foundry api.run.pivotal.io.


cf, Cloud Foundr,
target:
vagrant $ cf target api.run.pivotal.io
Setting target to https://api.run.pivotal.io... OK
login
Cloud Foundry. cf , -
. -
development, :
vagrant $ cf login
target: https://api.run.pivotal.io
Email> me@semmy.me
Password> ************
Authenticating... OK
1: development
2: production
3: staging
Space> 1
Switching to space development... OK
, Cloud
Foundry! ? , push.
push :
vagrant $ cf push --command "node server.js"
push Cloud Foundry. -
, -
. , Cloud Foundry, , ,
:
Name> sp_example
Instances> 1
1: 128M
2: 256M
3: 512M
4: 1G
Memory Limit> 256M
Creating sp_example... OK
1: sp_example
2: none
Subdomain> sp_example
1: cfapps.io
2: none
Domain> cfapps.io
Creating route sp_example.cfapps.io... OK
Binding sp_example.cfapps.io to sp_example... OK
Create services for application?> n
Save configuration?> n
Uploading sp_example... OK
238 8.

Preparing to start sp_example... OK


-----> Downloaded app package (4.0K)
-----> Resolving engine versions
WARNING: No version of Node.js specified in package.json, see:
https://devcenter.heroku.com/articles/nodejs-versions
Using Node.js version: 0.10.21
Using npm version: 1.2.30
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
npm WARN package.json sp_example@ No repository field.
npm WARN package.json sp_example@ No readme data.
Dependencies installed
-----> Building runtime environment
-----> Uploading droplet (15M)
Checking status of app 'sp_example'...
1 of 1 instances running (1 running)
Push successful! App 'sp_example' available at sp_example.cfapps.io

.
, , example, , -
. ,
. ,
.

, !
, URL, cf (
http://sp_example.cfapps.io). ,
.


, ,
cf . , -
apps ,
Cloud Foundry, :
vagrant $ cf apps
name status usage url
sp_example running 1 x 256M sp_example.cfapps.io
PaaS ,
console.log ,
. ,
. , Cloud Foundry -
logs,
, :
239

vagrant $ cf logs sp_example


Getting logs for sp_example #0... OK
Reading logs/env.log... OK
TMPDIR=/home/vcap/tmp
VCAP_APP_PORT=61749
USER=vcap
VCAP_APPLICATION= { ... }
PATH=/home/vcap/app/bin:/home/vcap/app/node_modules/.bin:/bin:/usr/bin
PWD=/home/vcap
VCAP_SERVICES={}
SHLVL=1
HOME=/home/vcap/app
PORT=61749
VCAP_APP_HOST=0.0.0.0
MEMORY_LIMIT=256m
_=/usr/bin/env
Reading logs/staging_task.log... OK
-----> Downloaded app package (4.0K)
-----> Resolving engine versions
WARNING: No version of Node.js specified in package.json, see:
https://devcenter.heroku.com/articles/nodejs-versions
Using Node.js version: 0.10.21
Using npm version: 1.2.30
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
npm WARN package.json sp_example@ No repository field.
npm WARN package.json sp_example@ No readme data.
Dependencies installed
-----> Building runtime environment
Reading logs/stderr.log... OK
Reading logs/stdout.log... OK
Server listening on port 61749

, Cloud Foundry .
env.log, , -
process.env . staging_
task.log, ,
( , , ,
cf push). stderr.log stdout.log.
, stdout.log console.log, -
. console.err,
stderr.log.


Cloud Foundry, -
. server.json ,
:
240 8.

var http = require("http"),


port = process.env.PORT || 3000;
var server = http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write(" " + port);
res.end(" Cloud Foundry!");
});
server.listen(port);
console.log(" " + port);
, push
, .

:
vagrant $ cf push sp_example
Save configuration?> n
Uploading sp_example... OK
Stopping sp_example... OK
Preparing to start sp_example... OK
-----> Downloaded app package (4.0K)
-----> Downloaded app buildpack cache (4.0K)
-----> Resolving engine versions
WARNING: No version of Node.js specified in package.json, see:
https://devcenter.heroku.com/articles/nodejs-versions
Using Node.js version: 0.10.21
Using npm version: 1.2.30
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
npm WARN package.json sp_example@ No repository field.
npm WARN package.json sp_example@ No readme data.
Dependencies installed
-----> Building runtime environment
-----> Uploading droplet (15M)
Checking status of app 'sp_example'...
1 of 1 instances running (1 running)
Push successful! App 'sp_example' available at sp_example.cfapps.io


Cloud Foundry
, , Cloud Foundry,
. , -
delete:
vagrant $ cf delete sp_example
Really delete sp_example?> y
Deleting sp_example... OK
241

package.json

express, redis, mongoose ntwitter. -
, (, Express
Twitter), .
node_modules, ,
package.json.
, Express. -

Cloud Foundry, :
var express = require("express"),
http = require("http"),
app = express(),
port = process.env.PORT || 3000;;
http.createServer(app).listen(port);
console.log("Express is listening on port " + port);
app.get("/hello", function (req, res) {
res.send("Hello, World!");
});
app.get("/goodbye", function (req, res) {
res.send("Goodbye World!");
});
Express package.json,
package.json:
{
"name": "sp_express",
"description": "a sample Express app",
"dependencies": {
"express": "3.4.x"
}
}
, , Express,
, 3.4 ( ).
, CLoud Foundry , ,
.
package.json, Cloud Foundry
, :
vagrant $ ~/app$ cf push --command "node server.js"
Name> sp_expressexample
, http://sp_expressexample.cfapps.io/hello http://
sp_expressexample.cfapps.io/goodbye, !
Twitter Amazeriffic
, , Redis
MongoDB. , ,
.
242 8.

Redis
, , Redis
MongoDB, . , -
PaaS. ,
.
,
cf. Redis Cloud Foundry, -
.
Twitter 7 Chapter8. -
, Package.json ntwitter
redis. :
{
"name": "tweet_counter",
"description": "tweet counter example for learning web app development",
"dependencies": {
"ntwitter":"0.5.x",
"redis":"0.9.x"
}
}

server.js , , -
process.env.PORT. , -
! ( , , ,
Redis):
vagrant $ cf push --command "node server.js"
Name> sp_tweetcounter
Instances> 1
1: 128M
2: 256M
3: 512M
4: 1G
Memory Limit> 256M
Creating sp_tweetcounter... OK
1: sp_tweetcounter
2: none
Subdomain> sp_tweetcounter
1: cfapps.io
2: none
Domain> cfapps.io
Binding sp_tweetcounter.cfapps.io to sp_tweetcounter... OK
Create services for application?> y
1: blazemeter n/a, via blazemeter
2: cleardb n/a, via cleardb
3: cloudamqp n/a, via cloudamqp
4: elephantsql n/a, via elephantsql
5: loadimpact n/a, via loadimpact
Redis 243

6: mongolab n/a, via mongolab


7: newrelic n/a, via newrelic
8: rediscloud n/a, via garantiadata
9: sendgrid n/a, via sendgrid
10: treasuredata n/a, via treasuredata
11: user-provided , via

: Cloud Foundry,
:
What kind?> 8
Name?> rediscloud-dfc38
1: 20mb: Lifetime Free Tier
Which plan?> 1
Creating service rediscloud-dfc38... OK
Binding rediscloud-dfc38 to sp_tweetcounter... OK
Create another service?> n
Bind other services to application?> n
Save configuration?> n

, , .
, , -
Redis. . ,
cf logs sp_tweetcounter, - logs/stderr.log:
Reading logs/stderr.log... OK
events.js:72
throw er; // Unhandled 'error' event
^
Error: Redis connection to 127.0.0.1:6379 failed connect ECONNREFUSED
at RedisClient.on_error (/home/vcap/app/node_modules/redis/index.js:189:24)
at Socket.<anonymous> (/home/vcap/app/node_modules/redis/index.js:95:14)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:415:13)

Redis,
(127.0.0.1),
(6379).
Redis , Cloud Foundry.
? ,
process.env!
cf logs sp tweetcounter, ,
VCAP_SERVICES.
JSON, -
:
VCAP_SERVICES = {
"rediscloud-n/a": [{
"name": "rediscloud-dfc38",
"label": "rediscloud-n/a",
244 8.

"tags": ["redis", "key-value"],


"plan": "20mb",
"credentials": {
"port": "18496",
"hostname": "pub-redis-18496.us-east-1-4.2.ec2.garantiadata.com",
"password": "REDACTED"
}
}]
}
,
Redis, URL, .
Redis , , ,
, .

VCAP_SERVICES
, JSON.parse , 5,
, -
JavaScript.

, Redis ,
tweet_counter.js :
var ntwitter = require("ntwitter"),
redis = require("redis"), // Redis
credentials = require("./credentials.json"),
redisClient,
counts = {},
twitter,
services,
redisCredentials;
// Twitter
twitter = ntwitter(credentials);
// ,
if (process.env.VCAP_SERVICES) {
// JSON
services = JSON.parse(process.env.VCAP_SERVICES);
redisCredentials = services["rediscloud-n/a"][0].credentials;
} else {
//
redisCredentials = {
"hostname": "127.0.0.1",
"port": "6379",
"password": null
};
}
// Redis
client = redis.createClient(redisCredentials.port, redisCredentials.hostname);
//
client.auth(redisCredentials.password);
MongoDB 245

,
VCAP_SERVICES, , , ,
JavaScript JSON. ,
rediscloud-n/a services.
(
Redis), .
VCAP_SERVICES , -
redisCredentials, . -
Redis, , . -
Redis ,
null, .
, -
. .
, cf apps, -
:
vagrant $ cf apps
Getting applications in development... OK
name status usage url
sp_example running 1 x 256M sp_example.cfapps.io
sp_express running 1 x 256M sp_express.cfapps.io
sp_tweetcounter running 1 x 256M sp_tweetcounter.cfapps.io
vagrant $ cf push sp_tweetcounter
, , -
, URL, Cloud
Foundry.

MongoDB
MongoDB Cloud Foundry -
, Redis. Amazeriffic
7 .
.
, process.env.PORT,
.
.
process.env.VCAP_SERVICES.
Redis. ,
MongoDB uri:
// mongoUrl -
//
if (process.env.VCAP_SERVICES) {
services = JSON.parse(process.env.VCAP_SERVICES);
mongoUrl = services["mongolab-n/a"][0].credentials.uri;
} else {
246 8.

// Cloud Foundry
mongoUrl = "mongodb://localhost/amazeriffic"
}

, Cloud
Foundry , .
MongoLab:
Create services for application?> y
1: blazemeter n/a, via blazemeter
2: cleardb n/a, via cleardb
3: cloudamqp n/a, via cloudamqp
4: elephantsql n/a, via elephantsql
5: loadimpact n/a, via loadimpact
6: mongolab n/a, via mongolab
7: newrelic n/a, via newrelic
8: rediscloud n/a, via garantiadata
9: sendgrid n/a, via sendgrid
10: treasuredata n/a, via treasuredata
11: user-provided, via
What kind?> 6
Name?> mongolab-8a0f4
1: sandbox: 0.5 GB
Which plan?> 1
Creating service mongolab-8a0f4... OK

Mongo , -
, Redis.
URL,
VCAP_SERVICES, ,
.


, Cloud Foundry, -
. Cloud Foundry -
(Platform as a Service). PaaS , -
, ,
-.
Cloud Foundry (
PaaS), , ,
, -
Cloud Foundry.
Cloud Foundry , Redis
MongoDB. ,
cf,
.
247


API
API,
. -
.
, Cloud Foundry.


.
Heroku. -
. Redis Mongo,
,
.
, Heroku
Node.js,
. ,
Nodejitsu Microsofts Windows Azure.
,
.
9

, ,
, , HTML, CSS
JavaScript. -, , ,
, , .
, ,
. , -
. ,
, ,
,
. ( JavaScript)
,
.
, , -
, , ,
. -
, , .
--
, , , -
. -
, Ruby on Rails, ,
(,
, ).
, Amazeriffic ,
. ,
, .


. , ,
. , -
, -
, ,
249

. , , -
, , -
. .
-
. .
,
.


.
, -
, ,
.
: ,
. ,
HTML:
<div class="tabs">
<a href=""><span class="active"></span></a>
<a href=""><span></span></a>
<a href=""><span></span></a>
<a href=""><span></span></a>
</div>
JavaScript DOM, ,
:
if ($element.parent().is(":nth-child(1)")) {
// ""
} else if ($element.parent().is(":nth-child(2)")) {
// ""
} else if ($element.parent().is(":nth-child(3)")) {
// ""
} else if ($element.parent().is(":nth-child(4)")) {
// ""
}
, -
. ,
, .
, -
, HTML,
JavaScript. 5 , - -
.
?
, , 5.
, ,
250 9.

, , ,
. ,
:
var newestTab = {
//
"name":"",
// ,
"content": function () {
var $content;
//
$content = $("<ul>");
for (i = toDos.length-1; i >= 0; i--) {
$content.append($("<li>").text(toDos[i]));
}
return $content;
}
}

, . -
, ,
,
, :
var main = function (toDoObjects) {
"use strict";
var toDos,
tabs;
toDos = toDoObjects.map(function (toDo) {
return toDo.description;
});
//
tabs = [];
//
tabs.push({
"name":"",
"content":function () {
// $content
return $content;
}
});
//
tabs.push({
"name":"",
"content":function () {
// $content
return $content;
}
});
//
tabs.push({
251

"name":"",
"content":function () {
// $content
return $content;
}
});
//
tabs.push({
"name":"",
"content":function () {
// $content
return $content;
}
});
};

, ,
.
HTML <div class="tabs">:
<!-- -->
<!-- JavaScript -->
</div> ( div):

tabs.
DOM:
tabs.forEach(function (tab) {
var $aElement = $("<a>").attr("href",""),
$spanElement = $("<span>").text(tab.name);
$aElement.append($spanElement);
$spanElement.on("click", function () {
var $content;
$(".tabs a span").removeClass("active");
$spanElement.addClass("active");
$("main .content").empty();
// ,
// tab
$content = tab.content();
$("main .content").append($content);
return false;
});
});

AJAX
, , -
- ,
, . -
.
252 9.

,
, , ,
. , ,
AJAX .
, jQuery get:
tabs.push({
"name":"",
"content":function () {
$.get("todos.json", function (toDoObjects) {
// $content
// 'return' $content
});
}
});

-
, , , -
, , .
,
Node.js, socket.io.

, ,
.
, ,
AJAX:
$content = tab.content();
$("main .content").append($content);

.
DOM content:
tabs.push({
"name":"",
"content":function () {
$.get("todos.json", function (toDoObjects) {
// $content
// DOM
$("main .content").append($content);
});
}
});

. -
: content ,
DOM. getContentAndUpdateThe
DOM.
253

: - -
, DOM,
content .
:
, . -
,
content:
// content
// ,
tabs.push({
"name":"",
"content":function (callback) {
$.get("todos.json", function (toDoObjects) {
// $content
// $content
callback($content);
});
}
});
// ...
//
tab.content(function ($content) {
$("main .content").append($content);
});

, , , -
Node.js, , Promises
() Reactive JavaScript ( JavaScript).
1
( ), -
.


, AJAX, -
. -
ToDo , , -
.
- ToDo.
:
$button.on("click", function () {
var description = $input.val(),
tags = $tagInput.val().split(","),

1
callback hell, .
, , .
. .
254 9.

newToDo = {"description":description, "tags":tags};


$.post("todos", newToDo, function (result) {
//
//
toDoObjects = result;
//
toDos = toDoObjects.map(function (toDo) {
return toDo.description;
});
$input.val("");
$tagInput.val("");
});
});
-
, . ,
, -
, , . -
AJAX, , .
jQuery trigger
, :
$button.on("click", function () {
var description = $input.val(),
tags = $tagInput.val().split(","),
newToDo = {"description":description, "tags":tags};
$.post("todos", newToDo, function (result) {
//
$input.val("");
$tagInput.val("");
//
$(".tabs a:first span").trigger("click");
});
});

, ToDo:
app.post("/todos", function (req, res) {
var newToDo = new ToDo({"description":req.body.description,
"tags":req.body.tags});
newToDo.save(function (err, result) {
console.log(result);
if (err !== null) {
// !
console.log(err);
res.json(err);
} else {
res.json(result);
}
});
};
255

AJAX
,
, ,
. , , ,
, (
). ?
,
.
. , -
, .
, , -
.
, jQuery -
fail, AJAX. API -
, (
, ). ,
,
Mongoose Redis Node.js. -
, .
, null:
// content ,
//
tabs.push({
"name":"",
"content":function (callback) {
$.get("todos.json", function (toDoObjects) {
// $content ''
// ,
// null, $content
//
callback(null, $content);
}).fail(function (jqXHR, textStatus, error) {
//
// null $content
callback(error, null);
});
}
});
call . -
, .

, Mongoose Redis:
tab.content(function (err, $content) {
if (err !== null) {
alert(", : " + err);
256 9.

} else {
$("main .content").append($content);
}
});

,
( todos.json).
Not found.


. -
, -
. ,
(Model
View Controller).


server.js.
,
, ,
, . -
.

:
Mongoose server.js -
Node.js.
,
. -
todo.js models, Amazeriffic.
, , :
var mongoose = require("mongoose");
// mongoose
var ToDoSchema = mongoose.Schema({
description: String,
tags: [ String ]
});
var ToDo = mongoose.model("ToDo", ToDoSchema);
module.exports = ToDo;

(require) server.js
ToDo, :
var express = require("express"),
http = require("http"),
257

mongoose = require("mongoose"),
// ToDo
ToDo = require("./models/todo.js"),
app = express();

, ,
.

:

. , , -
, todo.js -
models. , -
, controllers.
get post Express, -
.
. -
,
Express.
: index create.
controllers , models,
todos_controller.js.
ToDo ToDosController. , -
, server.js:
// , ,
// models
var ToDo = require("../models/todo.js"),
ToDosController = {};
ToDosController.index = function (req, res) {
ToDo.find({}, function (err, toDos) {
res.json(toDos);
});
};
ToDosController.create = function (req, res) {
var newToDo = new ToDo({"description":req.body.description,
"tags":req.body.tags});
newToDo.save(function (err, result) {
console.log(result);
if (err !== null) {
// !
console.log(err);
res.json(500, err);
} else {
res.json(200, result);
}
});
};
module.exports = ToDosController;
258 9.

, , server.
js require. , route , -
, . , ,
ToDo server.js ,
require :
var express = require("express"),
http = require("http"),
mongoose = require("mongoose"),
// ToDoController
ToDosController = require("./controllers/todos_controller.js"),
app = express();
// setup/Cloud Foundry/mongoose
//
app.get("/todos.json", ToDosController.index);
app.post("/todos", ToDosController.create);

, ,
. server.js -
,
, , , -
.
,
HTTP- .

HTTP, CRUD REST


6 HTTP. ,
HTTP: GET POST. -
get post Express, , ,
, . , , HTTP
, : PUT DELETE.
,
7 (.9.1).

9.1. HTTP, CRUD


HTTP CRUD
POST () Create () create ()
ID
GET () Read () show ()
ID
PUT () Update () update () -
ID
DELETE () Delete () destroy () -
ID

API,
, . API, -
259

, -
REST (RESTful web APIs). REST Representational State Transfer (-
) , , -
- HTTP.

ID
, Express,
. ,
. , ,
- ID MongoDB:
//
app.get("/todos.json", ToDosController.index);
// CRUD
app.get("/todos/:id", ToDosController.show);
app.post("/todos", ToDosController.create);

get .
show . , -
(:) . ,
/todos/. ,
/todos/helloworld, show
. , -
ID, helloworld.
,
? , params.
: -
. ID, -
:
ToDosController.show = function (req, res) {
// ID, URL
var id = req.params.id;
// ID
ToDo.find({"_id":id}, function (err, todo) {
if (err !== null) {
res.json(err);
} else {
if (todo.length > 0) {
res.json(todo[0]);
} else {
res.send(" ");
}
}
});
};
260 9.

, - ;
, , MongoDB
ID:
vagrant $ mongo
MongoDB shell version: 2.4.7
connecting to: test
> show dbs
amazeriffic 0.0625GB
local 0.03125GB
> use amazeriffic
switched to db amazeriffic
> show collections
system.indexes
todos
> db.todos.find()
{ "description" : "first", "_id" : ObjectId("5275643e0cff128714000001"), ... }
{ "description" : "second", "_id" : ObjectId("52756de289f2f5f014000001"), ... }
{ "description" : "test", "_id" : ObjectId("5275722a8d735d0015000001"), ... }
{ "description" : "hello", "_id" : ObjectId("5275cbdcd408d04c15000001"), ... }
, _id, , Chrome -
- http://localhost:3000/5275643e0cff128714000001
. , JSON, .

ID ( , 24
a f), ,
ID. -
.

jQuery

jQuery put delete


$.ajax. get post:
// PUT jQuery
// ToDo
// id 1234
$.ajax({
"url" : "todos/1234",
"type": "PUT",
"data": {"description":" "},
}).done(function (response) {
// !
}).fail(function (err) {
// !
261

});
// jQuery
// ToDo c id, 1234
$.ajax({
"url" : "todos/1234",
"type": "DELETE",
}).done(function (response) {
// !
}).fail(function (err) {
// !
});

-
( ,
).

HTTP
HTTP ,
CRUD, ,
HTTP. , , -
404, , ,
. , 404
, HTTP.
HTTP 200, , ,
500, . Express -
. ,
show , -
HTTP:
ToDosController.show = function (req, res) {
// id, URL
var id = req.params.id;
ToDo.find({"_id":id}, function (err, todo) {
if (err !== null) {
//
res.json(500, err);
} else {
if (todo.length > 0) {
// !
res.json(200, todo[0]);
} else {
// ID!
res.send(404);
}
}
});
};
262 9.

ID , ,
Chrome , -
404 HTTP.


--
(Model
View Controller (MVC)). ,
, ,
-.
-,
.
Amazeriffic ,
,
.
, , .
HTTP- ,
. , ,
, , -
( ) (view).
show ID (
), ( JSON) ,
.
. , -

Mongoose. Rails ,
Active Record Mongoose . ToDo
, , ,
. ,
, ,
.
, -
. HTML CSS -
. JSON , ,
. , , .
, MVC ,
HTML . JavaScript
Node.js : Jade EJS.
, :
HTTP . ( server.js) -
, . -
,
, .
, . .9.1.

. 9.1.
263
264 9.

. , -
.

Amazeriffic
Amazeriffic : ToDo
. , , , -
, .
,
, ? , -
.


. User
, , ID MongoDB
. ID
ToDo, , -
, .
Mongoose
. user.js models.
Mongoose. , , Mongoose -
Node.js, statement:
var mongoose = require("mongoose");
// Mongoose
var UserSchema = mongoose.Schema({
username: String,
});
var User = mongoose.model("User", UserSchema);
module.exports = User;
ToDo, -
. ToDo User.


. ,
-,
. CRUD, index,
-:
var User = require("../models/user.js"),
mongoose = require("mongoose");
var UsersController = {};
UsersController.index = function (req, res) {
console.log(" : ");
res.send(200);
Amazeriffic 265

};
//
UsersController.show = function (req, res) {
console.log(" : ");
res.send(200);
};
//
UsersController.create = function (req, res) {
console.log(" : ");
res.send(200);
};
//
UsersController.update = function (req, res) {
console.log(" : ");
res.send(200);
};
//
UsersController.destroy = function (req, res) {
console.log("destroy action called");
res.send(200);
};
module.exports = UsersController;

,
ToDoController. -
, User
, ToDo.
-
, :
// ,
User.find({}, function (err, result) {
if (err !== null) {
console.log("- ");
console.log(err);
} else if (result.length === 0) {
console.log(" ");
var exampleUser = new User({"username":""});
exampleUser.save(function (err, result) {
if (err) {
console.log(err);
} else {
console.log(" ");
}
});
}
});

. -
,
.
266 9.


, .
HTTP/
User , . server.js
, HTTP :
app.get("/users.json", usersController.index);
app.post("/users", usersController.create);
app.get("/users/:username", usersController.show);
app.put("/users/:username", usersController.update);
app.del("/users/:username", usersController.destroy);

, Express del delete HTTP


DELETE. , delete JavaScript .


, .9.2.

9.2.

GET /users/semmy/ Amazeriffic
GET /users/semmy/todos.json ToDo
POST /users/semmy/todos ToDo
PUT /users/semmy/todos/[id] ToDo ID
DELETE /users/semmy/todos/[id] ToDo ID

, ,
ToDo, ,
. ?
, users/:username,
ToDoController:
app.get("/users/:username/todos.json", toDosController.index);
app.post("/users/:username/todos", toDosController.create);
app.put("/users/:username/todos/:id", toDosController.update);
app.del("/users/:username/todos/:id", toDosController.destroy);

, , -
.
index.html .
show. ,
show view. , -
,
index.html Express,
sendfile:
Amazeriffic 267

UsersController.show = function (req, res) {


console.log("show action called");
// HTML,
res.sendfile("./client/index.html");
};

localhost:3000/users/semmy/,
, , ,
. ,
.
. localhost:3000/users/
hello/. , hello -
! 404,
. ,
, . show
:
UsersController.show = function (req, res) {
console.log("show action called");
User.find({"username":req.params.username}, function (err, result) {
if (err) {
console.log(err);
res.send(500, err);
} else if (result.length !== 0) {
//
res.sendfile("./client/index.html");
} else {
// ,
// 404
res.send(404);
}
});
};

, -
, .

ToDo
, -
User ToDo .
ToDo , ToDo .
ToDo ObjectID, -
Users.
, ,
- .
ToDo ,
User:
268 9.

var mongoose = require("mongoose"),


ToDoSchema,
ObjectId = mongoose.Schema.Types.ObjectId;
ToDoSchema = mongoose.Schema({
description: String,
tags: [ String ],
owner : { type: ObjectId, ref: "User" }
});
module.exports.ToDo = mongoose.model("ToDo", ToDoSchema);

, ToDo, null,
(, ,
).
ToDo,
, .
index ,
, :
ToDosController.index = function (req, res) {
var username = req.params.username || null,
respondWithToDos;
// , ToDo,
//
respondWithToDos = function (query) {
ToDo.find(query, function (err, toDos) {
if (err !== null) {
res.json(500,err);
} else {
res.json(200,toDos);
}
});
};
if (username !== null) {
// ,
User.find({"username":username}, function (err, result) {
if (err !== null) {
res.json(500, err);
} else if (result.length === 0) {
// ID!
res.send(404);
} else {
//
respondWithToDos({ "owner" : result[0].id });
}
});
} else {
//
respondWithToDos({});
}
};
269

, create , -
ToDo, :
ToDosController.create = function (req, res) {
var username = req.params.username || null,
newToDo = new ToDo({"description":req.body.description,
"tags":req.body.tags});
User.find({"username":username}, function (err, result) {
if (err) {
res.send(500);
} else {
if (result.length === 0) {
// ,
// ToDo
newToDo.owner = null;
} else {
// ,
//
// ID
newToDo.owner = result[0]._id;
}
newToDo.save(function (err, result) {
if (err !== null) {
res.json(500, err);
} else {
res.json(200, result);
}
});
}
});
};

, owner null, -
, _id,
. , ,
,
. localhost:3000,
.


- , ,
.
. -
-
. , ,
- , .
, .
270 9.

-
.
, -
- .
,
. -
--
. , -
,
. Ruby on Rails.
MVC ,
- . -
(HTML, CSS JavaScript
).
, -
.
--
- RESTful. (
) URL . -
URL, -
HTTP, .



, ,
. destroy ToDo -
ID. ,
.
? -
, ToDo todos.json. -
description -
. , _id .
, , , , -
:
"content":function (callback) {
$.get("todos.json", function (toDoObjects) {
var $content = $("<ul>");
// $content ""
toDoObjects.forEach(function (toDo) {
$content.append($("<li>").text(todo.description));
});
// $content
271

callback($content);
});
}
li ToDo.
li , -
. , DOM
HTML :
<li> ToDo <a href="todos/5275643e0cff128714000001"></a></li>
, $content:
var $todoListItem = $("<li>").text(todo.description),
$todoRemoveLink = $("<a>").attr("href", "todos/"+todo._id);
//
$todoListItem.append($todoRemoveLink)
$content.append($todoListItem);
, :
var $todoListItem = $("<li>").text(todo.description),
$todoRemoveLink = $("<a>").attr("href", "todos/"+todo._id);
$todoRemoveLink.on("click", function () {
$.ajax({
// delete HTTP
}).done(function () {
// ,
// DOM
});
// false,
return false;
});
//
$todoListItem.append($todoRemoveLink)
$content.append($todoListItem);
- ,
!

, -
. , -
, , -
. ,
JavaScript -
. , users.html,
users.js, javascripts. -
CSS ,
272 9.

style.css stylesheets.
.
,
, . ,
destroy . -

.
, ,
.

EJS Jade
, , MVC Node.js,
. ,
,
AJAX.
,
Jade EJS. HTML
, -
Express.


.
. , ,
. , ,
Twitter.
,
.

Ruby on Rails
, ,
Ruby on Rails,
-. , , -
, Rails .
-
Rails. , ,
.

Оценить