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

Preview:

Citation preview

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

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

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

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

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

— ОС: WebOS, Firefox OS, Chrome OS

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

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

2

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

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

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

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

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

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

4

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

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

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

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

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

5

Простейший 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

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

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

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

больше»

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

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

7

Что такое jQuery?

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

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

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

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

Google, Mozilla)

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

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

9

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

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

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

— jQuery === $

10

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

Поиск элементов<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

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

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

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

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

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

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

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

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

Итерирование по результатамВариант №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

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

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

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

elemsList.forEach(function(elem) {

});

01.

02.

03.

04.

05.

22

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

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

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

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

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

var $item = $(this);

});

01.

02.

03.

25

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

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

Атрибуты и свойства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

*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

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

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

$form.removeAttr('method');

01.

02.

03.

30

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

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

Атрибуты !== свойства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

Атрибуты !== свойства$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

Классы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

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

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

$form.removeClass('form');

01.

02.

03.

36

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

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

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

id: "auth-error",

class: ["error"],

foo: "bar",

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

}).appendTo(document.body);

01.

02.

03.

04.

05.

06.

39

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

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

События

Все элементы 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

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

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

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

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

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

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

45

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

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

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

var $button = $('button');

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

.on('click', yetClickHandler);

01.

02.

01.

02.

03.

47

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

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

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

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

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

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

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

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

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

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

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

01.

02.

03.

54

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

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

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

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

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

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

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

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

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

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

01.

02.

03.

61

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

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

event.stopPropagation();

}, true);

01.

02.

03.

04.

62

stopPropagation

stopPropagation

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

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

event.stopPropagation();

}, false);

01.

02.

03.

04.

65

stopPropagation

stopPropagation

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

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

event.stopImmediatePropagation();

}, false);

01.

02.

03.

04.

68

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

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

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

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

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

return false в теле

обработчика

Подключение 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

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

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

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

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

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

75

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

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

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

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

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

76

Спасибоdench@yandex-team.ru

twitter.com/denchistyakov