final move to png
|
@ -64,7 +64,7 @@ JavaScript -- быстрый и мощный язык, но браузер на
|
||||||
|
|
||||||
**Большинство возможностей JavaScript в браузере ограничено текущим окном и страницей.**
|
**Большинство возможностей JavaScript в браузере ограничено текущим окном и страницей.**
|
||||||
|
|
||||||
<img src="limitations.svg" width="530" height="400">
|
<img src="limitations.png" width="530" height="400">
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>JavaScript не может читать/записывать произвольные файлы на жесткий диск, копировать их или вызывать программы. Он не имеет прямого доступа к операционной системе.
|
<li>JavaScript не может читать/записывать произвольные файлы на жесткий диск, копировать их или вызывать программы. Он не имеет прямого доступа к операционной системе.
|
||||||
|
|
|
@ -52,7 +52,7 @@ var user = 'John', age = 25, message = 'Hello';
|
||||||
|
|
||||||
Например, переменная `message` -- это коробка, в которой хранится значение `"Hello!"`:
|
Например, переменная `message` -- это коробка, в которой хранится значение `"Hello!"`:
|
||||||
|
|
||||||
<img src="variable.svg">
|
<img src="variable.png">
|
||||||
|
|
||||||
В коробку можно положить любое значение, а позже - поменять его. Значение в переменной можно изменять сколько угодно раз:
|
В коробку можно положить любое значение, а позже - поменять его. Значение в переменной можно изменять сколько угодно раз:
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ alert( message );
|
||||||
|
|
||||||
При изменении значения старое содержимое переменной удаляется.
|
При изменении значения старое содержимое переменной удаляется.
|
||||||
|
|
||||||
<img src="variable-change.svg">
|
<img src="variable-change.png">
|
||||||
|
|
||||||
Можно объявить две переменные и копировать данные из одной в другую:
|
Можно объявить две переменные и копировать данные из одной в другую:
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
Шпаргалка с правилами синтаксиса (детально их варианты разобраны далее):
|
Шпаргалка с правилами синтаксиса (детально их варианты разобраны далее):
|
||||||
|
|
||||||
<img src="code-style.svg">
|
<img src="code-style.png">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
```js
|
```js
|
||||||
|
@ -57,7 +57,7 @@ if (n < 0) {
|
||||||
```
|
```
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<img src="figure-bracket-style.svg">
|
<img src="figure-bracket-style.png">
|
||||||
|
|
||||||
Если у вас уже есть опыт в разработке, и вы привыкли делать скобку на отдельной строке -- это тоже вариант. В конце концов, решать вам. Но в большинстве JavaScript-фреймворков стиль именно такой.
|
Если у вас уже есть опыт в разработке, и вы привыкли делать скобку на отдельной строке -- это тоже вариант. В конце концов, решать вам. Но в большинстве JavaScript-фреймворков стиль именно такой.
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
Её можно легко представить как шкаф с подписанными ящиками. Все данные хранятся в ящичках. По имени можно легко найти ящик и взять то значение, которое в нём лежит.
|
Её можно легко представить как шкаф с подписанными ящиками. Все данные хранятся в ящичках. По имени можно легко найти ящик и взять то значение, которое в нём лежит.
|
||||||
|
|
||||||
<img src="object.svg">
|
<img src="object.png">
|
||||||
|
|
||||||
В отличие от реальных шкафов, в ассоциативный массив можно в любой момент добавить новые именованные "ящики" или удалить существующие. Далее мы увидим примеры, как это делается.
|
В отличие от реальных шкафов, в ассоциативный массив можно в любой момент добавить новые именованные "ящики" или удалить существующие. Далее мы увидим примеры, как это делается.
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
var person = {}; // пока пустой
|
var person = {}; // пока пустой
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="object-person-empty.svg">
|
<img src="object-person-empty.png">
|
||||||
|
|
||||||
|
|
||||||
Основные операции с объектами -- это создание, получение и удаление свойств.
|
Основные операции с объектами -- это создание, получение и удаление свойств.
|
||||||
|
@ -55,7 +55,7 @@ person.name = 'Вася';
|
||||||
person.age = 25; // запишем ещё одно свойство: с именем 'age' и значением 25
|
person.age = 25; // запишем ещё одно свойство: с именем 'age' и значением 25
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="object-person-1.svg">
|
<img src="object-person-1.png">
|
||||||
|
|
||||||
Значения хранятся "внутри" ящиков. Обратим внимание -- любые значения, любых типов: число, строка -- не важно.
|
Значения хранятся "внутри" ящиков. Обратим внимание -- любые значения, любых типов: число, строка -- не важно.
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ delete person.age;
|
||||||
|
|
||||||
Осталось только свойство `name`:
|
Осталось только свойство `name`:
|
||||||
|
|
||||||
<img src="object-person-2.svg">
|
<img src="object-person-2.png">
|
||||||
|
|
||||||
Следующая операция:
|
Следующая операция:
|
||||||
<ol start="4">
|
<ol start="4">
|
||||||
|
|
|
@ -15,7 +15,7 @@ var phrase = message;
|
||||||
|
|
||||||
В результате такого копирования получились две полностью независимые переменные, в каждой из которых хранится значение `"Привет"`.
|
В результате такого копирования получились две полностью независимые переменные, в каждой из которых хранится значение `"Привет"`.
|
||||||
|
|
||||||
<img src="variable-copy-value.svg">
|
<img src="variable-copy-value.png">
|
||||||
|
|
||||||
## Копирование по ссылке
|
## Копирование по ссылке
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ var user = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="variable-contains-reference.svg">
|
<img src="variable-contains-reference.png">
|
||||||
|
|
||||||
Внимание: объект -- вне переменной. В переменной -- лишь "адрес" (ссылка) для него.
|
Внимание: объект -- вне переменной. В переменной -- лишь "адрес" (ссылка) для него.
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ var admin = user; // скопировали ссылку
|
||||||
|
|
||||||
Получили две переменные, в которых находятся ссылки на один и тот же объект:
|
Получили две переменные, в которых находятся ссылки на один и тот же объект:
|
||||||
|
|
||||||
<img src="variable-copy-reference.svg">
|
<img src="variable-copy-reference.png">
|
||||||
|
|
||||||
**Так как объект всего один, то изменения через любую переменную видны в других переменных:**
|
**Так как объект всего один, то изменения через любую переменную видны в других переменных:**
|
||||||
|
|
||||||
|
|
|
@ -84,13 +84,13 @@ alert( arr[2].name ); // Петя
|
||||||
|
|
||||||
Одно из применений массива -- это [очередь](http://ru.wikipedia.org/wiki/%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29). В классическом программировании так называют упорядоченную коллекцию элементов, такую что элементы добавляются в конец, а обрабатываются -- с начала.
|
Одно из применений массива -- это [очередь](http://ru.wikipedia.org/wiki/%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29). В классическом программировании так называют упорядоченную коллекцию элементов, такую что элементы добавляются в конец, а обрабатываются -- с начала.
|
||||||
|
|
||||||
<img src="queue.svg">
|
<img src="queue.png">
|
||||||
|
|
||||||
В реальной жизни эта структура данных встречается очень часто. Например, очередь сообщений, которые надо показать на экране.
|
В реальной жизни эта структура данных встречается очень часто. Например, очередь сообщений, которые надо показать на экране.
|
||||||
|
|
||||||
Очень близка к очереди еще одна структура данных: [стек](http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA). Это такая коллекция элементов, в которой новые элементы добавляются в конец и берутся с конца.
|
Очень близка к очереди еще одна структура данных: [стек](http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA). Это такая коллекция элементов, в которой новые элементы добавляются в конец и берутся с конца.
|
||||||
|
|
||||||
<img src="stack.svg">
|
<img src="stack.png">
|
||||||
|
|
||||||
Например, стеком является колода карт, в которую новые карты кладутся сверху, и берутся -- тоже сверху.
|
Например, стеком является колода карт, в которую новые карты кладутся сверху, и берутся -- тоже сверху.
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ alert( a ); // 0,,,,,5
|
||||||
|
|
||||||
Методы `push/pop` выполняются быстро, а `shift/unshift` -- медленно.
|
Методы `push/pop` выполняются быстро, а `shift/unshift` -- медленно.
|
||||||
|
|
||||||
<img src="array-speed.svg">
|
<img src="array-speed.png">
|
||||||
|
|
||||||
|
|
||||||
Чтобы понять, почему работать с концом массива -- быстрее, чем с его началом, разберём подробнее происходящее при операции:
|
Чтобы понять, почему работать с концом массива -- быстрее, чем с его началом, разберём подробнее происходящее при операции:
|
||||||
|
@ -243,7 +243,7 @@ fruits.shift(); // убрать 1 элемент с начала
|
||||||
<li>Обновить свойство `length`.</li>
|
<li>Обновить свойство `length`.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<img src="array-shift.svg">
|
<img src="array-shift.png">
|
||||||
|
|
||||||
**Чем больше элементов в массиве, тем дольше их перемещать, это много операций с памятью.**
|
**Чем больше элементов в массиве, тем дольше их перемещать, это много операций с памятью.**
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ fruits.shift(); // убрать 1 элемент с начала
|
||||||
fruits.pop(); // убрать 1 элемент с конца
|
fruits.pop(); // убрать 1 элемент с конца
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="array-pop.svg">
|
<img src="array-pop.png">
|
||||||
|
|
||||||
**Перемещать при `pop` не требуется, так как прочие элементы после этой операции остаются на тех же индексах.**
|
**Перемещать при `pop` не требуется, так как прочие элементы после этой операции остаются на тех же индексах.**
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ var list = {
|
||||||
```
|
```
|
||||||
|
|
||||||
Графическое представление этого списка:
|
Графическое представление этого списка:
|
||||||
<img src="linked-list.svg">
|
<img src="linked-list.png">
|
||||||
|
|
||||||
Альтернативный способ создания:
|
Альтернативный способ создания:
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ alert( result ); // 15
|
||||||
|
|
||||||
Поток вычислений получается такой
|
Поток вычислений получается такой
|
||||||
|
|
||||||
<img src="reduce.svg">
|
<img src="reduce.png">
|
||||||
|
|
||||||
В виде таблицы где каждая строка -- вызов функции на очередном элементе массива:
|
В виде таблицы где каждая строка -- вызов функции на очередном элементе массива:
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ var family = marry({
|
||||||
|
|
||||||
Получившийся объект `family` можно изобразить так:
|
Получившийся объект `family` можно изобразить так:
|
||||||
|
|
||||||
<img src="family.svg">
|
<img src="family.png">
|
||||||
|
|
||||||
Здесь стрелочками показаны ссылки, а вот свойство `name` ссылкой не является, там хранится примитив, поэтому оно внутри самого объекта.
|
Здесь стрелочками показаны ссылки, а вот свойство `name` ссылкой не является, там хранится примитив, поэтому оно внутри самого объекта.
|
||||||
|
|
||||||
|
@ -115,13 +115,13 @@ delete family.mother.husband;
|
||||||
|
|
||||||
А если две, то получается, что от бывшего `family.father` ссылки выходят, но в него -- ни одна не идёт:
|
А если две, то получается, что от бывшего `family.father` ссылки выходят, но в него -- ни одна не идёт:
|
||||||
|
|
||||||
<img src="family-no-father.svg">
|
<img src="family-no-father.png">
|
||||||
|
|
||||||
**Совершенно неважно, что из объекта выходят какие-то ссылки, они не влияют на достижимость этого объекта.**
|
**Совершенно неважно, что из объекта выходят какие-то ссылки, они не влияют на достижимость этого объекта.**
|
||||||
|
|
||||||
Бывший `family.father` стал недостижимым и будет удалён вместе со своми данными, которые также более недоступны из программы.
|
Бывший `family.father` стал недостижимым и будет удалён вместе со своми данными, которые также более недоступны из программы.
|
||||||
|
|
||||||
<img src="family-no-father-2.svg">
|
<img src="family-no-father-2.png">
|
||||||
|
|
||||||
А теперь -- рассмотрим более сложный случай. Что будет, если удалить главную ссылку `family`?
|
А теперь -- рассмотрим более сложный случай. Что будет, если удалить главную ссылку `family`?
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ window.family = null;
|
||||||
|
|
||||||
Результат:
|
Результат:
|
||||||
|
|
||||||
<img src="family-no-family.svg">
|
<img src="family-no-family.png">
|
||||||
|
|
||||||
Как видим, объекты в конструкции всё ещё связаны между собой. Однако, поиск от корня их не находит, они не достижимы, и значит сборщик мусора удалит их из памяти.
|
Как видим, объекты в конструкции всё ещё связаны между собой. Однако, поиск от корня их не находит, они не достижимы, и значит сборщик мусора удалит их из памяти.
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ setTimeout(function run() {
|
||||||
|
|
||||||
При `setInterval` внутренний таймер будет срабатывать чётко каждые `100` мс и вызывать `func(i)`:
|
При `setInterval` внутренний таймер будет срабатывать чётко каждые `100` мс и вызывать `func(i)`:
|
||||||
|
|
||||||
<img src="setinterval-interval.svg">
|
<img src="setinterval-interval.png">
|
||||||
|
|
||||||
Вы обратили внимание?...
|
Вы обратили внимание?...
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ setTimeout(function run() {
|
||||||
|
|
||||||
А так будет выглядить картинка с рекурсивным `setTimeout`:
|
А так будет выглядить картинка с рекурсивным `setTimeout`:
|
||||||
|
|
||||||
<img src="settimeout-interval.svg">
|
<img src="settimeout-interval.png">
|
||||||
|
|
||||||
**При рекурсивном `setTimeout` задержка всегда фиксирована и равна 100мс.**
|
**При рекурсивном `setTimeout` задержка всегда фиксирована и равна 100мс.**
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ alert( rabbit.eats ); // true
|
||||||
|
|
||||||
Иллюстрация происходящего при чтении `rabbit.eats` (поиск идет снизу вверх):
|
Иллюстрация происходящего при чтении `rabbit.eats` (поиск идет снизу вверх):
|
||||||
|
|
||||||
<img src="proto-animal-rabbit.svg">
|
<img src="proto-animal-rabbit.png">
|
||||||
|
|
||||||
**Объект, на который указывает ссылка `__proto__`, называется *"прототипом"*. В данном случае получилось, что `animal` является прототипом для `rabbit`.**
|
**Объект, на который указывает ссылка `__proto__`, называется *"прототипом"*. В данном случае получилось, что `animal` является прототипом для `rabbit`.**
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ alert( {}.__proto__.toString ); // function toString
|
||||||
<li>В дальнейшем при обращении к `obj.toString()` -- функция будет взята из `Object.prototype`.</li>
|
<li>В дальнейшем при обращении к `obj.toString()` -- функция будет взята из `Object.prototype`.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<img src="native-prototypes-object.svg">
|
<img src="native-prototypes-object.png">
|
||||||
|
|
||||||
Это можно легко проверить:
|
Это можно легко проверить:
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ alert( obj.__proto__.__proto__ ); // null, нет
|
||||||
|
|
||||||
Точно такой же подход используется в массивах `Array`, функциях `Function` и других объектах. Встроенные методы для них находятся в `Array.prototype`, `Function.prototype` и т.п.
|
Точно такой же подход используется в массивах `Array`, функциях `Function` и других объектах. Встроенные методы для них находятся в `Array.prototype`, `Function.prototype` и т.п.
|
||||||
|
|
||||||
<img src="native-prototypes-classes.svg">
|
<img src="native-prototypes-classes.png">
|
||||||
|
|
||||||
Например, когда мы создаём массив, `[1, 2, 3]`, то это альтернативный вариант синтаксиса `new Array`, так что у массивов есть стандартный прототип `Array.prototype`.
|
Например, когда мы создаём массив, `[1, 2, 3]`, то это альтернативный вариант синтаксиса `new Array`, так что у массивов есть стандартный прототип `Array.prototype`.
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ alert( arr ); // 1,2,3 <-- результат Array.prototype.toString
|
||||||
|
|
||||||
Как мы видели раньше, у `Object.prototype` есть свой `toString`, но так как в `Array.prototype` он ищется первым, то берётся именно вариант для массивов:
|
Как мы видели раньше, у `Object.prototype` есть свой `toString`, но так как в `Array.prototype` он ищется первым, то берётся именно вариант для массивов:
|
||||||
|
|
||||||
<img src="native-prototypes-array-tostring.svg">
|
<img src="native-prototypes-array-tostring.png">
|
||||||
|
|
||||||
|
|
||||||
[smart header="Вызов методов через `apply` из прототипа"]
|
[smart header="Вызов методов через `apply` из прототипа"]
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
Взглянем на него ещё раз на примере `Array`, который наследует от `Object`:
|
Взглянем на него ещё раз на примере `Array`, который наследует от `Object`:
|
||||||
|
|
||||||
<img src="class-inheritance-array-object.svg">
|
<img src="class-inheritance-array-object.png">
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Методы массивов `Array` хранятся в `Array.prototype`.</li>
|
<li>Методы массивов `Array` хранятся в `Array.prototype`.</li>
|
||||||
|
@ -109,7 +109,7 @@ Rabbit.prototype.jump = function() { ... };
|
||||||
|
|
||||||
Теперь выглядеть иерархия будет так:
|
Теперь выглядеть иерархия будет так:
|
||||||
|
|
||||||
<img src="class-inheritance-rabbit-animal.svg">
|
<img src="class-inheritance-rabbit-animal.png">
|
||||||
|
|
||||||
В `prototype` по умолчанию всегда находится свойство `constructor`, указывающее на функцию-конструктор. В частности, `Rabbit.prototype.constructor == Rabbit`. Если мы рассчитываем использовать это свойство, то при замене `prototype` через `Object.create` нужно его явно сохранить:
|
В `prototype` по умолчанию всегда находится свойство `constructor`, указывающее на функцию-конструктор. В частности, `Rabbit.prototype.constructor == Rabbit`. Если мы рассчитываем использовать это свойство, то при замене `prototype` через `Object.create` нужно его явно сохранить:
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ Rabbit.prototype.run = function(speed) {
|
||||||
|
|
||||||
Вызов `rabbit.run()` теперь будет брать `run` из своего прототипа:
|
Вызов `rabbit.run()` теперь будет брать `run` из своего прототипа:
|
||||||
|
|
||||||
<img src="class-inheritance-rabbit-run-animal.svg">
|
<img src="class-inheritance-rabbit-run-animal.png">
|
||||||
|
|
||||||
|
|
||||||
### Вызов метода родителя внутри своего
|
### Вызов метода родителя внутри своего
|
||||||
|
|
|
@ -72,7 +72,7 @@ alert( "Я люблю HTML5!".match(/\s\w\w\w\w\d/) ); // 'HTML5'
|
||||||
|
|
||||||
Совпадение (каждому классу в регэкспе соответствует один символ результата):
|
Совпадение (каждому классу в регэкспе соответствует один символ результата):
|
||||||
|
|
||||||
<img src="love-html5-classes.svg">
|
<img src="love-html5-classes.png">
|
||||||
|
|
||||||
## Граница слова \b
|
## Граница слова \b
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ alert( "Hello, Javascript!".match(/\bJava\b/) ); // null
|
||||||
|
|
||||||
Например, в строке <code class="subject">Hello, Java!</code> под `\b` подходят следующие позиции:
|
Например, в строке <code class="subject">Hello, Java!</code> под `\b` подходят следующие позиции:
|
||||||
|
|
||||||
<img src="hello-java-boundaries.svg">
|
<img src="hello-java-boundaries.png">
|
||||||
|
|
||||||
Как правило, `\b` используется, чтобы искать отдельно стоящее слово. Не на русском конечно, хотя подобную проверку, как мы увидим далее, можно легко сделать для любого языка. А вот на английском, как в примере выше или для чисел, которые являются частным случаем `\w` -- легко.
|
Как правило, `\b` используется, чтобы искать отдельно стоящее слово. Не на русском конечно, хотя подобную проверку, как мы увидим далее, можно легко сделать для любого языка. А вот на английском, как в примере выше или для чисел, которые являются частным случаем `\w` -- легко.
|
||||||
|
|
||||||
|
|
|
@ -51,17 +51,17 @@ alert( str.match(reg) ); // "witch" and her "broom"
|
||||||
Движок регулярных выражений пытается сопоставить её на 0й позиции в строке, но символ `a`, поэтому на 0й позиции соответствия явно нет.
|
Движок регулярных выражений пытается сопоставить её на 0й позиции в строке, но символ `a`, поэтому на 0й позиции соответствия явно нет.
|
||||||
|
|
||||||
Далее он переходит 1ю, 2ю позицию в исходной строке и, наконец, обнаруживает кавычку на 3й позиции:
|
Далее он переходит 1ю, 2ю позицию в исходной строке и, наконец, обнаруживает кавычку на 3й позиции:
|
||||||
<img src="witch_greedy1.svg">
|
<img src="witch_greedy1.png">
|
||||||
</li>
|
</li>
|
||||||
<li>Кавычка найдена, далее движок проверяет, есть ли соответствие для остальной части паттерна.
|
<li>Кавычка найдена, далее движок проверяет, есть ли соответствие для остальной части паттерна.
|
||||||
|
|
||||||
В данном случае следующий символ шаблона: <code class="pattern">.</code> (точка). Она обозначает "любой символ", так что следующая буква строки <code class="match">'w'</code> вполне подходит:
|
В данном случае следующий символ шаблона: <code class="pattern">.</code> (точка). Она обозначает "любой символ", так что следующая буква строки <code class="match">'w'</code> вполне подходит:
|
||||||
<img src="witch_greedy2.svg">
|
<img src="witch_greedy2.png">
|
||||||
</li>
|
</li>
|
||||||
<li>Далее "любой символ" повторяется, так как стоит квантификатор <code class="pattern">.+</code>. Движок регулярных выражений берёт один символ за другим, до тех пор, пока у него это получается.
|
<li>Далее "любой символ" повторяется, так как стоит квантификатор <code class="pattern">.+</code>. Движок регулярных выражений берёт один символ за другим, до тех пор, пока у него это получается.
|
||||||
|
|
||||||
В данном случае это означает "до конца строки":
|
В данном случае это означает "до конца строки":
|
||||||
<img src="witch_greedy3.svg">
|
<img src="witch_greedy3.png">
|
||||||
</li>
|
</li>
|
||||||
<li>Итак, текст закончился, движок регулярных выражений больше не может найти "любой символ", он закончил повторения для <code class="pattern">.+</code> и переходит к следующему символу шаблона.
|
<li>Итак, текст закончился, движок регулярных выражений больше не может найти "любой символ", он закончил повторения для <code class="pattern">.+</code> и переходит к следующему символу шаблона.
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ alert( str.match(reg) ); // "witch" and her "broom"
|
||||||
|
|
||||||
Иными словами, он сокращает текущее совпадение на один символ:
|
Иными словами, он сокращает текущее совпадение на один символ:
|
||||||
|
|
||||||
<img src="witch_greedy4.svg">
|
<img src="witch_greedy4.png">
|
||||||
|
|
||||||
Это называется "фаза возврата" или "фаза бэктрекинга" (backtracking -- англ.).
|
Это называется "фаза возврата" или "фаза бэктрекинга" (backtracking -- англ.).
|
||||||
|
|
||||||
|
@ -80,12 +80,12 @@ alert( str.match(reg) ); // "witch" and her "broom"
|
||||||
Если бы последним символом строки была кавычка <code class="pattern">'"'</code>, то на этом бы всё и закончилось. Но последний символ <code class="subject">'e'</code>, так что совпадения нет.</li>
|
Если бы последним символом строки была кавычка <code class="pattern">'"'</code>, то на этом бы всё и закончилось. Но последний символ <code class="subject">'e'</code>, так что совпадения нет.</li>
|
||||||
<li>...Поэтому движок уменьшает число повторений <code class="pattern">.+</code> ещё на один символ:
|
<li>...Поэтому движок уменьшает число повторений <code class="pattern">.+</code> ещё на один символ:
|
||||||
|
|
||||||
<img src="witch_greedy5.svg">
|
<img src="witch_greedy5.png">
|
||||||
|
|
||||||
Кавычка <code class="pattern">'"'</code> не совпадает с <code class="subject">'n'</code>. Опять неудача.</li>
|
Кавычка <code class="pattern">'"'</code> не совпадает с <code class="subject">'n'</code>. Опять неудача.</li>
|
||||||
<li>Движок продолжает отступать, он уменьшает количество повторений точки <code class="pattern">'.'</code> до тех пор, пока остаток паттерна, то есть в данном случае кавычка <code class="pattern">'"'</code>, не совпадёт:
|
<li>Движок продолжает отступать, он уменьшает количество повторений точки <code class="pattern">'.'</code> до тех пор, пока остаток паттерна, то есть в данном случае кавычка <code class="pattern">'"'</code>, не совпадёт:
|
||||||
|
|
||||||
<img src="witch_greedy6.svg">
|
<img src="witch_greedy6.png">
|
||||||
</li>
|
</li>
|
||||||
<li>Совпадение получено. Дальнейший поиск по оставшейся части строки <code class="subject">is one</code> новых совпадений не даст.</li>
|
<li>Совпадение получено. Дальнейший поиск по оставшейся части строки <code class="subject">is one</code> новых совпадений не даст.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
@ -121,30 +121,30 @@ alert( str.match(reg) ); // witch, broom
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>Первый шаг -- тот же, кавычка <code class="pattern">'"'</code> найдена на 3й позиции:
|
<li>Первый шаг -- тот же, кавычка <code class="pattern">'"'</code> найдена на 3й позиции:
|
||||||
<img src="witch_greedy1.svg">
|
<img src="witch_greedy1.png">
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>Второй шаг -- тот же, находим произвольный символ <code class="pattern">'.'</code>:
|
<li>Второй шаг -- тот же, находим произвольный символ <code class="pattern">'.'</code>:
|
||||||
<img src="witch_greedy2.svg">
|
<img src="witch_greedy2.png">
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>А вот дальше -- так как стоит ленивый режим работы `+`, то движок не повторет точку (произвольный символ) ещё раз, а останавливается на достигнутом и пытается проверить, есть ли соответствие остальной части шаблона, то есть <code class="pattern">'"'</code>:
|
<li>А вот дальше -- так как стоит ленивый режим работы `+`, то движок не повторет точку (произвольный символ) ещё раз, а останавливается на достигнутом и пытается проверить, есть ли соответствие остальной части шаблона, то есть <code class="pattern">'"'</code>:
|
||||||
<img src="witch_lazy3.svg">
|
<img src="witch_lazy3.png">
|
||||||
|
|
||||||
Если бы остальная часть шаблона на данной позиции совпала, то совпадение было бы найдено. Но в данном случе -- нет, символ `'i'` не равен '"'.
|
Если бы остальная часть шаблона на данной позиции совпала, то совпадение было бы найдено. Но в данном случе -- нет, символ `'i'` не равен '"'.
|
||||||
</li>
|
</li>
|
||||||
<li>Движок регулярных выражений увиличивает количество повторений точки на одно и пытается найти соответствие остатку шаблона ещё раз:
|
<li>Движок регулярных выражений увиличивает количество повторений точки на одно и пытается найти соответствие остатку шаблона ещё раз:
|
||||||
|
|
||||||
<img src="witch_lazy4.svg">
|
<img src="witch_lazy4.png">
|
||||||
Опять неудача. Тогда поисковой движок увеличивает количество повторений ещё и ещё...
|
Опять неудача. Тогда поисковой движок увеличивает количество повторений ещё и ещё...
|
||||||
</li>
|
</li>
|
||||||
<li>Только на 5м шаге поисковой движок наконец находит соответствие для остатка паттерна:
|
<li>Только на 5м шаге поисковой движок наконец находит соответствие для остатка паттерна:
|
||||||
|
|
||||||
<img src="witch_lazy5.svg">
|
<img src="witch_lazy5.png">
|
||||||
</li>
|
</li>
|
||||||
<li>Так как поиск происходит с флагом `g`, то он продолжается с конца текущего совпадения, давая ещё один результат:
|
<li>Так как поиск происходит с флагом `g`, то он продолжается с конца текущего совпадения, давая ещё один результат:
|
||||||
|
|
||||||
<img src="witch_lazy6.svg">
|
<img src="witch_lazy6.png">
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ alert( str.match(reg) ); // <span class="my">, span, s
|
||||||
|
|
||||||
Вот так выглядят скобочные группы:
|
Вот так выглядят скобочные группы:
|
||||||
|
|
||||||
<img src="regexp-nested-groups.svg">
|
<img src="regexp-nested-groups.png">
|
||||||
|
|
||||||
На нулевом месте -- всегда совпадение полностью, далее -- группы. Нумерация всегда идёт слева направо, по открывающей скобке.
|
На нулевом месте -- всегда совпадение полностью, далее -- группы. Нумерация всегда идёт слева направо, по открывающей скобке.
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
На рисунке ниже схематически отображена структура, которая получается если посмотреть на совокупность браузерных объектов с "высоты птичьего полёта".
|
На рисунке ниже схематически отображена структура, которая получается если посмотреть на совокупность браузерных объектов с "высоты птичьего полёта".
|
||||||
|
|
||||||
<img src="windowObjects.svg">
|
<img src="windowObjects.png">
|
||||||
|
|
||||||
Как видно из рисунка, на вершине стоит `window`.
|
Как видно из рисунка, на вершине стоит `window`.
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'p
|
||||||
Код выше стабильно работать не будет, потому что `IMG` идет без ширины/высоты:
|
Код выше стабильно работать не будет, потому что `IMG` идет без ширины/высоты:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<img src="ball.svg" id="ball">
|
<img src="ball.png" id="ball">
|
||||||
```
|
```
|
||||||
|
|
||||||
**Высота и ширина изображения неизвестны браузеру до тех пор, пока оно не загрузится, если размер не указан явно.**
|
**Высота и ширина изображения неизвестны браузеру до тех пор, пока оно не загрузится, если размер не указан явно.**
|
||||||
|
@ -43,7 +43,7 @@ ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'p
|
||||||
Чтобы это исправить, добавим `width/height` к картинке:
|
Чтобы это исправить, добавим `width/height` к картинке:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<img src="ball.svg" *!*width="40" height="40"*/!* id="ball">
|
<img src="ball.png" *!*width="40" height="40"*/!* id="ball">
|
||||||
```
|
```
|
||||||
|
|
||||||
Теперь браузер всегда знает ширину и высоту, так что все работает. Тот же эффект дало бы указание размеров в CSS.
|
Теперь браузер всегда знает ширину и высоту, так что все работает. Тот же эффект дало бы указание размеров в CSS.
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
Результат выглядит так:
|
Результат выглядит так:
|
||||||
|
|
||||||
<img src="metric-css.svg">
|
<img src="metric-css.png">
|
||||||
|
|
||||||
Вы можете открыть [edit src="metric"]этот документ в песочнице[/edit].
|
Вы можете открыть [edit src="metric"]этот документ в песочнице[/edit].
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
Вот общая картина:
|
Вот общая картина:
|
||||||
|
|
||||||
|
|
||||||
<img src="metric-all.svg">
|
<img src="metric-all.png">
|
||||||
|
|
||||||
На картинке все они с трудом помещаются, но, как мы увидим далее, их значения просты и понятны.
|
На картинке все они с трудом помещаются, но, как мы увидим далее, их значения просты и понятны.
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
</main>
|
</main>
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="metric-offset-parent.svg">
|
<img src="metric-offset-parent.png">
|
||||||
|
|
||||||
## offsetWidth/Height
|
## offsetWidth/Height
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
|
|
||||||
Эти два свойства -- самые простые. Они содержат "внешнюю" ширину/высоту элемента, то есть его полный размер, включая рамки `border`.
|
Эти два свойства -- самые простые. Они содержат "внешнюю" ширину/высоту элемента, то есть его полный размер, включая рамки `border`.
|
||||||
|
|
||||||
<img src="metric-offset-width-height.svg">
|
<img src="metric-offset-width-height.png">
|
||||||
|
|
||||||
Для нашего элемента:
|
Для нашего элемента:
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -153,7 +153,7 @@ function isHidden(elem) {
|
||||||
<li>`clientTop = 25` -- ширина верхней рамки</li>
|
<li>`clientTop = 25` -- ширина верхней рамки</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<img src="metric-client-left-top.svg">
|
<img src="metric-client-left-top.png">
|
||||||
|
|
||||||
...Но на самом деле они -- вовсе не рамки, а отступ внутренней части элемента от внешней.
|
...Но на самом деле они -- вовсе не рамки, а отступ внутренней части элемента от внешней.
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ function isHidden(elem) {
|
||||||
|
|
||||||
Получится так:
|
Получится так:
|
||||||
|
|
||||||
<img src="metric-client-left-top-rtl.svg">
|
<img src="metric-client-left-top-rtl.png">
|
||||||
|
|
||||||
|
|
||||||
## clientWidth/Height
|
## clientWidth/Height
|
||||||
|
@ -172,7 +172,7 @@ function isHidden(elem) {
|
||||||
|
|
||||||
Они включают в себя ширину содержимого `width` вместе с полями `padding`, но без прокрутки.
|
Они включают в себя ширину содержимого `width` вместе с полями `padding`, но без прокрутки.
|
||||||
|
|
||||||
<img src="metric-client-width-height.svg">
|
<img src="metric-client-width-height.png">
|
||||||
|
|
||||||
На рисунке выше посмотрим вначале на `clientHeight`, её посчитать проще всего. Прокрутки нет, так что это в точности то, что внутри рамок: CSS-ширина `200px` плюс верхнее и нижнее поля `padding` (по `20px`), итого `240px`.
|
На рисунке выше посмотрим вначале на `clientHeight`, её посчитать проще всего. Прокрутки нет, так что это в точности то, что внутри рамок: CSS-ширина `200px` плюс верхнее и нижнее поля `padding` (по `20px`), итого `240px`.
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ function isHidden(elem) {
|
||||||
|
|
||||||
**Если `padding` нет, то `clientWidth/Height` в точности равны размеру области содержимого, внутри рамок и полосы прокрутки.**
|
**Если `padding` нет, то `clientWidth/Height` в точности равны размеру области содержимого, внутри рамок и полосы прокрутки.**
|
||||||
|
|
||||||
<img src="metric-client-width-nopadding.svg">
|
<img src="metric-client-width-nopadding.png">
|
||||||
|
|
||||||
Поэтому в тех случаях, когда мы точно знаем, что `padding` нет, их используют для определения внутренних размеров элемента.
|
Поэтому в тех случаях, когда мы точно знаем, что `padding` нет, их используют для определения внутренних размеров элемента.
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ function isHidden(elem) {
|
||||||
|
|
||||||
Свойства `clientWidth/clientHeight` относятся только к видимой области элемента, а `scrollWidth/scrollHeight` добавляют к ней прокрученную (которую не видно) по горизонтали/вертикали.
|
Свойства `clientWidth/clientHeight` относятся только к видимой области элемента, а `scrollWidth/scrollHeight` добавляют к ней прокрученную (которую не видно) по горизонтали/вертикали.
|
||||||
|
|
||||||
<img src="metric-scroll-width-height.svg">
|
<img src="metric-scroll-width-height.png">
|
||||||
|
|
||||||
На рисунке выше:
|
На рисунке выше:
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -224,7 +224,7 @@ element.style.height = element.scrollHeight + 'px';
|
||||||
|
|
||||||
Следующее иллюстрация показывает значения `scrollHeight` и `scrollTop` для блока с вертикальной прокруткой.
|
Следующее иллюстрация показывает значения `scrollHeight` и `scrollTop` для блока с вертикальной прокруткой.
|
||||||
|
|
||||||
<img src="metric-scroll-top.svg">
|
<img src="metric-scroll-top.png">
|
||||||
|
|
||||||
[smart header="`scrollLeft/scrollTop` можно изменять"]
|
[smart header="`scrollLeft/scrollTop` можно изменять"]
|
||||||
В отличие от большинства свойств, которые доступны только для чтения, значения `scrollLeft/scrollTop` можно изменить, и браузер выполнит прокрутку элемента.
|
В отличие от большинства свойств, которые доступны только для чтения, значения `scrollLeft/scrollTop` можно изменить, и браузер выполнит прокрутку элемента.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
Свойства `clientWidth/Height` для элемента `document.documentElement` -- это как раз ширина/высота видимой области окна.
|
Свойства `clientWidth/Height` для элемента `document.documentElement` -- это как раз ширина/высота видимой области окна.
|
||||||
|
|
||||||
<img src="document-client-width-height.svg">
|
<img src="document-client-width-height.png">
|
||||||
|
|
||||||
[online]
|
[online]
|
||||||
Например, кнопка ниже выведет размер такой области для этой страницы:
|
Например, кнопка ниже выведет размер такой области для этой страницы:
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
Например:
|
Например:
|
||||||
|
|
||||||
<img src="coords.svg">
|
<img src="coords.png">
|
||||||
|
|
||||||
**Координаты относительно окна не учитывают прокрутку, они высчитываются от границ текущей видимой области.**
|
**Координаты относительно окна не учитывают прокрутку, они высчитываются от границ текущей видимой области.**
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ DOM позволяет делать что угодно с HTML-элементо
|
||||||
|
|
||||||
Так выглядят основные ссылки, по которым можно переходить между узлами DOM:
|
Так выглядят основные ссылки, по которым можно переходить между узлами DOM:
|
||||||
|
|
||||||
<img src="dom-links.svg">
|
<img src="dom-links.png">
|
||||||
|
|
||||||
Посмотрим на них повнимательнее.
|
Посмотрим на них повнимательнее.
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ for (var key in elems) {
|
||||||
|
|
||||||
Поэтому посмотрим на дополнительный набор ссылок, которые их не учитывают:
|
Поэтому посмотрим на дополнительный набор ссылок, которые их не учитывают:
|
||||||
|
|
||||||
<img src="dom-links-elements.svg">
|
<img src="dom-links-elements.png">
|
||||||
|
|
||||||
Эти ссылки похожи на те, что раньше, только в ряде мест стоит слово `Element`:
|
Эти ссылки похожи на те, что раньше, только в ряде мест стоит слово `Element`:
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Нужно расположить его внутри `<div>` фиксированного размера, так чтобы в один момент была видна только нужная часть списка:
|
Нужно расположить его внутри `<div>` фиксированного размера, так чтобы в один момент была видна только нужная часть списка:
|
||||||
|
|
||||||
<img src="carousel1.svg">
|
<img src="carousel1.png">
|
||||||
|
|
||||||
Чтобы список был длинный и элементы не переходили вниз, ему ставится `width: 9999px`, а элементам `<li>`, соответственно, `float:left`, либо для элементов используется `display: inline-block`, как в этом решении.
|
Чтобы список был длинный и элементы не переходили вниз, ему ставится `width: 9999px`, а элементам `<li>`, соответственно, `float:left`, либо для элементов используется `display: inline-block`, как в этом решении.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
Для "прокрутки" будем сдвигать `<ul>`. Это можно делать по-разному, например, назначением CSS-свойства `transform: translateX()` или `margin-left`:
|
Для "прокрутки" будем сдвигать `<ul>`. Это можно делать по-разному, например, назначением CSS-свойства `transform: translateX()` или `margin-left`:
|
||||||
|
|
||||||
<img src="carousel2.svg">
|
<img src="carousel2.png">
|
||||||
|
|
||||||
У внешнего `<div>` фиксированная ширина, поэтому "лишние" изображения обрезаются.
|
У внешнего `<div>` фиксированная ширина, поэтому "лишние" изображения обрезаются.
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
Всплытие гарантирует, что клик по внутреннему `<p>` вызовет обработчик `onclick` (если есть) сначала на самом `<p>`, затем на элементе `<div>` далее на элементе `<form>`, и так далее вверх по цепочке родителей до самого `document`.
|
Всплытие гарантирует, что клик по внутреннему `<p>` вызовет обработчик `onclick` (если есть) сначала на самом `<p>`, затем на элементе `<div>` далее на элементе `<form>`, и так далее вверх по цепочке родителей до самого `document`.
|
||||||
|
|
||||||
<img src="event-order-bubbling.svg" alt="Порядок всплытия событий">
|
<img src="event-order-bubbling.png" alt="Порядок всплытия событий">
|
||||||
|
|
||||||
Поэтому если в примере выше кликнуть на `P`, то последовательно выведутся `alert`: `p` -> `div` -> `form`.
|
Поэтому если в примере выше кликнуть на `P`, то последовательно выведутся `alert`: `p` -> `div` -> `form`.
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
|
|
||||||
В [стандарте DOM Events 3](http://www.w3.org/TR/DOM-Level-3-Events/) это продемонстрировано так:
|
В [стандарте DOM Events 3](http://www.w3.org/TR/DOM-Level-3-Events/) это продемонстрировано так:
|
||||||
|
|
||||||
<img src="eventflow.svg">
|
<img src="eventflow.png">
|
||||||
|
|
||||||
То есть, при клике на `TD` событие путешествует по цепочке родителей сначала вниз к элементу ("погружается"), а потом наверх ("всплывает"), по пути задействуя обработчики.
|
То есть, при клике на `TD` событие путешествует по цепочке родителей сначала вниз к элементу ("погружается"), а потом наверх ("всплывает"), по пути задействуя обработчики.
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
@ -79,7 +79,7 @@ function highlight(node) {
|
||||||
|
|
||||||
Естественно, клик может произойти внутри `<td>`, на элементе `<strong>`. Такой клик будет пойман единым обработчиком, но `target` у него будет не `<td>`, а `<strong>`:
|
Естественно, клик может произойти внутри `<td>`, на элементе `<strong>`. Такой клик будет пойман единым обработчиком, но `target` у него будет не `<td>`, а `<strong>`:
|
||||||
|
|
||||||
<img src="bagua-bubble.svg">
|
<img src="bagua-bubble.png">
|
||||||
|
|
||||||
Внутри обработчика `table.onclick` мы должны по `event.target` разобраться, в каком именно `<td>` был клик.
|
Внутри обработчика `table.onclick` мы должны по `event.target` разобраться, в каком именно `<td>` был клик.
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
Событие `mouseover` происходит, когда мышь появляется над элементом, а `mouseout` -- когда уходит из него.
|
Событие `mouseover` происходит, когда мышь появляется над элементом, а `mouseout` -- когда уходит из него.
|
||||||
|
|
||||||
<img src="mouseover-mouseout.svg">
|
<img src="mouseover-mouseout.png">
|
||||||
|
|
||||||
При этом мы можем узнать, с какого элемента пришла (или на какой ушла) мышь, используя дополнительное свойство объекта события `relatedTarget`.
|
При этом мы можем узнать, с какого элемента пришла (или на какой ушла) мышь, используя дополнительное свойство объекта события `relatedTarget`.
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
Это означает, что если посетитель двигает мышью быстро, то DOM-элементы, через которые мышь проходит на большой скорости, могут быть пропущены.
|
Это означает, что если посетитель двигает мышью быстро, то DOM-элементы, через которые мышь проходит на большой скорости, могут быть пропущены.
|
||||||
|
|
||||||
<img src="mouseover-mouseout-over-elems.svg">
|
<img src="mouseover-mouseout-over-elems.png">
|
||||||
|
|
||||||
При быстром движении с элемента `#FROM` до элемента `#TO`, как изображено на картинке выше -- промежуточные `<DIV>` будут пропущены. Сработает только событие `mouseout` на `#FROM` и `mouseover` на `#TO`.
|
При быстром движении с элемента `#FROM` до элемента `#TO`, как изображено на картинке выше -- промежуточные `<DIV>` будут пропущены. Сработает только событие `mouseout` на `#FROM` и `mouseover` на `#TO`.
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
В частности, возможна ситуация, когда курсор прыгает в середину страницы, и при этом `relatedTarget=null`, то есть он пришёл "ниоткуда" (на самом деле извне окна):
|
В частности, возможна ситуация, когда курсор прыгает в середину страницы, и при этом `relatedTarget=null`, то есть он пришёл "ниоткуда" (на самом деле извне окна):
|
||||||
|
|
||||||
<img src="mouseover-mouseout-from-outside.svg">
|
<img src="mouseover-mouseout-from-outside.png">
|
||||||
|
|
||||||
Обратим внимание ещё на такую деталь. При быстром движении курсор окажется над `#TO` сразу, даже если этот элемент глубоко в DOM. Его родители при движении сквозь них события не поймают.
|
Обратим внимание ещё на такую деталь. При быстром движении курсор окажется над `#TO` сразу, даже если этот элемент глубоко в DOM. Его родители при движении сквозь них события не поймают.
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
**При переходе на потомка срабатывает `mouseout` на родителе.**
|
**При переходе на потомка срабатывает `mouseout` на родителе.**
|
||||||
|
|
||||||
<img src="mouseover-to-child.svg">
|
<img src="mouseover-to-child.png">
|
||||||
|
|
||||||
Это кажется странным, но легко объяснимо.
|
Это кажется странным, но легко объяснимо.
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ Origin:http://javascript.ru
|
||||||
|
|
||||||
**Только при наличии такого заголовка в ответе -- браузер сочтёт запрос успешным, а иначе JavaScript получит ошибку.**
|
**Только при наличии такого заголовка в ответе -- браузер сочтёт запрос успешным, а иначе JavaScript получит ошибку.**
|
||||||
|
|
||||||
<img src="xhr-another-domain.svg">
|
<img src="xhr-another-domain.png">
|
||||||
|
|
||||||
То есть, ответ сервера может быть примерно таким:
|
То есть, ответ сервера может быть примерно таким:
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ Access-Control-Allow-Credentials: true
|
||||||
|
|
||||||
Дополнительно он может указать `Access-Control-Max-Age: sec`, где `sec` -- количество секунд, на которые нужно закэшировать разрешение. Тогда при последующих вызовах метода браузер уже не будет делать предзапрос.
|
Дополнительно он может указать `Access-Control-Max-Age: sec`, где `sec` -- количество секунд, на которые нужно закэшировать разрешение. Тогда при последующих вызовах метода браузер уже не будет делать предзапрос.
|
||||||
|
|
||||||
<img src="xhr-preflight.svg">
|
<img src="xhr-preflight.png">
|
||||||
|
|
||||||
Давайте рассмотрим предзапрос на конкретном примере.
|
Давайте рассмотрим предзапрос на конкретном примере.
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,15 @@
|
||||||
|
|
||||||
По двум точкам:
|
По двум точкам:
|
||||||
|
|
||||||
<img src="bezier2.svg">
|
<img src="bezier2.png">
|
||||||
|
|
||||||
По трём точкам:
|
По трём точкам:
|
||||||
|
|
||||||
<img src="bezier3.svg">
|
<img src="bezier3.png">
|
||||||
|
|
||||||
По четырём точкам:
|
По четырём точкам:
|
||||||
|
|
||||||
<img src="bezier4.svg">
|
<img src="bezier4.png">
|
||||||
|
|
||||||
|
|
||||||
Если вы посмотрите внимательно на эти кривые, то "на глазок" заметите:
|
Если вы посмотрите внимательно на эти кривые, то "на глазок" заметите:
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
Для двух точек -- это линейная кривая (т.е. прямая), для трёх точек -- квадратическая кривая (парабола), для четырёх -- кубическая.</li>
|
Для двух точек -- это линейная кривая (т.е. прямая), для трёх точек -- квадратическая кривая (парабола), для четырёх -- кубическая.</li>
|
||||||
<li>**Кривая всегда находится внутри [выпуклой оболочки](http://ru.wikipedia.org/wiki/%D0%92%D1%8B%D0%BF%D1%83%D0%BA%D0%BB%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BE%D0%BB%D0%BE%D1%87%D0%BA%D0%B0), образованной опорными точками:**
|
<li>**Кривая всегда находится внутри [выпуклой оболочки](http://ru.wikipedia.org/wiki/%D0%92%D1%8B%D0%BF%D1%83%D0%BA%D0%BB%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BE%D0%BB%D0%BE%D1%87%D0%BA%D0%B0), образованной опорными точками:**
|
||||||
|
|
||||||
<img src="bezier4-e.svg"> <img src="bezier3-e.svg">
|
<img src="bezier4-e.png"> <img src="bezier3-e.png">
|
||||||
|
|
||||||
Благодаря последнему свойству в компьютерной графике можно оптимизировать проверку пересечений двух кривых. Если их выпуклые оболочки не пересекаются, то и кривые тоже не пересекутся.
|
Благодаря последнему свойству в компьютерной графике можно оптимизировать проверку пересечений двух кривых. Если их выпуклые оболочки не пересекаются, то и кривые тоже не пересекутся.
|
||||||
</li>
|
</li>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
Вот некоторые примеры:
|
Вот некоторые примеры:
|
||||||
|
|
||||||
<img src="bezier-car.svg"> <img src="bezier-letter.svg"> <img src="bezier-vase.svg">
|
<img src="bezier-car.png"> <img src="bezier-letter.png"> <img src="bezier-vase.png">
|
||||||
|
|
||||||
## Математика
|
## Математика
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="bezier3-draw1.svg"></td>
|
<td><img src="bezier3-draw1.png"></td>
|
||||||
<td><img src="bezier3-draw2.svg"></td>
|
<td><img src="bezier3-draw2.png"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
Её график:
|
Её график:
|
||||||
|
|
||||||
<img src="bezier-up.svg">
|
<img src="bezier-up.png">
|
|
@ -158,7 +158,7 @@ stripe.onclick = function() {
|
||||||
|
|
||||||
График этой "кривой" таков:
|
График этой "кривой" таков:
|
||||||
|
|
||||||
<img src="bezier-linear.svg">
|
<img src="bezier-linear.png">
|
||||||
|
|
||||||
...Как видно, это просто прямая. По мере того, как проходит время `x`, завершённость анимации `y` равномерно приближается от `0` к `1`.
|
...Как видно, это просто прямая. По мере того, как проходит время `x`, завершённость анимации `y` равномерно приближается от `0` к `1`.
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ CSS для анимации:
|
||||||
|
|
||||||
График этой кривой:
|
График этой кривой:
|
||||||
|
|
||||||
<img src="train-curve.svg">
|
<img src="train-curve.png">
|
||||||
|
|
||||||
Как видно, процесс вначале развивается быстро -- кривая резко идёт вверх, а затем всё медленнее, медленнее.
|
Как видно, процесс вначале развивается быстро -- кривая резко идёт вверх, а затем всё медленнее, медленнее.
|
||||||
|
|
||||||
|
@ -222,10 +222,10 @@ CSS для анимации:
|
||||||
<td>`(0.42, 0, 0.58, 1.0)`</td>
|
<td>`(0.42, 0, 0.58, 1.0)`</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="ease.svg"></td>
|
<td><img src="ease.png"></td>
|
||||||
<td><img src="ease-in.svg"></td>
|
<td><img src="ease-in.png"></td>
|
||||||
<td><img src="ease-out.svg"></td>
|
<td><img src="ease-out.png"></td>
|
||||||
<td><img src="ease-in-out.svg"></td>
|
<td><img src="ease-in-out.png"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -260,7 +260,7 @@ CSS для анимации:
|
||||||
|
|
||||||
Почему так происходит -- отлично видно, если взглянуть на кривую Безье с указанными опорными точками:
|
Почему так происходит -- отлично видно, если взглянуть на кривую Безье с указанными опорными точками:
|
||||||
|
|
||||||
<img src="bezier-train-over.svg">
|
<img src="bezier-train-over.png">
|
||||||
|
|
||||||
Мы вынесли координату `y` для второй опорной точки на 1 ниже нуля, а для третьей опорной точки -- на 1 выше единицы, поэтому и кривая вышла за границы "обычного" квадрата. Её значения по `y` вышли из стандартного диапазона `0..1`.
|
Мы вынесли координату `y` для второй опорной точки на 1 ниже нуля, а для третьей опорной точки -- на 1 выше единицы, поэтому и кривая вышла за границы "обычного" квадрата. Её значения по `y` вышли из стандартного диапазона `0..1`.
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 3 KiB |
BIN
5-animation/2-css-transitions/bezier-linear@2x.png
Normal file
After Width: | Height: | Size: 7 KiB |
|
@ -181,7 +181,7 @@ function linear(timeFraction) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Её график:
|
Её график:
|
||||||
<img src="linear.svg">
|
<img src="linear.png">
|
||||||
|
|
||||||
Как видно, её график полностью совпадает с `transition-timing-function: linear`, и эффект абсолютно такой же.
|
Как видно, её график полностью совпадает с `transition-timing-function: linear`, и эффект абсолютно такой же.
|
||||||
|
|
||||||
|
@ -244,14 +244,14 @@ function quad(progress) {
|
||||||
|
|
||||||
**График квадратичной функции:**
|
**График квадратичной функции:**
|
||||||
|
|
||||||
<img src="quad.svg">
|
<img src="quad.png">
|
||||||
|
|
||||||
Пример для квадратичной функции (клик для просмотра):
|
Пример для квадратичной функции (клик для просмотра):
|
||||||
[iframe height=40 src="quad" link]
|
[iframe height=40 src="quad" link]
|
||||||
|
|
||||||
Увеличение степени влияет на ускорение. Например, график для 5-й степени:
|
Увеличение степени влияет на ускорение. Например, график для 5-й степени:
|
||||||
|
|
||||||
<img src="quint.svg">
|
<img src="quint.png">
|
||||||
|
|
||||||
В действии:
|
В действии:
|
||||||
[iframe height=40 src="quint" link]
|
[iframe height=40 src="quint" link]
|
||||||
|
@ -268,7 +268,7 @@ function circ(timeFraction) {
|
||||||
|
|
||||||
**График:**
|
**График:**
|
||||||
|
|
||||||
<img src="circ.svg">
|
<img src="circ.png">
|
||||||
|
|
||||||
[iframe height=40 src="circ" link]
|
[iframe height=40 src="circ" link]
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ function back(x, timeFraction) {
|
||||||
|
|
||||||
**График для `x = 1.5`:**
|
**График для `x = 1.5`:**
|
||||||
|
|
||||||
<img src="back.svg">
|
<img src="back.png">
|
||||||
|
|
||||||
Пример для `x = 1.5`:
|
Пример для `x = 1.5`:
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ function elastic(x, timeFraction) {
|
||||||
```
|
```
|
||||||
|
|
||||||
**График для `x=1.5`:**
|
**График для `x=1.5`:**
|
||||||
<img src="elastic.svg">
|
<img src="elastic.png">
|
||||||
|
|
||||||
Пример для `x=1.5`:
|
Пример для `x=1.5`:
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ var bounceEaseOut = makeEaseOut(bounce);
|
||||||
|
|
||||||
На этом графике видно, как преобразование `easeOut` изменяет поведение функции:
|
На этом графике видно, как преобразование `easeOut` изменяет поведение функции:
|
||||||
|
|
||||||
<img src="bounce-inout.svg">
|
<img src="bounce-inout.png">
|
||||||
|
|
||||||
Если есть анимационный эффект, такой как подпрыгивание -- он будет показан в конце, а не в начале (или наоборот, в начале, а не в конце).
|
Если есть анимационный эффект, такой как подпрыгивание -- он будет показан в конце, а не в начале (или наоборот, в начале, а не в конце).
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ bounceEaseInOut = makeEaseInOut(bounce);
|
||||||
|
|
||||||
Это отлично видно, если посмотреть графики `easeIn`, `easeOut` и `easeInOut` на примере функции `circ`:
|
Это отлично видно, если посмотреть графики `easeIn`, `easeOut` и `easeInOut` на примере функции `circ`:
|
||||||
|
|
||||||
<img src="circ-ease.svg">
|
<img src="circ-ease.png">
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><span style="color:#EE6B47">Красным</span> цветом обозначен обычный вариант функции `circ`.</li>
|
<li><span style="color:#EE6B47">Красным</span> цветом обозначен обычный вариант функции `circ`.</li>
|
||||||
|
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 3 KiB |
BIN
5-animation/3-js-animation/bezier-linear@2x.png
Normal file
After Width: | Height: | Size: 7 KiB |
|
@ -97,7 +97,7 @@ function User(name) {
|
||||||
|
|
||||||
Результат, получившееся из `my.js` дерево:
|
Результат, получившееся из `my.js` дерево:
|
||||||
|
|
||||||
<img src="my.svg">
|
<img src="my.png">
|
||||||
|
|
||||||
В узлах-эллипсах на иллюстрации выше стоит тип, например `FUNCTION` (функция) или `NAME` (имя переменной). Комментарии к ним на русском языке добавлены мной вручную.
|
В узлах-эллипсах на иллюстрации выше стоит тип, например `FUNCTION` (функция) или `NAME` (имя переменной). Комментарии к ним на русском языке добавлены мной вручную.
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ function leak() {
|
||||||
|
|
||||||
Посмотрим, какая структура памяти создается при каждом запуске:
|
Посмотрим, какая структура памяти создается при каждом запуске:
|
||||||
|
|
||||||
<img src="leak-xhr.svg">
|
<img src="leak-xhr.png">
|
||||||
|
|
||||||
Когда запускается асинхронный запрос `xhr`, браузер создаёт специальную внутреннюю ссылку (internal reference) на этот объект. находится в процессе коммуникации. Именно поэтому объект `xhr` будет жив после окончания работы функции.
|
Когда запускается асинхронный запрос `xhr`, браузер создаёт специальную внутреннюю ссылку (internal reference) на этот объект. находится в процессе коммуникации. Именно поэтому объект `xhr` будет жив после окончания работы функции.
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ div {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="border-box.svg">
|
<img src="border-box.png">
|
||||||
|
|
||||||
В верхнем случае браузер нарисовал весь элемент размером в `width x height`, в нижнем -- интерпретировал `width/height` как размеры внутренней области.
|
В верхнем случае браузер нарисовал весь элемент размером в `width x height`, в нижнем -- интерпретировал `width/height` как размеры внутренней области.
|
||||||
|
|
||||||
|
|