diff --git a/1-js/2-first-steps/2-external-script/article.md b/1-js/2-first-steps/2-external-script/article.md index dcebfe8b..9c610d68 100644 --- a/1-js/2-first-steps/2-external-script/article.md +++ b/1-js/2-first-steps/2-external-script/article.md @@ -13,10 +13,10 @@ Можно указать и полный URL, например: ```html - + ``` -Вы также можете использовать путь относительно текущей страницы, например `src="jquery.js"` обозначает файл из текущей директории. +Вы также можете использовать путь относительно текущей страницы, например `src="lodash.js"` обозначает файл из текущей директории. Чтобы подключить несколько скриптов, используйте несколько тегов: diff --git a/2-ui/1-document/15-metrics/metric.view/index.html b/2-ui/1-document/15-metrics/metric.view/index.html index 85d99068..246fa64e 100755 --- a/2-ui/1-document/15-metrics/metric.view/index.html +++ b/2-ui/1-document/15-metrics/metric.view/index.html @@ -2,7 +2,6 @@ - +

Красивый placeholder:

- - + diff --git a/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/source.view/index.html b/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/source.view/index.html index 47b37be7..d754fe3d 100755 --- a/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/source.view/index.html +++ b/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/source.view/index.html @@ -3,23 +3,41 @@ +

Красивый placeholder:

- - + diff --git a/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/task.md b/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/task.md index efd98c2f..96c90b07 100644 --- a/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/task.md +++ b/2-ui/4-forms-controls/2-focus-blur/1-emulate-placeholder/task.md @@ -1,18 +1,19 @@ -# Плейсхолдер +# Улучшенный плейсхолдер [importance 5] -Реализуйте плейсхолдер на JavaScript, чтобы он работал в IE9-. +Реализуйте более удобный плейсхолдер-подсказку на JavaScript через атрибут `data-placeholder`. Правила работы плейсхолдера: -Все три пункта должны быть соблюдены кросс-браузерно. Пример: +Демо: -[iframe src="solution" height=40] +[iframe src="solution" height=100] +В этой задаче плейсхолдер должен работать на одном конкретном input. Подумайте, если input много, как здесь применить делегирование? diff --git a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.md b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.md index 260dd373..8d12a516 100644 --- a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.md +++ b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.md @@ -1,110 +1,9 @@ -# Алгоритм -Самый естественный алгоритм решения: -
    -
  1. При клике мышонок получает фокус. Для этого нужно либо заменить `DIV` на другой тег, либо добавить ему `tabindex="-1"`.
  2. -
  3. Когда на элементе фокус, то клавиатурные события будут срабатывать прямо на нём. То есть ловим `mousie.onkeydown`. +Нам нужно ловить `onclick` на мышонке и в `onkeydown` на нём смотреть коды символов. При скан-кодах стрелок двигать мышонка через `position:absolute` или `position:fixed`. -Мы выбираем `keydown`, потому что он позволяет во-первых отлавливать нажатия на спец. клавиши (стрелки), а во-вторых, отменить действие браузера, которым по умолчанию является прокрутка страницы. -
  4. -
  5. При нажатии на стрелки двигаем мышонка через `position:absolute` и `top/left`.
  6. -
