Transcript
Page 1: Денис Чистяков: DOM, jQuery и все, все, все

DOM, jQuery и всевсе все

На Яндеск.Диске yadi.sk/d/4PUvH1NwAKes2

На JsFiddle jsfiddle.net/dench/RHtRZ/8/

Page 2: Денис Чистяков: DOM, jQuery и все, все, все

Среда выполнения— JavaScript !== Браузер

— Браузер в том числе

— ОС: WebOS, Firefox OS, Chrome OS

— Сервер: Node.JS, SpiderMonkey, Rhino

— Офисные приложения: MS Office, OpenOffice

2

Page 3: Денис Чистяков: DOM, jQuery и все, все, все

Различные средыпредоставляют различный API

для работы с ними

Page 4: Денис Чистяков: DOM, jQuery и все, все, все

DOM— Document Object Model — это API, для чтения и редактирования

содержимомого HTML и XML-документов

— Это дерево, узлами которого могут быть элементы, текст,

комментарии, атрибуты и другие

4

Page 5: Денис Чистяков: DOM, jQuery и все, все, все

Что позволяет нам DOM?— Получать доступ к узлу или набору узлов

— Обход дерева

— Изменять атрибуты узла

— Добавлять / удалять / клонировать узлы

— Обрабатывать события на узлах

5

Page 6: Денис Чистяков: DOM, jQuery и все, все, все

Простейший DOM<!DOCTYPE html><html lang="ru">

<head><title>DOM</title></head>

<body>

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

06.

07.

08.

6

Page 7: Денис Чистяков: DOM, jQuery и все, все, все

Что такое jQuery?— JS-библиотека, призванная сделать код удобнее и более

кроссбраузерным

— Главный слоган „Write less, do more“ — «Пиши меньше, получай

больше»

— Всё API нацелено сделать код короче, понятнее и исправить

шороховатости в нативных реализациях

7

Page 8: Денис Чистяков: DOM, jQuery и все, все, все

Что такое jQuery?

— Был разработан и презентован Джоном Резигом в 2006

— Продолжает развиваться и сейчас

— Код постоянно претерпевает рефакторинг и оптимизации

Page 9: Денис Чистяков: DOM, jQuery и все, все, все

Что такое jQuery?— Используется практически всеми крупнейшими компаниями (Яндекс,

Google, Mozilla)

