renovations
|
@ -13,7 +13,7 @@
|
||||||
result = a || b;
|
result = a || b;
|
||||||
```
|
```
|
||||||
|
|
||||||
**Логическое ИЛИ в классическом программировании работает следующим образом: "если *хотя бы один* из аргументов `true`, то возвращает `true`, иначе -- `false`".**
|
Логическое ИЛИ в классическом программировании работает следующим образом: "если *хотя бы один* из аргументов `true`, то возвращает `true`, иначе -- `false`". В JavaScript, как мы увидим далее, это не совсем так, но для начала рассмотрим только логические значения.
|
||||||
|
|
||||||
Получается следующая "таблица результатов":
|
Получается следующая "таблица результатов":
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ alert( true || false); // true
|
||||||
alert( false || false); // false
|
alert( false || false); // false
|
||||||
```
|
```
|
||||||
|
|
||||||
Если значение не логического типа -- то оно к нему приводится. Например, число `1` будет воспринято как `true`, а `0` -- как `false`:
|
Если значение не логического типа -- то оно к нему приводится в целях вычислений. Например, число `1` будет воспринято как `true`, а `0` -- как `false`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
//+ run
|
//+ run
|
||||||
|
@ -129,6 +129,9 @@ alert(result); // выведет "Привет!" - первое значение
|
||||||
alert(undefined || '' || false || 0); // 0
|
alert(undefined || '' || false || 0); // 0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[summary]
|
||||||
|
Итак, оператор `||` вычисляет операнды слева направо до первого "истинного" и возвращает его, а если все ложные -- то последнее значение.
|
||||||
|
[/summary]
|
||||||
|
|
||||||
## && (И)
|
## && (И)
|
||||||
|
|
||||||
|
@ -171,7 +174,7 @@ if ( 1 && 0 ) { // вычислится как true && false
|
||||||
|
|
||||||
К И применим тот же принцип "короткого цикла вычислений", но немного по-другому, чем к ИЛИ.
|
К И применим тот же принцип "короткого цикла вычислений", но немного по-другому, чем к ИЛИ.
|
||||||
|
|
||||||
**Если левый аргумент -- `false`, оператор И возвращает его и заканчивает вычисления. Иначе -- вычисляет и возвращает правый аргумент.**
|
Если левый аргумент -- `false`, оператор И возвращает его и заканчивает вычисления. Иначе -- вычисляет и возвращает правый аргумент.
|
||||||
|
|
||||||
Например:
|
Например:
|
||||||
|
|
||||||
|
@ -197,7 +200,12 @@ alert(1 && 2 && null && 3); // null
|
||||||
alert(1 && 2 && 3); // 3
|
alert(1 && 2 && 3); // 3
|
||||||
```
|
```
|
||||||
|
|
||||||
**Приоритет оператора И `&&` больше, чем ИЛИ `||`, т.е. он выполняется раньше.**
|
[summary]
|
||||||
|
Итак, оператор `&&` вычисляет операнды слева направо до первого "ложного" и возвращает его, а если все истинные -- то последнее значение.
|
||||||
|
[/summary]
|
||||||
|
|
||||||
|
[smart header="Приоритет у `&&` больше, чем у `||`"]
|
||||||
|
Приоритет оператора И `&&` больше, чем ИЛИ `||`, так что он выполняется раньше.
|
||||||
|
|
||||||
Поэтому в следующем коде сначала будет вычислено правое И: `1 && 0 = 0`, а уже потом -- ИЛИ.
|
Поэтому в следующем коде сначала будет вычислено правое И: `1 && 0 = 0`, а уже потом -- ИЛИ.
|
||||||
|
|
||||||
|
@ -205,7 +213,7 @@ alert(1 && 2 && 3); // 3
|
||||||
//+ run
|
//+ run
|
||||||
alert(5 || 1 && 0); // 5
|
alert(5 || 1 && 0); // 5
|
||||||
```
|
```
|
||||||
|
[/smart]
|
||||||
|
|
||||||
[warn header="Не используйте `&&` вместо `if`"]
|
[warn header="Не используйте `&&` вместо `if`"]
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ alert( +apples + +oranges); // 5, число, оба операнда предв
|
||||||
<tr><td>5</td><td>деление</td><td>`/`</td></tr>
|
<tr><td>5</td><td>деление</td><td>`/`</td></tr>
|
||||||
<tr><td>6</td><td>сложение</td><td>`+`</td></tr>
|
<tr><td>6</td><td>сложение</td><td>`+`</td></tr>
|
||||||
<tr><td>6</td><td>вычитание</td><td>`-`</td></tr>
|
<tr><td>6</td><td>вычитание</td><td>`-`</td></tr>
|
||||||
<tr><td>17</td><td>присвоение</td><td>`=`</td></tr>
|
<tr><td>3</td><td>присвоение</td><td>`=`</td></tr>
|
||||||
<tr><td>...</td><td>...</td><td>...</td></tr>
|
<tr><td>...</td><td>...</td><td>...</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ alert( +apples + +oranges); // 5, число, оба операнда предв
|
||||||
|
|
||||||
Обратим внимание, в таблице приоритетов также есть оператор присваивания `=`.
|
Обратим внимание, в таблице приоритетов также есть оператор присваивания `=`.
|
||||||
|
|
||||||
У него -- один из самых низких приоритетов: `17`.
|
У него -- один из самых низких приоритетов: `3`.
|
||||||
|
|
||||||
Именно поэтому, когда переменную чему-либо присваивают, например, `x = 2 * 2 + 1` сначала выполнится арифметика, а уже затем -- произойдёт присвоение `=`.
|
Именно поэтому, когда переменную чему-либо присваивают, например, `x = 2 * 2 + 1` сначала выполнится арифметика, а уже затем -- произойдёт присвоение `=`.
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ alert(number); // Infinity, плюс преобразовал строку "Infi
|
||||||
|
|
||||||
Обычно если мы хотим от посетителя получить число, то `Infinity` или `NaN` нам не подходят. Для того, чтобы отличить "обычные" числа от таких специальных значений, существует функция `isFinite`.
|
Обычно если мы хотим от посетителя получить число, то `Infinity` или `NaN` нам не подходят. Для того, чтобы отличить "обычные" числа от таких специальных значений, существует функция `isFinite`.
|
||||||
|
|
||||||
**Функция `isFinite(n)` возвращает `true` только тогда, когда `n` -- обычное число, а не одно из этих значений:**
|
**Функция `isFinite(n)` преобразует аргумент к числу и возвращает `true`, если это не `NaN/Infinity/-Infinity`:**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
//+ run
|
//+ run
|
||||||
|
|
|
@ -245,6 +245,14 @@ setTimeout(function() {}, 100);
|
||||||
В Internet Explorer, нулевая задержка `setInterval(.., 0)` не сработает. Это касается именно `setInterval`, т.е. `setTimeout(.., 0)` работает нормально.
|
В Internet Explorer, нулевая задержка `setInterval(.., 0)` не сработает. Это касается именно `setInterval`, т.е. `setTimeout(.., 0)` работает нормально.
|
||||||
[/warn]
|
[/warn]
|
||||||
|
|
||||||
|
[smart header="Откуда взялись эти 4мс?"]
|
||||||
|
Почему минимальная задержка -- 4мс, а не 1мс? Зачем она вообще существует?
|
||||||
|
|
||||||
|
Это -- "привет" от прошлого. Браузер Chrome как-то пытался убрать минимальную задержку в своих ранних версиях, но оказалось, что существуют сайты, которые используют `setTimeout(..,0)` рекурсивно, создавая тем самым "асинхронный цикл". И, если задержку совсем убрать, то будет 100% загрузка процессора, такой сайт "подвесит" браузер.
|
||||||
|
|
||||||
|
Поэтому, чтобы не ломать существующие скрипты, решили сделать задержку. По возможности, небольшую. На время создания стандарта оптимальным числом показались 4мс.
|
||||||
|
[/smart]
|
||||||
|
|
||||||
## Реальная частота срабатывания
|
## Реальная частота срабатывания
|
||||||
|
|
||||||
В ряде ситуаций таймер будет срабатывать реже, чем обычно. Задержка между вызовами `setInterval(..., 4)` может быть не 4мс, а 30мс или даже 1000мс.
|
В ряде ситуаций таймер будет срабатывать реже, чем обычно. Задержка между вызовами `setInterval(..., 4)` может быть не 4мс, а 30мс или даже 1000мс.
|
||||||
|
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
@ -1,6 +1,6 @@
|
||||||
# Интернационализация, встроенные объекты Intl
|
# Intl: интернационализация в JavaScript
|
||||||
|
|
||||||
Общая проблема строк, дат, чисел в JavaScript -- они совершенно не в курсе языков и стран, где находится посетитель.
|
Общая проблема строк, дат, чисел в JavaScript -- они "не в курсе" языка и особенностей стран, где находится посетитель.
|
||||||
|
|
||||||
В частности:
|
В частности:
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<dd>В одних странах выводятся цифрами, в других -- иероглифами, длинные числа разделяются где-то пробелом, где-то запятой.</dd>
|
<dd>В одних странах выводятся цифрами, в других -- иероглифами, длинные числа разделяются где-то пробелом, где-то запятой.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
Все современные браузеры, кроме IE10- (но есть библиотеки и для него) поддерживает стандарт [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf), предназначенный решить эти проблемы навсегда.
|
Все современные браузеры, кроме IE10- (но есть библиотеки и для него) поддерживают стандарт [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf), предназначенный решить эти проблемы навсегда.
|
||||||
|
|
||||||
[cut]
|
[cut]
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
# Книги по JS, HTML/CSS и не только
|
# Книги по JS, HTML/CSS и не только
|
||||||
|
|
||||||
При разработке сложных приложений вам понадобятся как смежные технологии, так и знание общей методологии программирования.
|
|
||||||
[cut]
|
|
||||||
|
|
||||||
Прямо сейчас вам будет достаточно знания основ HTML/CSS, но в будущем или параллельно с изучением учебника вы, возможно, захотите углубить свои знания и в других областях.
|
|
||||||
|
|
||||||
**Для обучения JavaScript по учебнику чтение книг, которые здесь предложены, не является обязательным.**
|
|
||||||
|
|
||||||
Мне часто задают вопрос: "Какую литературу порекомендуете?". На этой странице я предлагаю рекомендации по различным темам. Всего несколько книг на каждую тему, из большего количества все равно пришлось бы выбирать.
|
Мне часто задают вопрос: "Какую литературу порекомендуете?". На этой странице я предлагаю рекомендации по различным темам. Всего несколько книг на каждую тему, из большего количества все равно пришлось бы выбирать.
|
||||||
|
|
||||||
Кстати, по всем книжкам, особенно тех, которые касаются технологий, всегда ищите последнее издание.
|
Кстати, по всем книжкам, особенно тем, которые касаются технологий, всегда ищите последнее издание.
|
||||||
|
|
||||||
P.S. Скачать книги здесь нельзя. Эта страница содержит только рекомендации.
|
P.S. Скачать книги здесь нельзя. Эта страница содержит только рекомендации.
|
||||||
|
|
||||||
|
@ -18,20 +11,20 @@ P.S. Скачать книги здесь нельзя. Эта страница
|
||||||
CSS стоит изучать по одной из этих книг. Можно сразу по обеим.
|
CSS стоит изучать по одной из этих книг. Можно сразу по обеим.
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/5510936/?partner=iliakan">CSS ручной работы.</a>
|
<li><a href="http://www.ozon.ru/context/detail/id/24493075/?partner=iliakan">Большая книга CSS3.</a>
|
||||||
<i>Дэн Седерхольм</i>.</li>
|
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/5647176/?partner=iliakan">Большая книга CSS.</a>
|
|
||||||
<i>Дэвид Макфарланд.</i></li>
|
<i>Дэвид Макфарланд.</i></li>
|
||||||
|
<li><a href="http://www.ozon.ru/context/detail/id/3881079/?partner=iliakan">CSS. Каскадные таблицы стилей. Подробное руководство.</a>
|
||||||
|
<i>Эрик Мейер</i></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Для того, чтобы разобраться в конкретных вопросах CSS, и в качестве справочника полезна книга Эрика Мейера <a href="http://www.ozon.ru/context/detail/id/3881079/?partner=iliakan">CSS. Каскадные таблицы стилей. Подробное руководство.</a>, а также [стандарт CSS 2.1](http://specs.operafan.net/css2.1RU/CSS21/visuren.html).
|
Конечно, [стандарт CSS 2.1](http://specs.operafan.net/css2.1RU/CSS21/visuren.html) тоже будет вам в помощь. Подчас его скупая простота и точность гораздо понятнее, чем много страниц разъяснений.
|
||||||
|
|
||||||
## JavaScript
|
## JavaScript
|
||||||
|
|
||||||
Полезное чтение о языке, встроенных методах и конструкциях JavaScript:
|
Полезное чтение о языке, встроенных методах и конструкциях JavaScript:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/3881091/?partner=iliakan">JavaScript. Подробное руководство.</a>
|
<li><a href="http://www.ozon.ru/context/detail/id/19677670/?partner=iliakan">JavaScript. Подробное руководство.</a>
|
||||||
<i>Дэвид Флэнаган.</i></li>
|
<i>Дэвид Флэнаган.</i></li>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/6287517/?partner=iliakan">JavaScript. Шаблоны.</a>
|
<li><a href="http://www.ozon.ru/context/detail/id/6287517/?partner=iliakan">JavaScript. Шаблоны.</a>
|
||||||
<i>Стоян Стефанов.</i></li>
|
<i>Стоян Стефанов.</i></li>
|
||||||
|
@ -55,7 +48,7 @@ CSS стоит изучать по одной из этих книг. Можно
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/3905587/?partner=iliakan">Объектно-ориентированный анализ и проектирование с примерами приложений.</a>
|
<li><a href="http://www.ozon.ru/context/detail/id/3905587/?partner=iliakan">Объектно-ориентированный анализ и проектирование с примерами приложений.</a>
|
||||||
<i>Гради Буч и др.</i>.</li>
|
<i>Гради Буч и др.</i>.</li>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/2457392/?partner=iliakan">Приемы объектно-ориентированного проектирования. Паттерны проектирования.</a>
|
<li><a href="http://www.ozon.ru/context/detail/id/20217137/?partner=iliakan">Приемы объектно-ориентированного проектирования. Паттерны проектирования.</a>
|
||||||
<i>Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес.</i></li>
|
<i>Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес.</i></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -7,24 +7,50 @@
|
||||||
[cut]
|
[cut]
|
||||||
## Метод setImmediate(func)
|
## Метод setImmediate(func)
|
||||||
|
|
||||||
Для того, чтобы поставить функцию в очередь на выполнение без задержки, в Microsoft предложили метод [setImmediate(func)](http://msdn.microsoft.com/en-us/library/ie/hh773176.aspx). Он реализован в IE10.
|
Для того, чтобы поставить функцию в очередь на выполнение без задержки, в Microsoft предложили метод [setImmediate(func)](http://msdn.microsoft.com/en-us/library/ie/hh773176.aspx). Он реализован в IE10+ и на платформе Node.JS.
|
||||||
|
|
||||||
У `setImmediate` единственный аргумент -- это функция, выполнение которой нужно запланировать.
|
У `setImmediate` единственный аргумент -- это функция, выполнение которой нужно запланировать.
|
||||||
|
|
||||||
В других браузерах `setImmediate` нет, но его можно эмулировать, используя, к примеру, метод [postMessage](https://developer.mozilla.org/en-US/docs/DOM/window.postMessage), предназначенный для пересылки сообщений от одного окна другому. Детали работы с `postMessage` вы найдёте в статье [](/cross-window-messaging-with-postmessage). Желательно читать её после освоения темы "События".
|
В других браузерах `setImmediate` нет, но его можно эмулировать, используя, к примеру, метод [postMessage](https://developer.mozilla.org/en-US/docs/DOM/window.postMessage), предназначенный для пересылки сообщений от одного окна другому. Детали работы с `postMessage` вы найдёте в статье [](/cross-window-messaging-with-postmessage). Желательно читать её после освоения темы "События".
|
||||||
|
|
||||||
Эмуляция `setImmediate` с его помощью для всех браузеров, кроме IE7- (в которых нет `postMessage`, так что будет использован setTimeout):
|
Полифилл для `setImmediate` через `postMessage`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
//+ hide="Раскрыть код" src="setImmediate.js"
|
if (!window.setImmediate) window.setImmediate = (function() {
|
||||||
|
var head = { }, tail = head; // очередь вызовов, 1-связный список
|
||||||
|
|
||||||
|
var ID = Math.random(); // уникальный идентификатор
|
||||||
|
|
||||||
|
function onmessage(e) {
|
||||||
|
if(e.data != ID) return; // не наше сообщение
|
||||||
|
head = head.next;
|
||||||
|
var func = head.func;
|
||||||
|
delete head.func;
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(window.addEventListener) { // IE9+, другие браузеры
|
||||||
|
window.addEventListener('message', onmessage);
|
||||||
|
} else { // IE8
|
||||||
|
window.attachEvent( 'onmessage', onmessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.postMessage ? function(func) {
|
||||||
|
tail = tail.next = { func: func };
|
||||||
|
window.postMessage(ID, "*");
|
||||||
|
} :
|
||||||
|
function(func) { // IE7-
|
||||||
|
setTimeout(func, 0);
|
||||||
|
};
|
||||||
|
}());
|
||||||
```
|
```
|
||||||
|
|
||||||
Есть и более сложные эмуляции, включая [MessageChannel](http://www.w3.org/TR/webmessaging/#channel-messaging) для работы с [Web Workers](http://www.w3.org/TR/workers/) и хитрый метод для поддержки IE6-8: [](https://github.com/NobleJS/setImmediate). Все они по существу являются "хаками", направленными на то, чтобы обеспечить поддержку `setImmediate` в тех браузерах, где его нет.
|
Есть и более сложные эмуляции, включая [MessageChannel](http://www.w3.org/TR/webmessaging/#channel-messaging) для работы с [Web Workers](http://www.w3.org/TR/workers/) и хитрый метод для поддержки IE6-8: [](https://github.com/NobleJS/setImmediate). Все они по существу являются "хаками", направленными на то, чтобы обеспечить поддержку `setImmediate` в тех браузерах, где его нет.
|
||||||
|
|
||||||
## Тест производительности
|
## Тест производительности
|
||||||
|
|
||||||
Чтобы сравнить реальную частоту срабатывания -- измерим время на подсчет от 1 до 100 при `setTimeout/setImmediate`:
|
Чтобы сравнить реальную частоту срабатывания -- измерим время на 100 последовательных вызовов при `setTimeout(..0)` по сравнению с `setImmediate`:
|
||||||
|
|
||||||
[iframe src="setImmediate" border="1" link edit]
|
[codetabs src="setImmediate"]
|
||||||
|
|
||||||
Запустите пример выше -- и вы увидите реальную разницу во времени между `setTimeout(.., 0)` и `setImmediate`. Да, она может быть более в 50, 100 и более раз.
|
Запустите пример выше -- и вы увидите реальную разницу во времени между `setTimeout(.., 0)` и `setImmediate`. Да, она может быть более в 50, 100 и более раз.
|
|
@ -9,9 +9,9 @@
|
||||||
## Горячие клавиши
|
## Горячие клавиши
|
||||||
Для наибольшего удобства "шпаргалка" должна быть распечатана и повешена перед глазами, поэтому она сделана в виде 3-колоночного PDF.
|
Для наибольшего удобства "шпаргалка" должна быть распечатана и повешена перед глазами, поэтому она сделана в виде 3-колоночного PDF.
|
||||||
|
|
||||||
<a href="/files/tutorial/sublime/sheet.pdf">Скачать шпаргалку в формате PDF</a>
|
[Скачать шпаргалку в формате PDF](sheet.pdf)
|
||||||
|
|
||||||
Шпаргалка пока под Mac. Для Windows сочетания похожи, обычно вместо Mac-клавиши <code class="key">Cmd</code> под Windows будет <code class="key">Ctrl</code>. А если в сочетании есть и <code class="key">Cmd</code> и <code class="key">Ctrl</code>, то под Windows будет <code class="key">Ctrl</code> + <code class="key">Shift</code>.
|
Эта шпаргалка -- под Mac, для Windows сочетания похожи, обычно вместо Mac-клавиши <code class="key">Cmd</code> под Windows будет <code class="key">Ctrl</code>. А если в сочетании есть и <code class="key">Cmd</code> и <code class="key">Ctrl</code>, то под Windows будет <code class="key">Ctrl</code> + <code class="key">Shift</code>.
|
||||||
|
|
||||||
**Вы часто используете сочетание, но его нет в списке? Поделитесь им в комментариях!**
|
**Вы часто используете сочетание, но его нет в списке? Поделитесь им в комментариях!**
|
||||||
|
|
BIN
12-extra/7-sublime/sheet.pdf
Normal file
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
@ -1,6 +1,8 @@
|
||||||
# Выделение: Range, TextRange и Selection
|
# Выделение: Range, TextRange и Selection
|
||||||
|
|
||||||
В этой статье речь пойдет о документированных, но нечасто используемых объектах `Range`, `TextRange` и `Selection`. Мы рассмотрим вольный перевод спецификаций с понятными примерами и различные кроссбраузерные реализации.
|
В этой статье речь пойдет о документированных, но нечасто используемых объектах `Range`, `TextRange` и `Selection`. Мы рассмотрим вольный перевод спецификаций с понятными примерами и различные кроссбраузерные реализации.
|
||||||
|
|
||||||
|
Эта статья представляет собой обновлённый вариант статьи Александра Бурцева, которой уже нет онлайн. Публикуется с его разрешения, спасибо, Александр!
|
||||||
[cut]
|
[cut]
|
||||||
## Range
|
## Range
|
||||||
|
|
||||||
|
@ -158,7 +160,7 @@ function domRangeHighlight(text) {
|
||||||
|
|
||||||
В действии:
|
В действии:
|
||||||
|
|
||||||
[iframe border="1" src="domRangeHighlight" edit link]
|
[codetabs src="domRangeHighlight"]
|
||||||
|
|
||||||
С остальными свойствами и методами поэкспериментируйте сами. Перейдем к реализации range в IE.
|
С остальными свойствами и методами поэкспериментируйте сами. Перейдем к реализации range в IE.
|
||||||
|
|
||||||
|
@ -266,7 +268,7 @@ function ieTextRangeHighlight(text) {
|
||||||
|
|
||||||
В действии:
|
В действии:
|
||||||
|
|
||||||
[iframe border="1" src="ieTextRangeHighlight" edit link]
|
[codetabs border="1" src="ieTextRangeHighlight"]
|
||||||
|
|
||||||
С остальными свойствами и методами поэкспериментируйте сами.
|
С остальными свойствами и методами поэкспериментируйте сами.
|
||||||
|
|
||||||
|
@ -358,8 +360,8 @@ function setSelection() {
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
<p>В действии:</p>
|
В действии:
|
||||||
[iframe border="1" src="setSelection" edit link]
|
[codetabs border="1" src="setSelection"]
|
||||||
|
|
||||||
## Снятие выделения
|
## Снятие выделения
|
||||||
|
|
||||||
|
@ -403,11 +405,10 @@ function clearSelection() {
|
||||||
```
|
```
|
||||||
|
|
||||||
В действии:
|
В действии:
|
||||||
[iframe border="1" src="fix-ie" edit link]
|
[codetabs border="1" src="fix-ie"]
|
||||||
|
|
||||||
Код функций `getRangeObject(win)` для получения выделения в окне и `fixIERangeObject(range, win)` для исправления `TextRange` -- [edit src="fix-ie"]в песочнице вместе с этим примером[/edit].
|
Код функций `getRangeObject(win)` для получения выделения в окне и `fixIERangeObject(range, win)` для исправления `TextRange` -- [edit src="fix-ie"]в песочнице вместе с этим примером[/edit].
|
||||||
|
|
||||||
Эта статья представляет собой обновлённый вариант статьи Александра Бурцева, сайта которого сейчас нет онлайн. Спасибо, Александр!
|
|
||||||
[head]
|
[head]
|
||||||
<script>
|
<script>
|
||||||
|
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -7,13 +7,6 @@
|
||||||
## Пример
|
## Пример
|
||||||
Для примера рассмотрим следующий HTML:
|
Для примера рассмотрим следующий HTML:
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Код</th>
|
|
||||||
<th>Структура в памяти</th>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
|
@ -27,12 +20,9 @@
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
</td>
|
Его DOM (показаны только основные ссылки):
|
||||||
<td>
|
|
||||||
<img src="html.png">
|
<img src="html.png">
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Удаление removeChild
|
## Удаление removeChild
|
||||||
|
|
||||||
|
@ -49,17 +39,17 @@ var list = document.getElementsByTagName('UL')[0];
|
||||||
document.body.removeChild(document.body.children[0]);
|
document.body.removeChild(document.body.children[0]);
|
||||||
```
|
```
|
||||||
|
|
||||||
**В этом случае, так как DOM взаимосвязан, то он полностью остаётся в памяти!** Включая детей, родителей, соседей и т.п... Всё из-за внешней ссылки `list`, которая делает их достижимыми.
|
В этом случае, так как из этого `UL` можно по ссылкам добраться до любого другого места DOM, то получается, что все объекты по-прежнему достижимы и должны остаться в памяти:
|
||||||
|
|
||||||
<img src="html-list.png">
|
<img src="html-list.png">
|
||||||
|
|
||||||
То есть, в этом случае DOM работает по той же логике, что и обычные объекты.
|
То есть, DOM-объекты при использовании `removeChild` работают по той же логике, что и обычные объекты.
|
||||||
|
|
||||||
## Удаление через innerHTML
|
## Удаление через innerHTML
|
||||||
|
|
||||||
Удаление через очистку `elem.innerHTML="..."` браузеры интерпретируют по-разному.
|
А вот удаление через очистку `elem.innerHTML="..."` браузеры интерпретируют по-разному.
|
||||||
|
|
||||||
По идее, при присвоении `innerHTML` из DOM должны удаляться текущие узлы и добавляться новые (из html). Но стандарт ничего не говорит о том, что делать с узлами после удаления. И тут разные браузеры имеют разное мнение.
|
По идее, при присвоении `elem.innerHTML=html` из DOM должны удаляться предыдущие узлы и добавляться новые, из указанного `html`. Но стандарт ничего не говорит о том, что делать с узлами после удаления. И тут разные браузеры имеют разное мнение.
|
||||||
|
|
||||||
Посмотрим, что произойдёт с DOM-структурой при очистке `BODY`, если на какой-либо элемент есть ссылка.
|
Посмотрим, что произойдёт с DOM-структурой при очистке `BODY`, если на какой-либо элемент есть ссылка.
|
||||||
|
|
||||||
|
@ -107,12 +97,12 @@ document.body.innerHTML = "";
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Firefox</td>
|
<td>Firefox</td>
|
||||||
<td>Элемент</td>
|
<td>узел DOM</td>
|
||||||
<td>Элемент</td>
|
<td>узел DOM</td>
|
||||||
<td>`1`</td>
|
<td>`1`</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>IE 6-9</td>
|
<td>IE 11-</td>
|
||||||
<td>`null`</td>
|
<td>`null`</td>
|
||||||
<td>`null`</td>
|
<td>`null`</td>
|
||||||
<td>`0`</td>
|
<td>`0`</td>
|
||||||
|
@ -122,10 +112,10 @@ document.body.innerHTML = "";
|
||||||
Иными словами, браузеры ведут себя с различной степенью агрессивности по отношению к элементам.
|
Иными словами, браузеры ведут себя с различной степенью агрессивности по отношению к элементам.
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Firefox, Opera</dt>
|
<dt>Firefox</dt>
|
||||||
<dd>Главные пацифисты. Оставляют всё, на что есть ссылки, т.е. элемент, его родителя, соседей и детей.</dd>
|
<dd>Главный пацифист. Оставляет всё, на что есть ссылки, т.е. элемент, его родителя, соседей и детей, в точности как при `removeChild`.</dd>
|
||||||
<dt>Chrome/Safari</dt>
|
<dt>Chrome/Safari/Opera</dt>
|
||||||
<dd>Считают, что раз мы задали ссылку на `UL`, то нам нужно только это поддерево, а остальные (соседи, родитель) можно удалить.</dd>
|
<dd>Считают, что раз мы задали ссылку на `UL`, то нам нужно только это поддерево, а остальные узлы (соседей, родителей) можно удалить.</dd>
|
||||||
<dt>Internet Explorer</dt>
|
<dt>Internet Explorer</dt>
|
||||||
<dd>Как ни странно, самый агрессивный. Удаляет вообще всё, кроме узла, на который есть ссылка. Это поведение одинаково для всех версий IE.</dd>
|
<dd>Как ни странно, самый агрессивный. Удаляет вообще всё, кроме узла, на который есть ссылка. Это поведение одинаково для всех версий IE.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -133,7 +123,19 @@ document.body.innerHTML = "";
|
||||||
На иллюстрации ниже показано, какую часть DOM оставит каждый из браузеров:
|
На иллюстрации ниже показано, какую часть DOM оставит каждый из браузеров:
|
||||||
<img src="html-innerhtml.png">
|
<img src="html-innerhtml.png">
|
||||||
|
|
||||||
Таким образом, кросс-браузерно, при поддержке IE, гарантировано одно: **сам узел, на который есть ссылка, останется в памяти.**
|
## Итого
|
||||||
|
|
||||||
|
Если на какой-то DOM-узел есть ссылка, то:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>При использовании `removeChild` на родителе (или на этом узле, не важно) все узлы, достижимые из данного, остаются в памяти.
|
||||||
|
|
||||||
|
То есть, фактически, в памяти может остаться большая часть дерева DOM. Это даёт наибольшую свободу в коде, но может привести к большим "утечкам памяти" из-за сохранения данных, которые реально не нужны.</li>
|
||||||
|
<li>При удалении через `innerHTML` браузеры ведут себя с различной степенью агрессивности. Кросс-браузерно гарантировано одно: сам узел, на который есть ссылка, останется в памяти.
|
||||||
|
|
||||||
|
Поэтому обращаться к соседям и детям узла, предок которого удалён через присвоение `innerHTML`, нельзя.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Это поведение специфично для `innerHTML`. При обычном удалении узла из DOM все браузеры ведут себя как `Firefox/Opera`, т.е. остаётся всё.
|
|
||||||
|
|
BIN
6-optimize/8-memory-removechild-innerhtml/html-innerhtml.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
**Вот что он должен уметь абсолютно точно -- так это и разработать такую структуру HTML/CSS для элементов управления, которая не сломается, и с которой ему же потом удобно будет взаимодействовать**.
|
**Вот что он должен уметь абсолютно точно -- так это и разработать такую структуру HTML/CSS для элементов управления, которая не сломается, и с которой ему же потом удобно будет взаимодействовать**.
|
||||||
|
|
||||||
Это требует **отличного знания CSS в области позиционирования** элементов, включая тонкости работы `display`, `margin`, `border`, `outline`, `position`, `float`, `border-box` и остальных свойств, а также подходы к построению структуры компонент (CSS layouts).
|
Это требует отличного знания CSS в области позиционирования элементов, включая тонкости работы `display`, `margin`, `border`, `outline`, `position`, `float`, `border-box` и остальных свойств, а также подходы к построению структуры компонент (CSS layouts).
|
||||||
|
|
||||||
Многое можно сделать при помощи JavaScript. И зачастую, не зная CSS, так и делают. Но мы на это ловиться не будем.
|
Многое можно сделать при помощи JavaScript. И зачастую, не зная CSS, так и делают. Но мы на это ловиться не будем.
|
||||||
|
|
||||||
|
@ -15,9 +15,7 @@
|
||||||
Если что-то можно сделать через CSS -- лучше делать это через CSS.
|
Если что-то можно сделать через CSS -- лучше делать это через CSS.
|
||||||
[/summary]
|
[/summary]
|
||||||
|
|
||||||
Причина проста -- как бы ни был сложен CSS, JavaScript ещё сложнее. С этим можно поспорить, особенно если достать из нафталина IE 6,7 (IE5.5 не завалялся?) и показать, что CSS там ну совсем никакой. Да и в IE8 тоже есть забавные баги.
|
Причина проста -- обычно, даже если CSS на вид сложнее -- поддерживать и развивать его проще, чем JS. Поэтому овчинка стоит выделки.
|
||||||
|
|
||||||
**Как правило, даже если CSS на вид сложнее -- поддерживать и развивать его проще, чем JS**. Поэтому овчинка стоит выделки.
|
|
||||||
|
|
||||||
Кроме того, есть ещё одно наблюдение.
|
Кроме того, есть ещё одно наблюдение.
|
||||||
|
|
||||||
|
@ -64,10 +62,14 @@
|
||||||
|
|
||||||
С уверенностью могу рекомендовать следующие:
|
С уверенностью могу рекомендовать следующие:
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/3881079/?partner=iliakan">CSS. Каскадные таблицы стилей. Подробное руководство. Эрик Мейер.</a>
|
<li><a href="http://www.ozon.ru/context/detail/id/24493075/?partner=iliakan">Большая книга CSS3.</a>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/5647176/?partner=iliakan">Большая книга CSS, Дэвид Макфарланд</a></li>
|
<i>Дэвид Макфарланд.</i></li>
|
||||||
<li><a href="http://www.ozon.ru/context/detail/id/5510936/?partner=iliakan">CSS ручной работы, Дэн Седерхольм</a></li>
|
<li><a href="http://www.ozon.ru/context/detail/id/3881079/?partner=iliakan">CSS. Каскадные таблицы стилей. Подробное руководство.</a>
|
||||||
|
<i>Эрик Мейер</i></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Дальнейшие статьи раздела не являются *учебником* CSS, поэтому пожалуйста, изучите эту технологию до них. Это *очерки для лучшей систематизации и дополнения* уже существующих знаний.
|
Дальнейшие статьи раздела не являются *учебником* CSS, поэтому пожалуйста, изучите эту технологию до них.
|
||||||
|
|
||||||
|
Это очерки для лучшей систематизации и дополнения уже существующих знаний.
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 255 B |