+Скан-коды для клавиш стрелок можно узнать, нажимая на них на [тестовом стенде](#keyboard-test-stand). Вот они: 37-38-39-40 (влево-вверх-вправо-вниз). -Дальше решение -- попробуйте сделать сами. Возможны подводные камни :) +Проблема может возникнуть одна -- `keydown` не возникает на элементе, если на нём нет фокуса. -# Решение +Чтобы фокус был -- нужно добавить мышонку атрибут `tabindex` через JS или в HTML. -
    -
  1. -При получении фокуса -- готовим мышонка к перемещению: - -```js -mousie.onfocus = function() { - this.style.position = 'relative'; - this.style.left = '0px'; - this.style.top = '0px'; -} -``` - -
  2. -
  3. Коды для клавиш стрелок можно узнать, нажимая на них на [тестовом стенде](#keyboard-test-stand). Вот они: 37-38-39-40 (влево-вверх-вправо-вниз). - -При нажатии стрелки -- двигаем мышонка: - -```js -mousie.onkeydown = function(e) { - switch(e.keyCode) { - case 37: // влево - this.style.left = parseInt(this.style.left)-this.offsetWidth+'px'; - return false; - case 38: // вверх - this.style.top = parseInt(this.style.top)-this.offsetHeight+'px'; - return false; - case 39: // вправо - this.style.left = parseInt(this.style.left)+this.offsetWidth+'px'; - return false; - case 40: // вниз - this.style.top = parseInt(this.style.top)+this.offsetHeight+'px'; - return false; - } -} -``` - -Обратите внимание, что действием по умолчанию для стрелок является прокрутка страницы. Поэтому, чтобы её отменить, нужно использовать `return false`. - -Когда пользователь убирает фокус с мышки, то она перестает реагировать на клавиши. Нет нужды удалять обработчики на `blur`, потому что браузер перестанет вызывать `keydown`. -
  4. -
- -**В решении выше есть проблема. Мышонок находится в `DIV` с `position:relative`.** Это означает, что его `left/top` являются координатами не относительно документа, а относительно позиционированного предка. - -Что делать? Решений три. - -
  1. Первое -- учесть этого позиционированного предка при вычислении `left/top`, вычитать его координаты из координат относительно документа.
  2. -
  3. Второе -- сделать `position:fixed`. При этом координаты мышонка можно взять напрямую из [mousie.getBoundingClientRect()](https://developer.mozilla.org/en/DOM/element.getBoundingClientRect), т.е. все вычисления выполнять относительно окна. Это больше компьютерно-игровой подход, чем работа с документом.
  4. -
  5. Третье -- переместить мышонка под `document.body` в начале движения. Тогда и с координатами всё будет в порядке. Но при этом могут "слететь" стили.
  6. -
- -Хочется верить, что первое и второе решения понятны. А вот третье более интересно, так как скрывает новые тонкости. - -Если пойти этим путём, то в обработчик `onfocus` следует добавить перемещение мышонка под `BODY`: - -```js -mousie.onfocus = function() { - var coords = getCoords(this); - -*!* - document.body.appendChild(this); -*/!* - - this.style.position = 'absolute'; - this.style.left = coords.left + 'px'; - this.style.top = coords.top + 'px'; -}; -``` - -...Но вот беда! **При `document.body.appendChild(this)` с элемента слетает фокус!** - -Фокус нужно восстановить, чтобы ловить `keydown`. Однако некоторые браузеры, например FF и IE, не дают вызвать метод `focus()` элемента из его обработчика `onfocus`. То есть сделать это нельзя. - -Чтобы это обойти, можно поставить обработчик не `onfocus`, а `onclick`: - -```js -mousie.onclick = function() { - var coords = getCoords(this); - this.style.position = 'absolute'; - this.style.left = coords.left + 'px'; - this.style.top = coords.top + 'px'; - -*!* - if (this.parentNode != document.body) { - document.body.appendChild(this); - this.focus(); - } -*/!* -}; -``` - -Обычно событие `focus` всё равно происходит *после* `click`, но здесь элемент перемещается, поэтому оно "съедается" и мы инициируем его сами вызовом `focus()`. - -[edit src="solution"]Окончательное решение[/edit] \ No newline at end of file diff --git a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.view/index.html b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.view/index.html index 6a4031ca..a01d4440 100755 --- a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.view/index.html +++ b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/solution.view/index.html @@ -3,42 +3,45 @@ -Кликните на мышонка и передвигайте его, нажимая клавиши со стрелками. +

Кликните на мышонка и передвигайте его, нажимая клавиши со стрелками.

+ +
+ _   _
+(q\_/p)
+ /. .\
+=\_t_/=   __
+ /   \   (
+((   ))   )
+/\) (/\  /
+\  Y  /-'
+ nn^nn
+
-
-
-
- + \ No newline at end of file diff --git a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/source.view/index.html b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/source.view/index.html index a11adb9f..b58a674f 100755 --- a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/source.view/index.html +++ b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/source.view/index.html @@ -3,52 +3,37 @@ -Кликните на мышонка и передвигайте его, нажимая клавиши со стрелками. - -
+

Кликните на мышонка и передвигайте его, нажимая клавиши со стрелками.

+
+ _   _
+(q\_/p)
+ /. .\
+=\_t_/=   __
+ /   \   (
+((   ))   )
+/\) (/\  /
+\  Y  /-'
+ nn^nn
+
- - + \ No newline at end of file diff --git a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/task.md b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/task.md index 671e6133..b7bdddd8 100644 --- a/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/task.md +++ b/2-ui/4-forms-controls/2-focus-blur/2-keyboard-mouse/task.md @@ -4,73 +4,8 @@ Кликните по мышонку. Затем нажимайте клавиши со стрелками, и он будет двигаться. - +[demo src="solution"] -
-
-
- - - -Учтите при решении, что мышонок изначально находится где-то в глубине документа, в `DIV'е` с `position:relative`. +В этой задаче запрещается ставить обработчики куда-либо, кроме элемента `#mouse`. +Можно изменять атрибуты и классы в HTML. diff --git a/2-ui/4-forms-controls/2-focus-blur/3-hotkeys/solution.md b/2-ui/4-forms-controls/2-focus-blur/3-hotkeys/solution.md index 64e816a1..cb0173e2 100644 --- a/2-ui/4-forms-controls/2-focus-blur/3-hotkeys/solution.md +++ b/2-ui/4-forms-controls/2-focus-blur/3-hotkeys/solution.md @@ -1,14 +1,15 @@ # CSS для решения -Как видно из исходного кода, `#view` -- это `DIV`, который будет содержать результат, а `#area` - это редактируемое текстовое поле. +Как видно из исходного кода, `#view` -- это `
`, который будет содержать результат, а `#area` - это редактируемое текстовое поле. -Так как мы преобразуем `DIV` в `TEXTAREA` и обратно, нам нужно сделать их практически одинаковыми с виду: +Так как мы преобразуем `
` в `