— Имеет обширное комьюнити и огромное количество plugin`ов

— Есть расширения для UI и мобильных приложений

9

Page 10: Денис Чистяков: DOM, jQuery и все, все, все

Волшебный $— Переменные в JS могут начинаться с букв и некоторых символов

— jQuery — одна из первых библиотек, начавших использовать $ в

качестве пространства имен

— jQuery === $

10

Page 11: Денис Чистяков: DOM, jQuery и все, все, все

Поиск элементов

Page 12: Денис Чистяков: DOM, jQuery и все, все, все

Поиск элементов<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

12

Page 13: Денис Чистяков: DOM, jQuery и все, все, все

getElementByIddocument.getElementById('auth');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

13

Page 14: Денис Чистяков: DOM, jQuery и все, все, все

getElementById$('#auth');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

14

Page 15: Денис Чистяков: DOM, jQuery и все, все, все

querySelectordocument.querySelector('.auth');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

15

Page 16: Денис Чистяков: DOM, jQuery и все, все, все

querySelector$('.auth');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

16

Page 17: Денис Чистяков: DOM, jQuery и все, все, все

querySelectordocument.querySelector('[name="login"]');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

17

Page 18: Денис Чистяков: DOM, jQuery и все, все, все

querySelector$('[name="login"]');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

18

Page 19: Денис Чистяков: DOM, jQuery и все, все, все

querySelectorAlldocument.querySelectorAll('input,button');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

19

Page 20: Денис Чистяков: DOM, jQuery и все, все, все

NodeList не Array Ó методовforEach, map и т.п. — нет!

Page 21: Денис Чистяков: DOM, jQuery и все, все, все

Итерирование по результатамВариант №1

var elems = document.querySelectorAll('input,button');

for (var i = 0, l = elems.length; i < l; i++) {

var elem = elems[i];

}

01.

02.

03.

04.

21

Page 22: Денис Чистяков: DOM, jQuery и все, все, все

Итерирование по результатамВариант №2

var elems = document.querySelectorAll('input,button');

var elemsList = Array.prototype.slice.call(elems);

elemsList.forEach(function(elem) {

});

01.

02.

03.

04.

05.

22

Page 23: Денис Чистяков: DOM, jQuery и все, все, все

querySelectorAll$(':input');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

03.

04.

05.

23

Page 24: Денис Чистяков: DOM, jQuery и все, все, все

Все методы поискавозвращают коллекции и

предоставляют методы для

итерирования по ним

Page 25: Денис Чистяков: DOM, jQuery и все, все, все

Итерирование по результатам$(':input').each(function(){

var $item = $(this);

});

01.

02.

03.

25

Page 26: Денис Чистяков: DOM, jQuery и все, все, все

Для поиска используетсябиблиотека Sizzle

Page 27: Денис Чистяков: DOM, jQuery и все, все, все

Атрибуты и свойства

Page 28: Денис Чистяков: DOM, jQuery и все, все, все

Атрибуты и свойстваvar form = document.getElementById('auth');

var $form = $(form);

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

01.

02.

03.

04.

05.

28

Page 29: Денис Чистяков: DOM, jQuery и все, все, все

*Attributeform.getAttribute('action'); >> "/"

form.hasAttribute('method', 'POST'); >> false

form.setAttribute('method', 'POST');

form.hasAttribute('method', 'POST'); >> true

form.removeAttribute('method');

01.

02.

03.

04.

05.

29

Page 30: Денис Чистяков: DOM, jQuery и все, все, все

*Attribute$form.attr('action'); >> "/"

$form.attr('method', 'POST');

$form.removeAttr('method');

01.

02.

03.

30

Page 31: Денис Чистяков: DOM, jQuery и все, все, все

Data-атрибутыform.dataset['value']; >> "123"

form.dataset.hasOwnProperty('value'); >> true

form.dataset.foo = 'bar';

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

01.

02.

03.

01.

02.

03.

04.

31

Page 32: Денис Чистяков: DOM, jQuery и все, все, все

Data-атрибуты$form.data('value'); >> "123"

$form.data('foo', 'bar');

<form class="auth" id="auth" data-value="123" action="/">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button>Отправить</button>

</form>

01.

02.

01.

02.

03.

04.

05.

32

Page 33: Денис Чистяков: DOM, jQuery и все, все, все

Атрибуты !== свойстваform.getAttribute('action'); >> "/"

form.getAttribute('method'); >> null

form.getAttribute('id'); >> "auth"

form.action; >> "http://fiddle.jshell.net/"

form.method; >> "get"

form.id; >> "auth"

01.

02.

03.

01.

02.

03.

33

Page 34: Денис Чистяков: DOM, jQuery и все, все, все

Атрибуты !== свойства$form.attr('action'); >> "/"

$form.attr('method'); >> undefined

$form.attr('id'); >> "auth"

$form.prop('action'); >> "http://fiddle.jshell.net/"

$form.prop('method'); >> "get"

$form.prop('id'; >> "auth"

01.

02.

03.

01.

02.

03.

34

Page 35: Денис Чистяков: DOM, jQuery и все, все, все

Классыform.className; >> "auth"

form.className += " form"; >> "auth form"

form.classList.add('foo');

form.classList.item(1); >> "form"

form.classList.contains('foo'); >> true

form.classList.remove('foo');

01.

02.

01.

02.

03.

04.

35

Page 36: Денис Чистяков: DOM, jQuery и все, все, все

Классы$form.addClass('form');

$form.hasClass('form'); >> true

$form.removeClass('form');

01.

02.

03.

36

Page 37: Денис Чистяков: DOM, jQuery и все, все, все

Создание и удаление элементов

Page 38: Денис Чистяков: DOM, jQuery и все, все, все

createElement + appendChildvar elem = document.createElement('span');

elem.className = 'error';

elem.setAttribute('id', 'auth-error');

elem.setAttribute('foo', 'bar');

elem.textContent = "Введен неверный логин или пароль";

document.body.appendChild(elem);

01.

02.

03.

04.

05.

06.

38

Page 39: Денис Чистяков: DOM, jQuery и все, все, все

createElement + appendChildvar $elem = $('<span>', {

id: "auth-error",

class: ["error"],

foo: "bar",

text: "Введен неверный логин или пароль"

}).appendTo(document.body);

01.

02.

03.

04.

05.

06.

39

Page 40: Денис Чистяков: DOM, jQuery и все, все, все

cloneNodevar elem = document.createElement('span');

var clone = elem.cloneNode(true)

clone.id = 'mail-error';

clone.textContent = "Не удалось отправить письмо";

document.body.appendChild(elem);

document.body.appendChild(clone);

01.

02.

03.

04.

05.

06.

07.

40

Page 41: Денис Чистяков: DOM, jQuery и все, все, все

cloneNodevar $body = $(document.body);

var $elem = $('<span>', {…});

var $clone = $elem.clone(true)

.prop('id', 'mail-error')

.text("Не удалось отправить письмо")

$body.append($elem).append($clone)

01.

02.

03.

04.

05.

06.

41

Page 42: Денис Чистяков: DOM, jQuery и все, все, все

События

Page 43: Денис Чистяков: DOM, jQuery и все, все, все

Все элементы DOM и jQueryмогут реагировать на те или

иные события

Page 44: Денис Чистяков: DOM, jQuery и все, все, все

Можно навешивать обработчики в HTML<form class="auth" id="auth"

data-value="123" action="/" onsubmit="submitHandler()">

<input type="text" value="" name="login">

<input type="password" value="" name="password">

<button onclick="clickHandler()">Отправить</button>

</form>

01.

02.

03.

04.

05.

06.

44

Page 45: Денис Чистяков: DOM, jQuery и все, все, все

Почему это плохо?— Нельзя навешать более одного обработчика на узел

— JS и HTML становятся тесно связаны

— Неинтуитивно

— При изменении HTML необходимо всегда помнить про атрибуты с

обработчиками

— Нельзя динамически навешивать обработчики

45

Page 46: Денис Чистяков: DOM, jQuery и все, все, все

addEventListenervar form = document.getElementById('auth');

form.addEventListener('submit', submitHandler);

var button = document.querySelector('button');

button.addEventListener('click', clickHandler);

button.addEventListener('click', yetClickHandler);

01.

02.

01.

02.

03.

46

Page 47: Денис Чистяков: DOM, jQuery и все, все, все

addEventListenervar $form = $('#auth');

$form.on('submit', submitHandler);

var $button = $('button');

$button.on('click', clickHandler);

.on('click', yetClickHandler);

01.

02.

01.

02.

03.

47

Page 48: Денис Чистяков: DOM, jQuery и все, все, все

Существует два подхода

— Перехват событий (Capturing)

— Всплывающие события (Bubbling)

Page 49: Денис Чистяков: DOM, jQuery и все, все, все

Перехват событий (Capturing)

Page 50: Денис Чистяков: DOM, jQuery и все, все, все

Перехват событий (Capturing)

Page 51: Денис Чистяков: DOM, jQuery и все, все, все

Перехват событий (Capturing)

Page 52: Денис Чистяков: DOM, jQuery и все, все, все

Перехват событий (Capturing)

Page 53: Денис Чистяков: DOM, jQuery и все, все, все

Перехват событий (Capturing)

Page 54: Денис Чистяков: DOM, jQuery и все, все, все

addEventListenervar button = document.querySelector('button');

button.addEventListener('click', clickHandler, true);

button.addEventListener('click', yetClickHandler, true);

01.

02.

03.

54

Page 55: Денис Чистяков: DOM, jQuery и все, все, все

Всплывающие события (Bubbling)

Page 56: Денис Чистяков: DOM, jQuery и все, все, все

Всплывающие события (Bubbling)

Page 57: Денис Чистяков: DOM, jQuery и все, все, все

Всплывающие события (Bubbling)

Page 58: Денис Чистяков: DOM, jQuery и все, все, все

Всплывающие события (Bubbling)

Page 59: Денис Чистяков: DOM, jQuery и все, все, все

Всплывающие события (Bubbling)

Page 60: Денис Чистяков: DOM, jQuery и все, все, все

В jQuery все событиявсплывающие из соображений

кроссбраузерности

Page 61: Денис Чистяков: DOM, jQuery и все, все, все

addEventListenervar button = document.querySelector('button');

button.addEventListener('click', clickHandler, false);

button.addEventListener('click', yetClickHandler, false);

01.

02.

03.

61

Page 62: Денис Чистяков: DOM, jQuery и все, все, все

stopPropagationvar button = document.querySelector('button');

button.addEventListener('click', function(event) {

event.stopPropagation();

}, true);

01.

02.

03.

04.

62

Page 63: Денис Чистяков: DOM, jQuery и все, все, все

stopPropagation

Page 64: Денис Чистяков: DOM, jQuery и все, все, все

stopPropagation

Page 65: Денис Чистяков: DOM, jQuery и все, все, все

stopPropagationvar button = document.querySelector('button');

button.addEventListener('click', function(event) {

event.stopPropagation();

}, false);

01.

02.

03.

04.

65

Page 66: Денис Чистяков: DOM, jQuery и все, все, все

stopPropagation

Page 67: Денис Чистяков: DOM, jQuery и все, все, все

stopPropagation

Page 68: Денис Чистяков: DOM, jQuery и все, все, все

stopImmediatePropagationvar button = document.querySelector('button');

button.addEventListener('click', function(event) {

event.stopImmediatePropagation();

}, false);

01.

02.

03.

04.

68

Page 69: Денис Чистяков: DOM, jQuery и все, все, все

У многих элементов естьдействия по умолчанию

Page 70: Денис Чистяков: DOM, jQuery и все, все, все

preventDefaultvar link = document.querySelector('a');

link.addEventListener('click', function(event) {

console.log(this);

}, false);

<a href="http://yandex.ru">Yandex</a>

01.

02.

03.

04.

70

Page 71: Денис Чистяков: DOM, jQuery и все, все, все

preventDefaultvar link = document.querySelector('a');

link.addEventListener('click', function(event) {

event.preventDefault();

console.log(this);

}, false);

<a href="http://yandex.ru">Yandex</a>

01.

02.

03.

04.

05.

71

Page 72: Денис Чистяков: DOM, jQuery и все, все, все

В jQuery методы такжедоступны у объекта события

Page 73: Денис Чистяков: DOM, jQuery и все, все, все

В jQuery этого же эффектаможно достигнуть, выполнив

return false в теле

обработчика

Page 74: Денис Чистяков: DOM, jQuery и все, все, все

Подключение jQuery на странице<!DOCTYPE html><html lang="ru">

<head><title>jQuery</title></head>

<body>

<form class="auth" id="auth" data-value="123" action="/">

</form>

<script src="//yandex.st/jquery/2.0.3/jquery.min.js">

</script>

</body></html>

01.

02.

03.

04.

05.

06.

07.

08.

74

Page 75: Денис Чистяков: DOM, jQuery и все, все, все

jQuery tips and tricks— Называйте jQuery-переменные, начиная с $

— Всегда кэшируйте результаты селекторов

— Используйте live-события по возможности

— Посмотрите „30 Days to Learn jQuery“

— Используйте map, grep, proxy и другие утилиты

75

Page 76: Денис Чистяков: DOM, jQuery и все, все, все

Мы научились— Получать доступ к узлу или набору узлов

— Обход дерева

— Изменять атрибуты узла

— Добавлять / удалять / клонировать узлы

— Обрабатывать события на узлах

76