From 5fb0e36f13632702fdbd53caa3dd58524e5d01a8 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 15 Feb 2015 11:23:36 +0300 Subject: [PATCH] renovations --- .../4-put-ball-in-center/ball-half/index.html | 2 +- .../4-put-ball-in-center/solution.md | 4 +- .../solution.view/index.html | 2 +- .../source.view/index.html | 2 +- .../solution.view/index.html | 2 +- .../1-move-ball-field/source.view/index.html | 2 +- .../{5-fixevent => 12-fixevent}/article.md | 0 .../2-hoverintent/solution.md | 7 +- .../2-hoverintent/task.md | 2 +- .../article.md | 6 +- .../4-drag-and-drop/1-slider/solution.md | 6 + .../1-slider/solution.view/index.html | 44 +-- .../1-slider/solution.view/style.css | 22 ++ .../1-slider/source.view/index.html | 18 + .../1-slider/source.view/style.css | 22 ++ .../1-slider/task.md | 7 +- .../4-drag-and-drop/2-drag-heroes/solution.md | 5 + .../2-drag-heroes/solution.view/index.html | 9 +- .../2-drag-heroes/solution.view}/soccer.css | 25 +- .../2-drag-heroes/solution.view/soccer.js | 103 ++++++ .../2-drag-heroes/source.view/index.html | 10 +- .../2-drag-heroes/source.view}/soccer.css | 25 +- .../2-drag-heroes/source.view/soccer.js | 1 + .../4-drag-and-drop/2-drag-heroes/task.md | 20 + .../article.md | 178 ++++----- .../4-drag-and-drop/ball.view/index.html | 44 +++ .../4-drag-and-drop/ball2.view/index.html | 49 +++ .../4-drag-and-drop/ball3.view/index.html | 63 ++++ .../ball_shift.png | Bin .../ball_shift@2x.png | Bin .../article.md | 343 +++++++----------- .../between.png | Bin .../dragDemo.view/DragManager.js | 39 +- .../dragDemo.view/dragDemo.css | 4 + .../dragDemo.view/index.html | 38 ++ .../shiftx.png | Bin .../6-drag-and-drop/1-slider/solution.md | 46 --- .../1-slider/solution.view/lib.js | 44 --- .../1-slider/source.view/index.html | 17 - .../1-slider/source.view/lib.js | 44 --- .../2-drag-heroes/solution.view/soccer.js | 80 ---- .../2-drag-heroes/source.view/soccer.js | 2 - .../6-drag-and-drop/2-drag-heroes/task.md | 13 - .../1-scale-with-mouse-wheel/solution.md | 0 .../solution.view/index.html | 0 .../1-scale-with-mouse-wheel/task.md | 0 .../2-no-doc-scroll/solution.md | 0 .../solution.view/fix-textarea-scroll.js | 0 .../2-no-doc-scroll/solution.view/index.html | 0 .../2-no-doc-scroll/source.view/index.html | 0 .../2-no-doc-scroll/task.md | 0 .../{4-mousewheel => 6-mousewheel}/article.md | 14 +- .../wheel.view/index.html | 0 .../dragDemo.view/index.html | 35 -- .../dragDemo.view/lib.js | 30 -- .../1-avatar-above-scroll/solution.md | 0 .../1-avatar-above-scroll}/solution.md | 0 .../solution.view/index.html | 0 .../source.view/index.html | 0 .../1-avatar-above-scroll/task.md | 0 .../2-updown-button/solution.md | 0 .../2-updown-button/solution.view/index.html | 0 .../2-updown-button/source.view/index.html | 0 .../2-updown-button/task.md | 0 .../3-load-visible-img/solution.md | 0 .../solution.view/index.html | 0 .../3-load-visible-img/source.view/index.html | 0 .../3-load-visible-img/task.md | 0 .../article.md | 0 .../solution.view/index.html | 2 +- .../1-center-ball-css/source.view/index.html | 2 +- .../3-animate-ball/solution.view/index.html | 2 +- .../3-animate-ball/source.view/index.html | 2 +- .../solution.view/index.html | 2 +- .../source.view/index.html | 2 +- .../6-extra/9-drag-and-drop-plus/article.md | 6 +- export-plunks.sh | 2 - import-plunks.sh | 2 - plunks.json | 1 - 79 files changed, 686 insertions(+), 766 deletions(-) rename 2-ui/3-event-details/{5-fixevent => 12-fixevent}/article.md (100%) create mode 100644 2-ui/3-event-details/4-drag-and-drop/1-slider/solution.md rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/1-slider/solution.view/index.html (61%) mode change 100755 => 100644 create mode 100644 2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/style.css create mode 100644 2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/index.html create mode 100644 2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/style.css rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/1-slider/task.md (64%) create mode 100644 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.md rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/2-drag-heroes/solution.view/index.html (53%) mode change 100755 => 100644 rename 2-ui/3-event-details/{6-drag-and-drop/2-drag-heroes/source.view => 4-drag-and-drop/2-drag-heroes/solution.view}/soccer.css (58%) mode change 100755 => 100644 create mode 100644 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.js rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/2-drag-heroes/source.view/index.html (53%) mode change 100755 => 100644 rename 2-ui/3-event-details/{6-drag-and-drop/2-drag-heroes/solution.view => 4-drag-and-drop/2-drag-heroes/source.view}/soccer.css (58%) mode change 100755 => 100644 create mode 100644 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.js create mode 100644 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/task.md rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/article.md (51%) create mode 100644 2-ui/3-event-details/4-drag-and-drop/ball.view/index.html create mode 100644 2-ui/3-event-details/4-drag-and-drop/ball2.view/index.html create mode 100644 2-ui/3-event-details/4-drag-and-drop/ball3.view/index.html rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/ball_shift.png (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{6-drag-and-drop => 4-drag-and-drop}/ball_shift@2x.png (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{7-drag-and-drop-objects => 5-drag-and-drop-objects}/article.md (50%) rename 2-ui/3-event-details/{7-drag-and-drop-objects => 5-drag-and-drop-objects}/between.png (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{7-drag-and-drop-objects => 5-drag-and-drop-objects}/dragDemo.view/DragManager.js (82%) mode change 100755 => 100644 rename 2-ui/3-event-details/{7-drag-and-drop-objects => 5-drag-and-drop-objects}/dragDemo.view/dragDemo.css (88%) mode change 100755 => 100644 create mode 100644 2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/index.html rename 2-ui/3-event-details/{7-drag-and-drop-objects => 5-drag-and-drop-objects}/shiftx.png (100%) mode change 100755 => 100644 delete mode 100644 2-ui/3-event-details/6-drag-and-drop/1-slider/solution.md delete mode 100755 2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/lib.js delete mode 100755 2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/index.html delete mode 100755 2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/lib.js delete mode 100755 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.js delete mode 100755 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.js delete mode 100644 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/task.md rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/1-scale-with-mouse-wheel/solution.md (100%) rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/1-scale-with-mouse-wheel/solution.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/1-scale-with-mouse-wheel/task.md (100%) rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/2-no-doc-scroll/solution.md (100%) rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/2-no-doc-scroll/solution.view/fix-textarea-scroll.js (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/2-no-doc-scroll/solution.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/2-no-doc-scroll/source.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/2-no-doc-scroll/task.md (100%) rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/article.md (84%) rename 2-ui/3-event-details/{4-mousewheel => 6-mousewheel}/wheel.view/index.html (100%) mode change 100755 => 100644 delete mode 100755 2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/index.html delete mode 100755 2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/lib.js delete mode 100644 2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/solution.md rename 2-ui/3-event-details/{6-drag-and-drop/2-drag-heroes => 9-onscroll/1-avatar-above-scroll}/solution.md (100%) rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/1-avatar-above-scroll/solution.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/1-avatar-above-scroll/source.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/1-avatar-above-scroll/task.md (100%) rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/2-updown-button/solution.md (100%) rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/2-updown-button/solution.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/2-updown-button/source.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/2-updown-button/task.md (100%) rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/3-load-visible-img/solution.md (100%) rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/3-load-visible-img/solution.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/3-load-visible-img/source.view/index.html (100%) mode change 100755 => 100644 rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/3-load-visible-img/task.md (100%) rename 2-ui/3-event-details/{9-event-onscroll => 9-onscroll}/article.md (100%) delete mode 100755 export-plunks.sh delete mode 100755 import-plunks.sh delete mode 100644 plunks.json diff --git a/2-ui/1-document/15-metrics/4-put-ball-in-center/ball-half/index.html b/2-ui/1-document/15-metrics/4-put-ball-in-center/ball-half/index.html index 96382832..0403e13b 100755 --- a/2-ui/1-document/15-metrics/4-put-ball-in-center/ball-half/index.html +++ b/2-ui/1-document/15-metrics/4-put-ball-in-center/ball-half/index.html @@ -18,7 +18,7 @@
- + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
diff --git a/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.md b/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.md index 2dd7a7a5..fefe340d 100644 --- a/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.md +++ b/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.md @@ -33,7 +33,7 @@ ball.style.top = Math.round(field.clientHeight/2 - ball.offsetHeight/2)+'px'; Код выше стабильно работать не будет, потому что `IMG` идет без ширины/высоты: ```html - + ``` **Высота и ширина изображения неизвестны браузеру до тех пор, пока оно не загрузится, если размер не указан явно.** @@ -43,7 +43,7 @@ ball.style.top = Math.round(field.clientHeight/2 - ball.offsetHeight/2)+'px'; Чтобы это исправить, добавим `width/height` к картинке: ```html - + ``` Теперь браузер всегда знает ширину и высоту, так что все работает. Тот же эффект дало бы указание размеров в CSS. diff --git a/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.view/index.html b/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.view/index.html index 534da2d6..153be17e 100755 --- a/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.view/index.html +++ b/2-ui/1-document/15-metrics/4-put-ball-in-center/solution.view/index.html @@ -18,7 +18,7 @@
- + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
diff --git a/2-ui/1-document/15-metrics/4-put-ball-in-center/source.view/index.html b/2-ui/1-document/15-metrics/4-put-ball-in-center/source.view/index.html index 397cf9e1..5a17ab77 100755 --- a/2-ui/1-document/15-metrics/4-put-ball-in-center/source.view/index.html +++ b/2-ui/1-document/15-metrics/4-put-ball-in-center/source.view/index.html @@ -18,7 +18,7 @@
- + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
diff --git a/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/solution.view/index.html b/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/solution.view/index.html index 7689586d..a2182f30 100755 --- a/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/solution.view/index.html +++ b/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/solution.view/index.html @@ -35,7 +35,7 @@
- + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
diff --git a/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/source.view/index.html b/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/source.view/index.html index c4730bc2..80640073 100755 --- a/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/source.view/index.html +++ b/2-ui/2-events-and-interfaces/3-obtaining-event-object/1-move-ball-field/source.view/index.html @@ -28,7 +28,7 @@
- + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
diff --git a/2-ui/3-event-details/5-fixevent/article.md b/2-ui/3-event-details/12-fixevent/article.md similarity index 100% rename from 2-ui/3-event-details/5-fixevent/article.md rename to 2-ui/3-event-details/12-fixevent/article.md diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md index 8f27252c..ecea5df5 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md @@ -4,16 +4,15 @@ В браузере нет способа "просто получить" текущие координаты. Это может сделать обработчик события, в данном случае `mousemove`. Поэтому нужно будет поставить обработчик на `mousemove` и при каждом движении запоминать текущие координаты, чтобы `setInterval` мог раз в 100мс сравнивать их. -Можно обойтись и без `setInterval` -- сравнивать координаты при каждом срабатывании `mousemove`. Если передвинулись на маленькое расстояние с последнего `mousemove` -- это "наведение на элемент", а на большое -- игнорируем. Вариант с `setInterval` теоретически надёжнее, но на практике и один `mousemove` работает. +Можно обойтись и без `setInterval` -- сравнивать координаты при каждом срабатывании `mousemove`. Если передвинулись на маленькое расстояние с последнего `mousemove` -- это "наведение на элемент", а на большое -- игнорируем. Вариант с `setInterval` лучше с точки зрения производительности -- `mousemove` происходит уж очень часто, но если проверка несложная, то и `mousemove` подойдёт. -Чтобы наш код не срабатывал чересчур часто, мы будем начинать анализ координат при заходе на элемент, а заканчивать -- при выходе с него. - -Если выход осуществлён, и при этом на элементе зафиксировано "состояние наведения", то нужно вызвать соответствующий обработчик `options.out`. +Имеет смысл начинать анализ координат и отслеживание `mousemove` при заходе на элемент, а заканчивать -- при выходе с него. Чтобы точно отловить момент входа и выхода, без учёта подэлементов (во избежание мигания), можно использовать `mouseenter/mouseleave`. В решении, предложенном ниже, однако, используется `mouseover/mouseout`, так как это позволит легко "прикрутить" к такому объекту делегирование, если потребуется. А, чтобы не было лишних срабатываний, лишние переходы отфильтровываются. +При этом при обнаружении "наведения на элемент" это запоминается в переменной `isHover` и вызывается `options.over`, а затем, при выходе с элемента, если было "наведение", вызывается `options.out`. diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md index 66de2788..db49fb3d 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md @@ -42,7 +42,7 @@ new HoverIntent({ }); ``` -Демо: +Демо этого кода: [iframe src="solution" height=110] diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md index ff73c43f..3dce9eb5 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md @@ -20,16 +20,14 @@ Для `mouseout` всё наоборот: + -[online] -В примере ниже вы можете наглядно посмотреть события `mouseover/out`, возникающие на всех элементах. - +В примере ниже, если у вас есть мышь, вы можете наглядно посмотреть события `mouseover/out`, возникающие на всех элементах. [codetabs src="mouseoverout" height=220] -[/online] [warn header="`relatedTarget` может быть `null`"] Свойство `relatedTarget` может быть равно `null`. diff --git a/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.md b/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.md new file mode 100644 index 00000000..cdaf826c --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.md @@ -0,0 +1,6 @@ + +Как можно видеть из HTML/CSS, слайдер -- это `DIV`, подкрашенный фоном/градиентом, внутри которого находится другой `DIV`, оформленный как бегунок, с `position:relative`. + +Бегунок немного поднят, и вылезает по высоте из родителя. + +На этой основе мы реализуем горизонтальный Drag'n'Drop, ограниченный по ширине. Его особенность -- в `position:relative` у переносимого элемента, т.е. координата ставится не абсолютная, а относительно родителя. diff --git a/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/index.html b/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/index.html old mode 100755 new mode 100644 similarity index 61% rename from 2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/index.html rename to 2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/index.html index a8e293f1..e3f71cf8 --- a/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/index.html +++ b/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/index.html @@ -2,29 +2,7 @@ - - + @@ -37,9 +15,7 @@ var sliderElem = document.getElementById('slider'); var thumbElem = sliderElem.children[0]; -thumbElem.ondragstart = function() { return false; }; thumbElem.onmousedown = function(e) { - e = fixEvent(e); var thumbCoords = getCoords(thumbElem); var shiftX = e.pageX - thumbCoords.left; // shiftY здесь не нужен, слайдер двигается только по горизонтали @@ -47,8 +23,6 @@ thumbElem.onmousedown = function(e) { var sliderCoords = getCoords(sliderElem); document.onmousemove = function(e) { - e = fixEvent(e); - // вычесть координату родителя, т.к. position: relative var newLeft = e.pageX - shiftX - sliderCoords.left; @@ -71,9 +45,21 @@ thumbElem.onmousedown = function(e) { return false; // disable selection start (cursor change) }; +thumbElem.ondragstart = function() { + return false; +}; + +function getCoords(elem) { // кроме IE8- + var box = elem.getBoundingClientRect(); + + return { + top: box.top + pageYOffset, + left: box.left + pageXOffset + }; + +} - - + \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/style.css b/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/style.css new file mode 100644 index 00000000..0ed3c7a5 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/1-slider/solution.view/style.css @@ -0,0 +1,22 @@ + +.slider { + border-radius: 5px; + background: #E0E0E0; + background: -moz-linear-gradient(left top , #E0E0E0, #EEEEEE) repeat scroll 0 0 transparent; + background: -webkit-gradient(linear, left top, right bottom, from(#E0E0E0), to(#EEEEEE)); + background: linear-gradient(left top, #E0E0E0, #EEEEEE); + width: 310px; + height: 15px; + margin: 5px; +} + +.thumb { + width: 10px; + height: 25px; + border-radius: 3px; + position: relative; + left: 10px; + top: -5px; + background: blue; + cursor: pointer; +} diff --git a/2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/index.html b/2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/index.html new file mode 100644 index 00000000..763c1d19 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/index.html @@ -0,0 +1,18 @@ + + + + + + + + +
+
+
+ + + + + \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/style.css b/2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/style.css new file mode 100644 index 00000000..0ed3c7a5 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/1-slider/source.view/style.css @@ -0,0 +1,22 @@ + +.slider { + border-radius: 5px; + background: #E0E0E0; + background: -moz-linear-gradient(left top , #E0E0E0, #EEEEEE) repeat scroll 0 0 transparent; + background: -webkit-gradient(linear, left top, right bottom, from(#E0E0E0), to(#EEEEEE)); + background: linear-gradient(left top, #E0E0E0, #EEEEEE); + width: 310px; + height: 15px; + margin: 5px; +} + +.thumb { + width: 10px; + height: 25px; + border-radius: 3px; + position: relative; + left: 10px; + top: -5px; + background: blue; + cursor: pointer; +} diff --git a/2-ui/3-event-details/6-drag-and-drop/1-slider/task.md b/2-ui/3-event-details/4-drag-and-drop/1-slider/task.md similarity index 64% rename from 2-ui/3-event-details/6-drag-and-drop/1-slider/task.md rename to 2-ui/3-event-details/4-drag-and-drop/1-slider/task.md index 2b436f6d..58537031 100644 --- a/2-ui/3-event-details/6-drag-and-drop/1-slider/task.md +++ b/2-ui/3-event-details/4-drag-and-drop/1-slider/task.md @@ -7,13 +7,8 @@ Захватите мышкой синий бегунок и двигайте его, чтобы увидеть в работе. -Позже к этому слайдеру можно будет добавить дополнительные функции по чтению/установке значения. - - ([getCoords](#getCoords) -- в lib.js). - Важно: \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.md b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.md new file mode 100644 index 00000000..7178a96f --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.md @@ -0,0 +1,5 @@ +В решении этой задачи для переноса мы используем координаты относительно окна и `position:fixed`. Так проще. + +А по окончании -- прибавляем прокрутку и делаем `position:absolute`, чтобы элемент был привязан к определённому месту в документе, а не в окне. Можно было и сразу `position:absolute` и оперировать в абсолютных координатах, но код был бы немного длиннее. + +Детали решения расписаны в комментариях в исходном коде. \ No newline at end of file diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/index.html b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/index.html old mode 100755 new mode 100644 similarity index 53% rename from 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/index.html rename to 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/index.html index 563aff26..05999852 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/index.html +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/index.html @@ -8,9 +8,9 @@

Расставьте супергероев по полю.

-

Супергерои -- это элементы с классом "draggable". Сделайте так, чтобы их можно было переносить.

+

Супергерои и мяч -- это элементы с классом "draggable". Сделайте так, чтобы их можно было переносить.

-

Важно: если супергероя подносят к низу или верху страницы, она должна автоматически прокручиваться. Конечно, можно прокрутить и клавиатурой, но так -- удобнее. Если страница помещается на вашем экране целиком и не имеет вертикальной прокрутки -- сделайте окно браузера меньше, чтобы протестировать эту возможность.

+

Важно: если супергероя подносят к низу или верху страницы, она должна автоматически прокручиваться. Если страница помещается на вашем экране целиком и не имеет вертикальной прокрутки -- сделайте окно браузера меньше, чтобы протестировать эту возможность.

Да, и ещё: супергерои ни при каких условиях не должны попасть за край экрана.

@@ -23,15 +23,12 @@
-
+
- - - diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.css b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.css old mode 100755 new mode 100644 similarity index 58% rename from 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.css rename to 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.css index b0095acc..acc4bcf6 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.css +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.css @@ -10,9 +10,10 @@ html, body { float: left; } +/* герои и мяч (переносимые элементы) */ .hero { background: url(//js.cx/drag-heroes/heroes.png); - width: 105px; + width: 130px; height: 128px; float: left; } @@ -26,33 +27,21 @@ html, body { } #hero3 { - background-position: -131px 0; + background-position: -120px 0; } #hero4 { - background-position: -131px -128px; + background-position: -125px -128px; } #hero5 { - background-position: -236px 0; - width: 130px; + background-position: -248px -128px; } -#winnie { - background: url(//js.cx/drag-heroes/winnie.png); - width: 115px; - height: 128px; - float: left; +#hero6 { + background-position: -244px 0; } .draggable { cursor: pointer; } - -.dragging { - z-index: 1000; - position: absolute; - cursor: move; -} - - diff --git a/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.js b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.js new file mode 100644 index 00000000..a6f29316 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/solution.view/soccer.js @@ -0,0 +1,103 @@ + + +document.onmousedown = function(e) { + + var dragElement = e.target; + + if (!dragElement.classList.contains('draggable')) return; + + var coords, shiftX, shiftY; + + startDrag(e.clientX, e.clientY); + + document.onmousemove = function(e) { + moveAt(e.clientX, e.clientY); + }; + + dragElement.onmouseup = function() { + finishDrag(); + }; + + + // ------------------------- + + function startDrag(clientX, clientY) { + + shiftX = clientX - dragElement.getBoundingClientRect().left; + shiftY = clientY - dragElement.getBoundingClientRect().top; + + dragElement.style.position = 'fixed'; + + document.body.appendChild(dragElement); + + moveAt(clientX, clientY); + }; + + function finishDrag() { + // конец переноса, перейти от fixed к absolute-координатам + dragElement.style.top = parseInt(dragElement.style.top) + pageYOffset + 'px'; + dragElement.style.position = 'absolute'; + + document.onmousemove = null; + dragElement.onmouseup = null; + } + + function moveAt(clientX, clientY) { + // новые координаты + var newX = clientX - shiftX; + var newY = clientY - shiftY; + + // ------- обработаем вынос за нижнюю границу окна ------ + // новая нижняя граница элемента + var newBottom = newY + dragElement.offsetHeight; + + // если новая нижняя граница вылезает вовне окна - проскроллим его + if (newBottom > document.documentElement.clientHeight) { + // координата нижней границы документа относительно окна + var docBottom = document.documentElement.getBoundingClientRect().bottom; + + // scrollBy, если его не ограничить - может заскроллить за текущую границу документа + // обычно скроллим на 10px + // но если расстояние от newBottom до docBottom меньше, то меньше + var scrollY = Math.min(docBottom - newBottom, 10); + + // ошибки округления при полностью прокрученной странице + // могут привести к отрицательному scrollY, что будет означать прокрутку вверх + // поправим эту ошибку + if (scrollY < 0) scrollY = 0; + + window.scrollBy(0, scrollY); + + // резким движением мыши элемент можно сдвинуть сильно вниз + // если он вышел за нижнюю границу документа - + // передвигаем на максимально возможную нижнюю позицию внутри документа + newY = Math.min(newY, document.documentElement.clientHeight - dragElement.offsetHeight); + } + + + // ------- обработаем вынос за верхнюю границу окна ------ + if (newY < 0) { + // проскроллим вверх на 10px, либо меньше, если мы и так в самом верху + var scrollY = Math.min(-newY, 10); + if (scrollY < 0) scrollY = 0; // поправим ошибку округления + + window.scrollBy(0, -scrollY); + // при резком движении мыши элемент мог "вылететь" сильно вверх, поправим его + newY = Math.max(newY, 0); + } + + + // зажать в границах экрана по горизонтали + // здесь прокрутки нет, всё просто + if (newX < 0) newX = 0; + if (newX > document.documentElement.clientWidth - dragElement.offsetHeight) { + newX = document.documentElement.clientWidth - dragElement.offsetHeight; + } + + dragElement.style.left = newX + 'px'; + dragElement.style.top = newY + 'px'; + } + + // отменим действие по умолчанию на mousedown (выделение текста, оно лишнее) + return false; +} \ No newline at end of file diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/index.html b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/index.html old mode 100755 new mode 100644 similarity index 53% rename from 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/index.html rename to 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/index.html index 235238f1..05999852 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/index.html +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/index.html @@ -8,13 +8,12 @@

Расставьте супергероев по полю.

-

Супергерои -- это элементы с классом "draggable". Сделайте так, чтобы их можно было переносить.

+

Супергерои и мяч -- это элементы с классом "draggable". Сделайте так, чтобы их можно было переносить.

-

Важно: если супергероя подносят к низу или верху страницы, она должна автоматически прокручиваться. Конечно, можно прокрутить и клавиатурой, но так -- удобнее. Если страница помещается на вашем экране целиком и не имеет вертикальной прокрутки -- сделайте окно браузера меньше, чтобы протестировать эту возможность.

+

Важно: если супергероя подносят к низу или верху страницы, она должна автоматически прокручиваться. Если страница помещается на вашем экране целиком и не имеет вертикальной прокрутки -- сделайте окно браузера меньше, чтобы протестировать эту возможность.

Да, и ещё: супергерои ни при каких условиях не должны попасть за край экрана.

-
@@ -24,15 +23,12 @@
-
+
- - - diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.css b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.css old mode 100755 new mode 100644 similarity index 58% rename from 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.css rename to 2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.css index b0095acc..acc4bcf6 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.css +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.css @@ -10,9 +10,10 @@ html, body { float: left; } +/* герои и мяч (переносимые элементы) */ .hero { background: url(//js.cx/drag-heroes/heroes.png); - width: 105px; + width: 130px; height: 128px; float: left; } @@ -26,33 +27,21 @@ html, body { } #hero3 { - background-position: -131px 0; + background-position: -120px 0; } #hero4 { - background-position: -131px -128px; + background-position: -125px -128px; } #hero5 { - background-position: -236px 0; - width: 130px; + background-position: -248px -128px; } -#winnie { - background: url(//js.cx/drag-heroes/winnie.png); - width: 115px; - height: 128px; - float: left; +#hero6 { + background-position: -244px 0; } .draggable { cursor: pointer; } - -.dragging { - z-index: 1000; - position: absolute; - cursor: move; -} - - diff --git a/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.js b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.js new file mode 100644 index 00000000..f5e11556 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/source.view/soccer.js @@ -0,0 +1 @@ +// Ваш код \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/task.md b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/task.md new file mode 100644 index 00000000..288aa10f --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/2-drag-heroes/task.md @@ -0,0 +1,20 @@ +# Расставить супергероев по полю + +[importance 5] + +В этой задаче вы можете проверить своё понимание сразу нескольких аспектов Drag'n'Drop. + +Сделайте так, чтобы элементы с классом `draggable` можно было переносить мышкой. По окончании переноса элемент остаётся на том месте в документе, где его положили. + +Требования к реализации: + + +Футбольное поле в этой задач слишком большое, чтобы показывать его здесь, поэтому откройте его, кликнув по ссылке ниже. Там же и подробное описание задачи (осторожно, винни-пух и супергерои!). + +[demo src="solution"] + diff --git a/2-ui/3-event-details/6-drag-and-drop/article.md b/2-ui/3-event-details/4-drag-and-drop/article.md similarity index 51% rename from 2-ui/3-event-details/6-drag-and-drop/article.md rename to 2-ui/3-event-details/4-drag-and-drop/article.md index 9b4407a8..80d22846 100644 --- a/2-ui/3-event-details/6-drag-and-drop/article.md +++ b/2-ui/3-event-details/4-drag-and-drop/article.md @@ -5,48 +5,51 @@ Drag'n'Drop -- это возможность захватить мышью эл Перенос мышкой может заменить целую последовательность кликов. И, самое главное, он упрощает внешний вид интерфейса: функции, реализуемые через Drag'n'Drop, в ином случае потребовали бы дополнительных полей, виджетов и т.п. [cut] + ## Отличия от HTML5 Drag'n'Drop -В современном стандарте HTML5 есть поддержка Drag'n'Drop при помощи [специальных событий](http://www.html5rocks.com/en/tutorials/dnd/basics/). Эти события поддерживаются всеми браузерами, в мелочах отстаёт от них IE. +В современном стандарте HTML5 есть поддержка Drag'n'Drop при помощи [специальных событий](http://www.html5rocks.com/en/tutorials/dnd/basics/). -У них есть своя область применения, например можно перетащить файл в браузер, но здесь сосредоточимся на реализации техник Drag'n'Drop в более широком смысле, для более обширного класса задач. +Эти события поддерживаются всеми современными браузерами, и у них есть свои интересные особенности, например, можно перетащить файл в браузер, так что JS получит доступ к его содержимому. Они заслуживают отдельного рассмотрения. -**Далее речь пойдет о реализации Drag'n'Drop при помощи событий мыши.** +Но в плане именно Drag'n'Drop у них есть существенные ограничения. Например, нельзя организовать перенос "только по горизонтали" или "только по вертикали". Также нельзя ограничить перенос внутри заданной зоны. Есть и другие интерфейсные задачи, которые такими встроенными событиями нереализуемы. -**Изложенные методы применяются в элементах управления для обработки любых действий вида "захватить - потянуть - отпустить".** +Поэтому здесь мы будем рассматривать Drag'n'Drop при помощи событий мыши. -## Основная логика Drag'n'Drop +Рассматриваемые приёмы, вообще говоря, применяются не только в Drag'n'Drop, но и для любых интерфейсных взаимодействий вида "захватить - потянуть - отпустить". + +## Алгоритм Drag'n'Drop -Для организации Drag'n'Drop нужно: + Основной алгоритм Drag'n'Drop выглядит так:
    -
  1. При помощи события `mousedown` отследить нажатие кнопки на переносимом элементе.
  2. -
  3. При нажатии -- подготовить элемент к перемещению: обычно ему назначается `position:absolute` и ставятся координаты `left/top` по координатам курсора.
  4. -
  5. Далее отслеживаем движение мыши через mousemove и передвигаем переносимый элемент на новые координаты путём смены `left/top`.
  6. +
  7. Отслеживаем нажатие кнопки мыши на переносимом элементе при помощи события `mousedown`.
  8. +
  9. При нажатии -- подготовить элемент к перемещению.
  10. +
  11. Далее отслеживаем движение мыши через mousemove и передвигаем переносимый элемент на новые координаты путём смены `left/top` и `position:absolute`.
  12. При отпускании кнопки мыши, то есть наступлении события mouseup -- остановить перенос элемента и произвести все действия, связанные с окончанием Drag'n'Drop.
+ В следующем примере эти шаги реализованы для переноса мяча: ```js -//+ autorun var ball = document.getElementById('ball'); ball.onmousedown = function(e) { // 1. отследить нажатие*!* - var self = this; // подготовить к перемещению // 2. разместить на том же месте, но в абсолютных координатах*!* - this.style.position = 'absolute'; + ball.style.position = 'absolute'; moveAt(e); // переместим в body, чтобы мяч был точно не внутри position:relative - document.body.appendChild(this); + document.body.appendChild(ball); - this.style.zIndex = 1000; // показывать мяч над другими элементами + ball.style.zIndex = 1000; // показывать мяч над другими элементами - // передвинуть мяч под координаты курсора + // передвинуть мяч под координаты курсора + // и сдвинуть на половину ширины/высоты для центрирования function moveAt(e) { - self.style.left = e.pageX-20+'px'; // 20 - половина ширины/высоты мяча - self.style.top = e.pageY-20+'px'; + ball.style.left = e.pageX - ball.offsetWidth/2 + 'px'; + ball.style.top = e.pageY - ball.offsetHeight/2 + 'px'; } // 3, перемещать по экрану*!* @@ -55,27 +58,24 @@ ball.onmousedown = function(e) { // 1. отследить нажатие*!* } // 4. отследить окончание переноса *!* - this.onmouseup = function() { - document.onmousemove = self.onmouseup = null; + ball.onmouseup = function() { + document.onmousemove = null; + ball.onmouseup = null; } } ``` -В действии: -
-Кликните по мячу и тяните, чтобы двигать его. - -
+Если запустить этот код на картинке `#ball`, то мы заметим нечто странное. При начале переноса мяч "раздваивается" и переносится не сам мяч, а его "клон". -**Попробуйте этот пример. Он не совсем работает, мячик "раздваивается".** +[online] +В действии (внутри ифрейма): -Сейчас мы это исправим. +[iframe src="ball" height=230] +[/online] -## Отмена переноса браузера +Это потому, что браузер имеет свой собственный Drag'n'Drop, который автоматически запускается и вступает в конфликт с нашим. Это происходит именно для картинок и некоторых других элементов. -При нажатии мышью на `` браузер начинает выполнять свой собственный, встроенный Drag'n'Drop, который и портит наш перенос. - -Чтобы браузер не вмешивался, нужно отменить действие по умолчанию для события `dragstart`: +Его нужно отключить: ```js ball.ondragstart = function() { @@ -83,78 +83,45 @@ ball.ondragstart = function() { }; ``` -Исправленный пример: +Теперь всё будет в порядке. -```js -//+ autorun -var ball = document.getElementById('ball2'); +[online] +В действии (внутри ифрейма): -ball.onmousedown = function(e) { - var self = this; +[iframe src="ball2" height=230] +[/online] - this.style.position = 'absolute'; - moveAt(e); - document.body.appendChild(this); +Ещё одна особенность правильного Drag'd'Drop -- событие `mousemove` отслеживается на `document`, а не на `ball`. - this.style.zIndex = 1000; - - function moveAt(e) { - self.style.left = e.pageX-20+'px'; - self.style.top = e.pageY-20+'px'; - } +С первого взгляда кажется, что мышь всегда над мячом и обработчик `mousemove` можно повесить на сам мяч, а не на документ. - document.onmousemove = function(e) { - moveAt(e); - }; +Однако, на самом деле мышь во время переноса не всегда над мячом. - this.onmouseup = function() { - document.onmousemove = self.onmouseup = null; - }; -} +Вспомним, событие `mousemove` возникает хоть и часто, но не для каждого пикселя. Быстрое движение курсора вызовет `mousemove` уже не над мячом, а, например, в дальнем конце страницы. -*!* -ball.ondragstart = function() { - return false; -}; -*/!* -``` - -В действии: - -
-Кликните по мячу и тяните, чтобы двигать его. - -
- -[smart header="Обработчик `mousemove` ставим на `document`"] - -**Почему событие `mousemove` в примере отслеживается на `document`, а не на `ball`?** - -С первого взгляда кажется, что мышь всегда над мячом и обработчик `mousemove` можно повесить на сам мяч, а не на документ. - -Однако, на самом деле **мышь во время переноса не всегда над мячом**. Вспомните, браузер регистрирует `mousemove` часто, но не для каждого пикселя. - -Быстрое движение курсора вызовет `mousemove` уже не над мячом, а, например, в дальнем конце страницы. Вот почему мы должны отслеживать `mousemove` на всём `document`. -[/smart] ## Правильное позиционирование В примерах выше мяч позиционируется в центре под курсором мыши: ```js -self.style.left = e.pageX - 20 + 'px'; -self.style.top = e.pageY - 20 + 'px'; +self.style.left = e.pageX - ball.offsetWidth/2 + 'px'; +self.style.top = e.pageY - ball.offsetHeight/2 + 'px'; ``` -Число `20` здесь -- половина длины мячика. Оно использовано здесь потому, что если поставить `left/top` ровно в `pageX/pageY`, то мячик прилипнет верхним-левым углом к курсору мыши. Будет некрасиво. +Если поставить `left/top` ровно в `pageX/pageY`, то мячик прилипнет верхним-левым углом к курсору мыши. Будет некрасиво. Поэтому мы сдвигаем его на половину высоты/ширины, чтобы был центром под мышью. Уже лучше. -**Для правильного переноса необходимо, чтобы изначальный сдвиг курсора относительно элемента сохранялся: где захватили, за ту "часть элемента" и переносим.** +Но не идеально. В частности, в самом начале переноса, особенно если мячик "взят" за край -- он резко "прыгает" центром под курсор мыши. + +**Для правильного переноса необходимо, чтобы изначальный сдвиг курсора относительно элемента сохранялся.** + +Где захватили, за ту "часть элемента" и переносим: - + -**Пример с правильным позиционированием:** +Итоговый код с правильным позиционированием: -В этом примере позиционирование осуществляется не на `20px`, а с учётом изначального сдвига. ```js -//+ autorun -var ball = document.getElementById('ball3'); +var ball = document.getElementById('ball'); ball.onmousedown = function(e) { - var self = this; - var coords = getCoords(this); + var coords = getCoords(ball); *!* var shiftX = e.pageX - coords.left; var shiftY = e.pageY - coords.top; */!* - this.style.position = 'absolute'; - document.body.appendChild(this); + ball.style.position = 'absolute'; + document.body.appendChild(ball); moveAt(e); - this.style.zIndex = 1000; // над другими элементами + ball.style.zIndex = 1000; // над другими элементами function moveAt(e) { - self.style.left = e.pageX - *!*shiftX*/!* + 'px'; - self.style.top = e.pageY - *!*shiftY*/!* + 'px'; + ball.style.left = e.pageX - *!*shiftX*/!* + 'px'; + ball.style.top = e.pageY - *!*shiftY*/!* + 'px'; } document.onmousemove = function(e) { moveAt(e); }; - this.onmouseup = function() { - document.onmousemove = self.onmouseup = null; + ball.onmouseup = function() { + document.onmousemove = null; + ball.onmouseup = null; }; } @@ -224,12 +188,11 @@ ball.ondragstart = function() { }; ``` -В действии: +[online] +В действии (внутри ифрейма): -
-Кликните по мячу и тяните, чтобы двигать его. - -
+[iframe src="ball3" height=230] +[/online] Различие особенно заметно, если захватить мяч за правый-нижний угол. В предыдущем примере мячик "прыгнет" серединой под курсор, в этом -- будет плавно переноситься с текущей позиции. @@ -240,7 +203,7 @@ ball.ondragstart = function() { Его компоненты:
    -
  1. События `mousedown` -> `document.mousemove` -> `mouseup`.
  2. +
  3. События `ball.mousedown` -> `document.mousemove` -> `ball.mouseup`.
  4. Передвижение с учётом изначального сдвига `shiftX/shiftY`.
  5. Отмена действия браузера по событию `dragstart`.
@@ -250,10 +213,7 @@ ball.ondragstart = function() { Это и многое другое мы рассмотрим в статье про [Drag'n'Drop объектов](/drag-and-drop-objects). - -[libs] -getCoords.js -[/libs] \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/ball.view/index.html b/2-ui/3-event-details/4-drag-and-drop/ball.view/index.html new file mode 100644 index 00000000..7cc5ed13 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/ball.view/index.html @@ -0,0 +1,44 @@ + + + + + + + +

Кликните по мячу и тяните, чтобы двигать его.

+ + + + + + + + + \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/ball2.view/index.html b/2-ui/3-event-details/4-drag-and-drop/ball2.view/index.html new file mode 100644 index 00000000..22d2afe1 --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/ball2.view/index.html @@ -0,0 +1,49 @@ + + + + + + + +

Кликните по мячу и тяните, чтобы двигать его.

+ + + + + + + + + \ No newline at end of file diff --git a/2-ui/3-event-details/4-drag-and-drop/ball3.view/index.html b/2-ui/3-event-details/4-drag-and-drop/ball3.view/index.html new file mode 100644 index 00000000..1379da2e --- /dev/null +++ b/2-ui/3-event-details/4-drag-and-drop/ball3.view/index.html @@ -0,0 +1,63 @@ + + + + + + + +

Кликните по мячу и тяните, чтобы двигать его.

+ + + + + + + + + \ No newline at end of file diff --git a/2-ui/3-event-details/6-drag-and-drop/ball_shift.png b/2-ui/3-event-details/4-drag-and-drop/ball_shift.png old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/6-drag-and-drop/ball_shift.png rename to 2-ui/3-event-details/4-drag-and-drop/ball_shift.png diff --git a/2-ui/3-event-details/6-drag-and-drop/ball_shift@2x.png b/2-ui/3-event-details/4-drag-and-drop/ball_shift@2x.png old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/6-drag-and-drop/ball_shift@2x.png rename to 2-ui/3-event-details/4-drag-and-drop/ball_shift@2x.png diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/article.md b/2-ui/3-event-details/5-drag-and-drop-objects/article.md similarity index 50% rename from 2-ui/3-event-details/7-drag-and-drop-objects/article.md rename to 2-ui/3-event-details/5-drag-and-drop-objects/article.md index 671e3973..e4c236d4 100644 --- a/2-ui/3-event-details/7-drag-and-drop-objects/article.md +++ b/2-ui/3-event-details/5-drag-and-drop-objects/article.md @@ -1,34 +1,40 @@ -# Мышь: Drag'n'Drop объектов +# Мышь: Drag'n'Drop более глубоко -В [предыдущей статье](/drag-and-drop) мы рассмотрели основы Drag'n'Drop. Здесь мы построим на этой основе фреймворк, предназначенный для переноса *объектов* -- элементов списка, узлов дерева и т.п. +В [предыдущей статье](/drag-and-drop) мы рассмотрели основы Drag'n'Drop. Здесь мы разберём дополнительные "тонкие места" и приёмы реализации, которые возникают на практике. + +Почти все javascript-библиотеки реализуют Drag'n'Drop так, как написано (хотя бывает что и менее эффективно). + +Зная, что и как, вы сможете легко написать свой код переноса или поправить, адаптировать существующую библиотеку под себя. + +Этот материал не строго обязателен для изучения, он специфичен именно для Drag'n'Drop. -Почти все javascript-библиотеки реализуют Drag'n'Drop так, как написано (хотя бывает что и менее эффективно ;)). Зная, что и как, вы сможете легко написать свой код переноса или поправить, адаптировать существующую библиотеку под себя. [cut] + ## Документ Как пример задачи -- возьмём документ с иконками браузера ("объекты переноса"), которые можно переносить в компьютер ("цель переноса"): ```html - - - - - + + + + +

Браузер переносить сюда:

- + ``` -Работающий пример с переносом. +Работающий пример с переносом: -[iframe border=1 src="dragDemo" height=250 link edit] +[iframe border=1 src="dragDemo" height=280 link edit] Далее мы рассмотрим, как делается фреймворк для таких переносов, а в перспективе -- и для более сложных. @@ -41,35 +47,32 @@ ## Начало переноса -Чтобы начать перенос элемента, мы должны отловить нажатие левой кнопки мыши на нём. Для этого используем событие `mousedown`. +Чтобы начать перенос элемента, мы должны отловить нажатие левой кнопки мыши на нём. Для этого используем событие `mousedown`... И, конечно, делегирование. -..И здесь нас ждёт первая особенность переноса объектов. На что ставить обработчик? +Переносимых элементов может быть много. В нашем документе-примере это всего лишь несколько иконок, но если мы хотим переносить элементы списка или дерева, то их может быть 100 штук и более. -**Переносимых элементов может быть много.** В нашем документе-примере это всего лишь несколько иконок, но если мы хотим переносить элементы списка или дерева, то их может быть 100 штук и более. +Поэтому повесим обработчик `mousedown` на контейнер, который содержит переносимые элементы, и будем определять нужный элемент поиском ближайшего `draggable` вверх по иерархии от `event.target`. -Назначать обработчик на каждый DOM-элемент -- нецелесообразно. Проще всего решить эту задачу делегированием. +В качестве контейнера здесь будем брать `document`, хотя это может быть и любой элемент. -**Повесим обработчик `mousedown` на контейнер, который содержит переносимые элементы,** и будем определять нужный элемент поиском ближайшего `draggable` вверх по иерархии от `event.target`. В качестве контейнера здесь и далее будем брать `document`. - -Найденный переносимый объект сохраним в переменной `dragObject` и начнём двигать. +Найденный `draggable`-элемент сохраним в свойстве `dragObject.elem` и начнём двигать. Код обработчика `mousedown`: ```js var dragObject = {}; -document.onmousedown = function(e){ +document.onmousedown = function(e) { - if (e.which != 1) { - return; // нажатие правой кнопкой не запускает перенос + if (e.which != 1) { // если клик правой кнопкой мыши + return; // то он не запускает перенос } - // найти ближайший draggable, пройдя по цепочке родителей target - var elem = findDraggable(e.target, document); + var elem = e.target.closest('.draggable'); - if (!elem) return; // не нашли, клик вне draggable объекта + if (!elem) return; // не нашли, клик вне draggable-объекта - // запомнить переносимый объект + // запомнить переносимый объект dragObject.elem = elem; // запомнить координаты, с которых начат перенос объекта @@ -78,33 +81,23 @@ document.onmousedown = function(e){ } ``` -В обработчике используется функция `findDraggable` для поиска переносимого элемента по `event.target`: +[warn header="Не начинаем перенос по `mousedown`"] +Ранее мы по `mousedown` начинали перенос. -```js -function findDraggable(event) { - var elem = event.target; +Но на самом деле нажатие на элемент вовсе не означает, что его собираются куда-то двигать. Возможно, на нём просто кликают. - // найти ближайший draggable, пройдя по цепочке родителей target - while(elem != document && elem.getAttribute('draggable') == null) { - elem = elem.parentNode; - } - return elem == document ? null : elem; -} -``` +Это важное различие. Снимать элемент со своего места и куда-то двигать нужно только при переносе. -**Здесь мы пока не начинаем перенос, потому что нажатие на элемент вовсе не означает, что его собираются куда-то двигать.** Возможно, на нём просто кликают. - -Это важное различие. Нужно отличать перенос от клика, в том числе -- от клика, который сопровождается нечаянным перемещением на пару пикселей (рука дрогнула). - -Иначе при клике элемент будет сниматься со своего места, и потом тут же возвращаться обратно (никуда не положили). Это лишняя работа и, вообще, выглядит некрасиво. - -**Поэтому в `mousedown` мы запоминаем, какой элемент и где был зажат, а начало переноса будем инициировать из `mousemove`,** если он передвинут хотя бы на несколько пикселей. +Чтобы отличить перенос от клика, в том числе -- от клика, который сопровождается нечаянным перемещением на пару пикселей (рука дрогнула), мы будем запоминать в `dragObject`, какой элемент (`elem`) и где (`downX/downY`) был зажат, а начало переноса будем инициировать из `mousemove`, если он передвинут хотя бы на несколько пикселей. +[/warn] ## Перенос элемента Первой задачей обработчика `mousemove` является инициировать начало переноса, если элемент передвинули в зажатом состоянии. -Ну а второй задачей -- отображать его перенос при каждом передвижении мыши. Схематично, обработчик имеет такой вид: +Ну а второй задачей -- отображать его перенос при каждом передвижении мыши. + +Схематично, обработчик будет иметь такой вид: ```js document.onmousemove = function(e) { @@ -118,13 +111,13 @@ document.onmousemove = function(e) { } ``` -Здесь мы видим новое свойство `dragObject.avatar`. При начале переноса *аватар* делается из элемента и сохраняется в свойство `dragObject.avatar`. +Здесь мы видим новое свойство `dragObject.avatar`. При начале переноса "аватар" делается из элемента и сохраняется в свойство `dragObject.avatar`. -***"Аватар"* -- это DOM-элемент, который перемещается по экрану.** +**"Аватар" -- это DOM-элемент, который перемещается по экрану.** Почему бы не перемещать по экрану сам `draggable`-элемент? Зачем, вообще, нужен аватар? -Дело в том, что иногда сам элемент передвигать неудобно, например он слишком большой. А удобно создать некоторое визуальное представление элемента, и его уже переносить. Аватар дает такую возможность. +Дело в том, что иногда сам элемент передвигать неудобно, например потому, что он слишком большой. А удобно создать некоторое визуальное представление элемента, и его уже переносить. Аватар дает такую возможность. А в простейшем случае аватаром можно будет сделать сам элемент, и это не повлечёт дополнительных расходов. @@ -154,7 +147,7 @@ avatar.style.left = новая координата + 'px'; avatar.style.top = новая координата + 'px'; ``` -**Как вычислять новые координаты `left/top` при переносе?** +Как вычислять новые координаты `left/top` при переносе? Чтобы элемент сохранял свою позицию под курсором, необходимо при нажатии запомнить его изначальный сдвиг относительно курсора, и сохранять его при переносе. @@ -169,7 +162,7 @@ avatar.style.left = e.pageX - shiftX + 'px'; avatar.style.top = e.pageY - shiftY + 'px'; ``` -### Полный код mousemove +## Полный код mousemove Код `mousemove`, решающий задачу начала переноса и позиционирования аватара: @@ -213,12 +206,11 @@ document.onmousemove = function(e) { Функция `createAvatar(e)` создает аватар. В нашем случае в качестве аватара берется сам `draggable` элемент. После создания аватара в него записывается функция `avatar.rollback`, которая задает поведение при отмене переноса. -Как правило, отмена переноса влечет за собой разрушение аватара, если это был клон, или возвращение его на прежнее место, если это сам элемент. +Как правило, отмена переноса влечет за собой разрушение аватара, если это был клон, или возвращение его на прежнее место, если это сам элемент. В нашем случае для отмены переноса нужно запомнить старую позицию элемента и его родителя. ```js -//+ hide="Раскрыть код createAvatar" function createAvatar(e) { // запомнить старые свойства, чтобы вернуться к ним при отмене переноса @@ -245,7 +237,7 @@ function createAvatar(e) { } ``` -Функция `startDrag(e)` инициирует начало переноса и позиционирует аватар на странице. +Функция `startDrag(e)`, которую вызывает `mousemove`, если видит, что элемент в "зажатом" состоянии перенесли достаточно далеко, инициирует начало переноса и позиционирует аватар на странице: ```js function startDrag(e) { @@ -257,7 +249,7 @@ function startDrag(e) { } ``` -### Окончание переноса +## Окончание переноса Окончание переноса происходит по событию `mouseup`. @@ -306,18 +298,16 @@ function finishDrag(e) { ```js // возвратит ближайший droppable или null -// *!*предварительный вариант findDroppable, исправлен ниже!*/!* +*!* +// это предварительный вариант findDroppable, исправлен ниже! +*/!* function findDroppable(event) { // взять элемент на данных координатах var elem = document.elementFromPoint(event.clientX, event.clientY); - // пройти вверх по цепочке родителей в поисках droppable - while(elem != document && elem.getAttribute('droppable') == null) { - elem = elem.parentNode; - } - - return elem == document ? null : elem; + // найти ближайший сверху droppable + return elem.closest('.droppable'); } ``` @@ -325,67 +315,48 @@ function findDroppable(event) { Вариант выше -- предварительный. Он не будет работать. Если попробовать применить эту функцию, будет все время возвращать один и тот же элемент! А именно -- *текущий переносимый*. Почему так? -..Дело в том, что в процессе переноса под мышкой находится именно аватар. При начале переноса ему даже `z-index` ставится большой, чтобы он был поверх всех остальных. +...Дело в том, что в процессе переноса под мышкой находится именно аватар. При начале переноса ему даже `z-index` ставится большой, чтобы он был поверх всех остальных. **Аватар перекрывает остальные элементы. Поэтому функция `document.elementFromPoint()` увидит на текущих координатах именно его.** -Чтобы это изменить, нужно либо поправить код переноса, чтобы аватар двигался *рядом* с курсором мыши, либо поступить проще: +Чтобы это изменить, нужно либо поправить код переноса, чтобы аватар двигался *рядом* с курсором мыши, либо дать аватару стиль `pointer-events:none` (кроме IE10-), либо:
  1. Спрятать аватар.
  2. Вызывать `elementFromPoint`.
  3. Показать аватар.
-Напишем вспомогательную функцию `getElementUnderClientXY(elem, clientX, clientY)`, которая это делает: - -```js -/* получить элемент на координатах clientX/clientY, под elem */ -function getElementUnderClientXY(elem, clientX, clientY) { - // сохранить старый display и спрятать переносимый элемент - var display = elem.style.display || ''; - elem.style.display = 'none'; - - // получить самый вложенный элемент под курсором мыши - var target = document.elementFromPoint(clientX, clientY); - - // показать переносимый элемент обратно - elem.style.display = display; - - if (!target || target == document) { // такое бывает при выносе за границы окна - target = document.body; // поправить значение, чтобы был именно элемент - } - - return target; -} -``` - -Правильный код `findDroppable`: +Напишем функцию `findDroppable(event)`, которая это делает: ```js function findDroppable(event) { - var elem = getElementUnderClientXY(dragObject.avatar, event.clientX, event.clientY); + // спрячем переносимый элемент + dragObject.avatar.hidden = true; - while(elem != document && elem.getAttribute('droppable') == null) { - elem = elem.parentNode; + // получить самый вложенный элемент под курсором мыши + var elem = document.elementFromPoint(event.clientX, event.clientY); + + // показать переносимый элемент обратно + dragObject.avatar.hidden = false; + + if (elem == null) { + // такое возможно, если курсор мыши "вылетел" за границу окна + return null; } - return elem == document ? null : elem; + return target.closest('.droppable'); } ``` -## Сводим части фреймворка вместе +## DragManager -Сейчас в нашем распоряжении находятся основные фрагменты кода и решения всех технических подзадач. +Из фрагментов кода, разобранных выше, можно собрать мини-фреймворк. -Приведем их в нормальный вид. - -### dragManager - -Перенос будет координироваться единым объектом. Назовем его `dragManager`. +Объект `DragManager` будет запоминать текущий переносимый объект и отслеживать его перенос. Для его создания используем не обычный синтаксис `{...}`, а вызов `new function`. Это позволит прямо при создании объявить дополнительные переменные и функции в замыкании, которыми могут пользоваться методы объекта, а также назначить обработчики: ```js -var dragManager = new function() { +var DragManager = new function() { var dragObject = {}; @@ -404,11 +375,13 @@ var dragManager = new function() { } ``` -Всю работу будут выполнять обработчики `onMouse*`, которые оформлены как локальные функции. В данном случае они ставятся на `document` через `on...`, но вы легко можете поменять это на `addEventListener/attachEvent`. +Всю работу будут выполнять обработчики `onMouse*`, которые оформлены как локальные функции. В данном случае они ставятся на `document` через `on...`, но это легко поменять это на `addEventListener`. -Внутренний объект `dragObject` будет содержать информацию об объекте переноса. +Код функция `onMouse*` мы подробно рассмотрели ранее, но вы сможете увидеть их в полном примере ниже. -У него будут следующие свойства: +Внутренний объект `dragObject` будет содержать информацию об объекте переноса. + +У него будут следующие свойства, которые также разобраны выше:
`elem`
Текущий зажатый мышью объект, если есть (ставится в `mousedown`).
@@ -420,63 +393,56 @@ var dragManager = new function() {
Относительный сдвиг курсора от угла элемента, вспомогательное свойство вычисляется в начале переноса.
-**Задачей `dragManager` является общее управление переносом.** Для обработки его окончания вызываются методы `onDrag*`, которые назначаются внешним кодом. +Задачей `DragManager` является общее управление переносом. Что же касается действий при его окончании -- их должен назначить внешний код, который использует `DragManager`. -Разработчик, подключив `dragManager`, описывает в этих методах, что делать при начале и завершении переноса. +Можно сделать это через вспомогательные методы `onDrag*`, которые устанавливаются внешним кодом и затем вызываются фреймворком. Разработчик, подключив `DragManager`, описывает в этих методах, что делать при начале и завершении переноса. Конечно же, можно заменить методы `onDrag*` на генерацию "своих" событий. -[smart] -Если в вашем распоряжении есть современный JavaScript-фреймворк, то можно заменить вызовы методов `onDrag*` на генерацию соответствующих событий. -[/smart] - -### Реализация переноса иконок - -С использованием этого фреймворка перенос иконок браузеров в компьютер реализуется просто: +С использованием `DragManager` пример, с которого начиналась эта глава -- перенос иконок браузеров в компьютер, реализуется совсем просто: ```js -dragManager.onDragEnd = function(dragObject, dropElem) { +DragManager.onDragEnd = function(dragObject, dropElem) { + + // скрыть/удалить переносимый объект + dragObject.elem.hidden = true; // успешный перенос, показать улыбку классом computer-smile dropElem.className = 'computer computer-smile'; - // скрыть переносимый объект - dragObject.elem.style.display = 'none'; - // убрать улыбку через 0.2 сек - setTimeout(function() { dropElem.className = 'computer'; }, 200); + setTimeout(function() { + dropElem.classList.remove('computer-smile'; + }, 200); }; -dragManager.onDragCancel = function(dragObject) { +DragManager.onDragCancel = function(dragObject) { // откат переноса dragObject.avatar.rollback(); }; ``` -Результат: +Полный пример с кодом: - -[iframe border=1 src="dragDemo" height=250 link edit] +[codetabs src="dragDemo" height=280] -## Варианты расширения этого кода +## Расширения -Существует масса возможных применений Drag'n'Drop. Реализациях всех из них здесь превратила бы довольно простой фреймворк в страшнейшего монстра. +Существует масса возможных применений Drag'n'Drop. Здесь мы не будем реализовывать их все, поскольку не стоит цель создать фреймворк-монстр. -Поэтому мы разберем варианты расширений и их реализации, чтобы вы, при необходимости, легко могли написать то, что нужно. +Однако, мы рассмотрим их, чтобы, при необходимости, легко было написать то, что нужно. ### Захватывать элемент можно только за "ручку" -Функция `createAvatar(e)` может быть модифицирована, чтобы захватывать элемент можно было, только ухватившись за определенную зону. +Часто бывает, что перенос должен быть инициирован только при захвате за определённую зону элемента. К примеру, модальное окно можно "взять", только захватив его за заголовок. -Например, окно чата можно "взять", только захватив его за заголовок. +Для этого достаточно добавить необходимую проверку, к примеру, в функцию `createAvatar` или перед её запуском. -Для этого достаточно проверять по `e.target`, куда, всё же, нажал посетитель. Если взять элемент на данных координатах нельзя, то `createAvatar` может вернуть `false`, и перенос не будет начат. +Если `mousedown` был внутри элемента, помеченного, к примеру, классом `draghandle`, то начинаем перенос, иначе -- нет. -### Проверка прав положить на droppable +### Проверка прав на droppable -Бывает так, что не на любое место в `droppable` можно положить элемент. - -Само решение "можно или нет" может зависеть как от переносимого элемента (или "аватара" как его полномочного представителя), так и от конкретного места в `droppable`, над которым посетитель отпустил кнопку мыши. +Бывает и так, что не на любое место в `droppable` можно положить элемент. Например: в админке есть дерево всех объектов сайта: статей, разделов, посетителей и т.п. @@ -486,31 +452,19 @@ dragManager.onDragCancel = function(dragObject) {
  • Узел "статья" (draggable) можно переносить в "раздел" (droppable), а узел "пользователи" -- нельзя. Но и то и другое можно поместить в "корзину".
  • -Эта задача решается добавлением проверки в `findDroppable(e)`. Эта функция знает и об аватаре и о событии. При попытке положить в "неправильное" место функция `findDroppable(e)` должна возвращать `null`. +Здесь решение: "можно или нет" переносить или нельзя зависит от "типа" переносимого объекта. -Рассмотрим эту задачу поглубже, так как она встречается часто. +Есть и более сложные варианты, когда решение зависит от конкретного места в `droppable`, над которым посетитель отпустил кнопку мыши. К примеру, переносить в верхнюю часть можно, а в нижнюю -- нет. -**Есть две наиболее частые причины, по которым аватар нельзя положить на потенциальный `droppable`.** +Эта задача решается добавлением проверки в `findDroppable(e)`. Эта функция знает и об аватаре и о событии, включая координаты. При попытке положить в "неправильное" место функция `findDroppable(e)` должна возвращать `null`. -Первую мы уже рассмотрели: "несовпадение типов". Это как раз тот случай, когда "узлы-разделы" дерева админки могут принимать только "статьи", и не могут -- "посетителей". +Однако, на практике бывают ситуации, когда решение "прямо сейчас" принять невозможно. Например, нужно сделать запрос на сервер: "А разрешено ли текущему посетителю производить такую операцию?" -В этом случае мы можем проверить это в `findDroppable`, так как вся необходимая информация о типах у нас есть. +Как при этом должен вести себя интерфейс? Можно, конечно сделать, чтобы элемент после отпускания кнопки мыши "завис" над `droppable`, ожидая ответа. Однако, такое решение неудобно в реализации и странновато выглядит для посетителя. -Вторая причина -- посложнее. +Как правило, применяют "оптимистичный" алгоритм, по которому мы считаем, что перенос обычно успешен, но при необходимости можем отменить его. -**Может не хватать прав на такое действие с `draggable/droppable`, в рамках наложенных на посетителя ограничений.** - -Например, человек не может положить статью именно в данный раздел. - -А возможно, объект переноса удален из базы администратором, и браузер об этом (пока) не знает -- мы должны корректно обрабатывать все случаи, включая этот. - -Здесь сложность в том, что **окончательное решение знает только сервер**. Значит, нужно сделать запрос. А элемент после отпускания мыши не может "зависнуть" над элементом в ожидании ответа, нужно его куда-то положить. - -**Как правило, применяют "оптимистичный" сценарий, по которому мы считаем, что перенос обычно успешен.** - -При нём посетитель кладет объект туда, куда он хочет. - -Затем, в коде `onDragEnd`: +При нём посетитель кладет объект туда, куда он хочет, а затем, в коде `onDragEnd`:
    1. Визуально обрабатывается завершение переноса, как будто все ок.
    2. Производится асинхронный запрос к серверу, содержащий информацию о переносе.
    3. @@ -518,93 +472,58 @@ dragManager.onDragCancel = function(dragObject) {
    4. Если нет -- выводится ошибка и возвращается `avatar.rollback()`. Аватар в этом случае должен предусматривать возможность отката после успешного завершения.
    -**Процесс общения с сервером сопровождается индикацией загрузки и, при необходимости, блокировкой новых операций переноса до получения подтверждения.** - - +Процесс общения с сервером сопровождается индикацией загрузки и, при необходимости, блокировкой новых операций переноса до получения подтверждения. -### Индикация переноса +### Подсветка текущего droppable -Можно добавить методы `onDragEnter/onDragMove/onDragLeave` для интеграции с внешним кодом, которые вызываются при заходе (`onDragEnter`), при каждом передвижении (`onDragMove`), и при выходе из `droppable` (`onDragLeave`). +Удобно, когда пользователь во время переноса наглядно видит, куда он сейчас положит draggable. Например, текущий droppable (или его часть) подсвечиваются. -При этом бывает, что нужно поддерживать перенос *в элемент*, но и перенос *между элементами*. Разберем два варианта такой ситуации: +Для этого в `DragManager` можно добавить дополнительные методы интеграции с внешним кодом: + -
    -
    Поддержка трех видов переноса: "между", "под", "над" `droppable`
    -
    Этот сценарий встречается, когда можно вставить статью как *в* существующий "узел-раздел" дерева, так и *между* разделами. +Возможен более сложный вариант, когда нужно поддерживать не только перенос *в элемент*, но и перенос *между элементами*, например вставку одной статьи между двумя другими. -В этом случае `droppable` делится на 3 части по высоте: 25% - 50% - 25%, берутся координаты элемента и определяется попадание координаты события на нужную часть. +Для этого код, который обрабатывает перенос, может "делить на части" droppable, к примеру, в отношении 25% - 50% - 25%, и смотреть: -В параметры `dragObject` добавляется флаг, обозначающий, куда по отношению к найденному `droppable` происходит перенос. -
    -
    Поддержка переноса только "между"
    -
    Здесь есть два варианта. -
      -
    1. Во-первых, можно разделить `droppable` в отношении 50%/50% и по координатам смотреть, куда мы попали.
    2. -
    3. В некоторых случаях, например при вставке между `droppable`-элементами списка, можно считать, что *элемент вставляется перед тем `LI`, над которым проходит*. +
        +
      • Если перенос в верхнюю четверть, то это -- "над".
      • +
      • Если перенос в середину, то это "внутрь".
      • +
      • Если перенос в нижнюю четверть, то это -- "под".
      • +
      -А чтобы вставить после последнего -- нужно перетащить аватар на сам DOM-элемент списка, но не на существующий `droppable`, а в пустое место, которое оставляется внизу для этой цели.
    4. -
    -
    -
    - -Индикацию "переноса между" удобнее всего делать либо раздвижением элементов, либо показом полосы-индикатора border-top/border-bottom, как показано на рисунке ниже: +Текущий `droppable` и позиция относительно него при этом могут помечаться подсветкой и жирной чертой над/под, если требуется. +Пример индикации из Firefox: ### Анимация отмены переноса + Отмену переноса и возврат аватара на место можно красиво анимировать. -Один из частых вариантов -- скольжение объекта обратно к исходному месту, откуда его взяли. Для этого достаточно поправить `avatar.revert()` соотвествующим образом. +Один из частых вариантов -- скольжение объекта обратно к исходному месту, откуда его взяли. Для этого достаточно поправить `avatar.rollback()`. ## Итого -Алгоритм Drag'n'Drop: +Уточнённый алгоритм Drag'n'Drop:
    1. При `mousedown` запомнить координаты нажатия.
    2. -
    3. При `mousemove` инициировать перенос, как только зажатый элемент передвинули на 3 пикселя или больше. +
    4. При `mousemove` инициировать перенос, как только зажатый элемент передвинули на 3 пикселя или больше. Сообщить во внешний код вызовом `onDragStart`.
      1. Создать аватар, если можно начать перенос с этой точки `draggable`.
      2. -
      3. Перемещать его по экрану. Новые координаты ставить по `e.pageX/pageY` с учетом изначального сдвига элемента относительно курсора.
      4. +
      5. Перемещать его по экрану, новые координаты ставить по `e.pageX/pageY` с учетом изначального сдвига элемента относительно курсора.
      6. +
      7. Сообщать во внешний код о текущем `droppable` под курсором и позиции над ним вызовами `onDragEnter`, `onDragMove`, `onDragLeave`.
      -
    5. При `mouseup` обработать завершение переноса. Элемент под аватаром получить по координатам, предварительно спрятав аватар.
    6. +
    7. При `mouseup` обработать завершение переноса. Элемент под аватаром получить по координатам, предварительно спрятав аватар. Сообщить во внешний код вызовом `onDragEnd`.
    -Получившийся попутно с обсуждением технических моментов Drag'n'Drop фреймворк обладает рядом особенностей: +Получившаяся реализация Drag'n'Drop проста, эффективна, изящна. -[compare] -+Он прост. Он действительно очень прост. -+Он полностью кросс-браузерный, не содержит хаков. -+Он позволяет работать с большим количеством потенциальных `draggable`/`droppable`. -+Его легко расширить и поменять. -[/compare] - -Вы можете получить файлы и посмотреть итоговое демо [edit src="dragDemo"]в песочнице[/edit]. - - -В зависимости от ваших задач, вы можете либо использовать его как отправную точку, либо реализовать свой. +Её очень легко поменять или адаптировать под "особые" потребности. ООП-вариант фреймворка находится в статье [](/drag-and-drop-plus). -[head] - -[/head] -[libs] -getCoords.js -[/libs] \ No newline at end of file diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/between.png b/2-ui/3-event-details/5-drag-and-drop-objects/between.png old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/7-drag-and-drop-objects/between.png rename to 2-ui/3-event-details/5-drag-and-drop-objects/between.png diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/DragManager.js b/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/DragManager.js old mode 100755 new mode 100644 similarity index 82% rename from 2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/DragManager.js rename to 2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/DragManager.js index cd288616..955c28fb --- a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/DragManager.js +++ b/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/DragManager.js @@ -1,4 +1,4 @@ -var dragManager = new function() { +var DragManager = new function() { /** * составной объект для хранения информации о переносе: @@ -17,7 +17,7 @@ var dragManager = new function() { if (e.which != 1) return; - var elem = findDraggable(e); + var elem = e.target.closest('.draggable'); if (!elem) return; dragObject.elem = elem; @@ -118,23 +118,22 @@ var dragManager = new function() { avatar.style.position = 'absolute'; } - function findDraggable(event) { - var elem = event.target; - while(elem != document && elem.getAttribute('draggable') == null) { - elem = elem.parentNode; - } - return elem == document ? null : elem; - } - function findDroppable(event) { + // спрячем переносимый элемент + dragObject.avatar.hidden = true; - var elem = getElementUnderClientXY(dragObject.avatar, event.clientX, event.clientY); + // получить самый вложенный элемент под курсором мыши + var elem = document.elementFromPoint(event.clientX, event.clientY); - while(elem != document && elem.getAttribute('droppable') == null) { - elem = elem.parentNode; + // показать переносимый элемент обратно + dragObject.avatar.hidden = false; + + if (elem == null) { + // такое возможно, если курсор мыши "вылетел" за границу окна + return null; } - return elem == document ? null : elem; + return elem.closest('.droppable'); } document.onmousemove = onMouseMove; @@ -145,3 +144,15 @@ var dragManager = new function() { this.onDragCancel = function(dragObject) { }; }; + + +function getCoords(elem) { // кроме IE8- + var box = elem.getBoundingClientRect(); + + return { + top: box.top + pageYOffset, + left: box.left + pageXOffset + }; + +} + diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/dragDemo.css b/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/dragDemo.css old mode 100755 new mode 100644 similarity index 88% rename from 2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/dragDemo.css rename to 2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/dragDemo.css index 0be6b3a1..19fdadb2 --- a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/dragDemo.css +++ b/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/dragDemo.css @@ -9,3 +9,7 @@ .computer-smile { background: url(//js.cx/clipart/computer-smile.gif) no-repeat; } + +.draggable { + cursor: pointer; +} \ No newline at end of file diff --git a/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/index.html b/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/index.html new file mode 100644 index 00000000..8fa656c1 --- /dev/null +++ b/2-ui/3-event-details/5-drag-and-drop-objects/dragDemo.view/index.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
    + + + + + +
    + +

    Браузер переносить сюда:

    + +
    +
    + + + diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/shiftx.png b/2-ui/3-event-details/5-drag-and-drop-objects/shiftx.png old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/7-drag-and-drop-objects/shiftx.png rename to 2-ui/3-event-details/5-drag-and-drop-objects/shiftx.png diff --git a/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.md b/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.md deleted file mode 100644 index 0c3b2ed2..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.md +++ /dev/null @@ -1,46 +0,0 @@ -# HTML/CSS, подсказка - -Слайдер -- это `DIV`, подкрашенный фоном/градиентом, внутри которого находится другой `DIV`, оформленный как бегунок, с `position:relative`. - -Бегунок немного поднят, и вылезает по высоте из родителя. - -# HTML/CSS для слайдера - -Например, вот так: - -```html - - - -
    -
    -
    -``` - -Теперь на этом реализуйте перенос бегунка. - -# Полное решение - - -Это горизонтальный Drag'n'Drop, ограниченный по ширине. Его особенность -- в `position:relative` у переносимого элемента, т.е. координата ставится не абсолютная, а относительно родителя. diff --git a/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/lib.js b/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/lib.js deleted file mode 100755 index 4b84d52a..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/1-slider/solution.view/lib.js +++ /dev/null @@ -1,44 +0,0 @@ - -function fixEvent(e) { - e = e || window.event; - - if (!e.target) e.target = e.srcElement; - - if (e.pageX == null && e.clientX != null ) { // если нет pageX.. - var html = document.documentElement; - var body = document.body; - - e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0); - e.pageX -= html.clientLeft || 0; - - e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0); - e.pageY -= html.clientTop || 0; - } - - if (!e.which && e.button) { - e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) ) - } - - return e; -} - - -function getCoords(elem) { - var box = elem.getBoundingClientRect(); - - var body = document.body; - var docElem = document.documentElement; - - var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop; - var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft; - - var clientTop = docElem.clientTop || body.clientTop || 0; - var clientLeft = docElem.clientLeft || body.clientLeft || 0; - - var top = box.top + scrollTop - clientTop; - var left = box.left + scrollLeft - clientLeft; - - return { top: Math.round(top), left: Math.round(left) }; -} - - diff --git a/2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/index.html b/2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/index.html deleted file mode 100755 index 7536c19b..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/lib.js b/2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/lib.js deleted file mode 100755 index 4b84d52a..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/1-slider/source.view/lib.js +++ /dev/null @@ -1,44 +0,0 @@ - -function fixEvent(e) { - e = e || window.event; - - if (!e.target) e.target = e.srcElement; - - if (e.pageX == null && e.clientX != null ) { // если нет pageX.. - var html = document.documentElement; - var body = document.body; - - e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0); - e.pageX -= html.clientLeft || 0; - - e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0); - e.pageY -= html.clientTop || 0; - } - - if (!e.which && e.button) { - e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) ) - } - - return e; -} - - -function getCoords(elem) { - var box = elem.getBoundingClientRect(); - - var body = document.body; - var docElem = document.documentElement; - - var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop; - var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft; - - var clientTop = docElem.clientTop || body.clientTop || 0; - var clientLeft = docElem.clientLeft || body.clientLeft || 0; - - var top = box.top + scrollTop - clientTop; - var left = box.left + scrollLeft - clientLeft; - - return { top: Math.round(top), left: Math.round(left) }; -} - - diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.js b/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.js deleted file mode 100755 index 405e0d93..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.view/soccer.js +++ /dev/null @@ -1,80 +0,0 @@ - - -document.body.onmousedown = function(e) { - - var dragElement = e.target; - - if (!dragElement.classList.contains('draggable')) return; - - var coords, shiftX, shiftY; - - startDrag(e.pageX, e.pageY); - - document.onmousemove = function(e) { - moveAt(e.pageX, e.pageY); - }; - - dragElement.onmouseup = function() { - finishDrag(); - }; - - - // ------------------------- - - function startDrag(pageX, pageY) { - - coords = getCoords(dragElement); - shiftX = pageX - coords.left; - shiftY = pageY - coords.top; - - dragElement.classList.add("dragging"); - dragElement.style.position = 'absolute'; - document.body.appendChild(dragElement); - - moveAt(pageX, pageY); - }; - - function finishDrag() { - dragElement.classList.remove('dragging'); - document.onmousemove = dragElement.onmouseup = null; - } - - function moveAt(pageX, pageY) { - var newX = pageX - shiftX; - var newY = pageY - shiftY; - - var newBottom = newY + dragElement.offsetHeight; - - var docScroll = getDocumentScroll(); - - // прокрутить вниз, если нужно - if (newBottom > docScroll.bottom) { - // ...но не за конец документа - var scrollSizeToEnd = docScroll.height - docScroll.bottom; - - // scrollBy, если его не ограничить, - // может заскроллить за текущую границу страницы - var toScrollY = Math.min(scrollSizeToEnd, 10); - window.scrollBy(0, toScrollY ); - - // при необходимости двигаем элемент вверх, чтобы поместился - // метод scrollBy асинхронный, поэтому учитываем будущую прокрутку (+toScrollY) - newY = Math.min(newY, docScroll.bottom - dragElement.offsetHeight + toScrollY); - } - - if (newY < docScroll.top) { - var toScrollY = Math.min(docScroll.top, 10); - window.scrollBy(0, -toScrollY ); - newY = Math.max(newY, docScroll.top - toScrollY ); - } - - // зажать в границах экрана по горизонтали - newX = Math.max(newX, 0); - newX = Math.min(newX, document.documentElement.clientWidth - dragElement.offsetHeight); - - dragElement.style.left = newX + 'px'; - dragElement.style.top = newY + 'px'; - } - - return false; -} \ No newline at end of file diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.js b/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.js deleted file mode 100755 index eb778e9f..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/source.view/soccer.js +++ /dev/null @@ -1,2 +0,0 @@ - -/* ваш код */ \ No newline at end of file diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/task.md b/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/task.md deleted file mode 100644 index 56f2db1a..00000000 --- a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/task.md +++ /dev/null @@ -1,13 +0,0 @@ -# Расставить супергероев по полю - -[importance 5] - -Сделайте так, чтобы элементы с классом `draggable` можно было переносить мышкой. - -Футбольное поле в этой задач слишком большое, чтобы показывать его здесь, поэтому откройте его, кликнув по ссылке ниже. Там же и подробное описание задачи (осторожно, винни-пух и супергерои!). - -[demo src="solution"] - - - -P.S. Для вашего удобства добавлены функции `getCoords` -- для координат и `getDocumentScroll` -- для получения границ видимой области и прокрутки в документе. \ No newline at end of file diff --git a/2-ui/3-event-details/4-mousewheel/1-scale-with-mouse-wheel/solution.md b/2-ui/3-event-details/6-mousewheel/1-scale-with-mouse-wheel/solution.md similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/1-scale-with-mouse-wheel/solution.md rename to 2-ui/3-event-details/6-mousewheel/1-scale-with-mouse-wheel/solution.md diff --git a/2-ui/3-event-details/4-mousewheel/1-scale-with-mouse-wheel/solution.view/index.html b/2-ui/3-event-details/6-mousewheel/1-scale-with-mouse-wheel/solution.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/1-scale-with-mouse-wheel/solution.view/index.html rename to 2-ui/3-event-details/6-mousewheel/1-scale-with-mouse-wheel/solution.view/index.html diff --git a/2-ui/3-event-details/4-mousewheel/1-scale-with-mouse-wheel/task.md b/2-ui/3-event-details/6-mousewheel/1-scale-with-mouse-wheel/task.md similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/1-scale-with-mouse-wheel/task.md rename to 2-ui/3-event-details/6-mousewheel/1-scale-with-mouse-wheel/task.md diff --git a/2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/solution.md b/2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/solution.md similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/solution.md rename to 2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/solution.md diff --git a/2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/solution.view/fix-textarea-scroll.js b/2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/solution.view/fix-textarea-scroll.js old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/solution.view/fix-textarea-scroll.js rename to 2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/solution.view/fix-textarea-scroll.js diff --git a/2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/solution.view/index.html b/2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/solution.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/solution.view/index.html rename to 2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/solution.view/index.html diff --git a/2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/source.view/index.html b/2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/source.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/source.view/index.html rename to 2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/source.view/index.html diff --git a/2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/task.md b/2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/task.md similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/2-no-doc-scroll/task.md rename to 2-ui/3-event-details/6-mousewheel/2-no-doc-scroll/task.md diff --git a/2-ui/3-event-details/4-mousewheel/article.md b/2-ui/3-event-details/6-mousewheel/article.md similarity index 84% rename from 2-ui/3-event-details/4-mousewheel/article.md rename to 2-ui/3-event-details/6-mousewheel/article.md index 474651e4..89bc302a 100644 --- a/2-ui/3-event-details/4-mousewheel/article.md +++ b/2-ui/3-event-details/6-mousewheel/article.md @@ -9,15 +9,15 @@ Несмотря на то, что колёсико мыши обычно ассоциируется с прокруткой, это совсем разные вещи. -Кроме того, событие `onscroll` происходит после прокрутки, а `onwheel` -- до прокрутки, поэтому в нём можно отменить саму прокрутку (действие браузера). +Кроме того, событие `onscroll` происходит *после* прокрутки, а `onwheel` -- *до* прокрутки, поэтому в нём можно отменить саму прокрутку (действие браузера). ## Зоопарк wheel в разных браузерах -Событие `wheel` появилось в [стандарте](http://www.w3.org/TR/DOM-Level-3-Events/#event-type-wheel) не так давно. Оно поддерживается IE9+, Firefox 17+. Возможно, другими браузерами на момент чтения этой статьи. +Событие `wheel` появилось в [стандарте](http://www.w3.org/TR/DOM-Level-3-Events/#event-type-wheel) не так давно. Оно поддерживается Chrome 31+, IE9+, Firefox 17+. До него браузеры обрабатывали прокрутку при помощи событий [mousewheel](http://msdn.microsoft.com/en-us/library/ie/ms536951.aspx) (все кроме Firefox) и [DOMMouseScroll](https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/DOMMouseScroll), [MozMousePixelScroll](https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/MozMousePixelScroll) (только Firefox). @@ -27,26 +27,24 @@
    Свойство `deltaY` -- количество прокрученных пикселей по горизонтали и вертикали. Существуют также свойства `deltaX` и `deltaZ` для других направлений прокрутки.
    `MozMousePixelScroll`
    Срабатывает, начиная с Firefox 3.5, только в Firefox. Даёт возможность отменить прокрутку и получить размер в пикселях через свойство `detail`, ось прокрутки в свойстве `axis`.
    -
    `DOMMouseScroll`
    -
    Существует в Firefox очень давно, отличается от предыдущего тем, что даёт в `detail` количество строк. Если не нужна поддержка Firefox < 3.5, то не нужно и это событие.
    `mousewheel`
    Срабатывает в браузерах, которые ещё не реализовали `wheel`. В свойстве `wheelDelta` -- условный "размер прокрутки", обычно равен `120` для прокрутки вверх и `-120` -- вниз. Он не соответствует какому-либо конкретному количеству пикселей.
    Чтобы кросс-браузерно отловить прокрутку и, при необходимости, отменить её, можно использовать все эти события. -Пример: +Пример, включающий поддержку IE8-: ```js if (elem.addEventListener) { if ('onwheel' in document) { - // IE9+, FF17+ + // IE9+, FF17+, Ch31+ elem.addEventListener ("wheel", onWheel, false); } else if ('onmousewheel' in document) { // устаревший вариант события elem.addEventListener ("mousewheel", onWheel, false); } else { - // 3.5 <= Firefox < 17, более старое событие DOMMouseScroll пропустим + // Firefox < 17 elem.addEventListener ("MozMousePixelScroll", onWheel, false); } } else { // IE<9 diff --git a/2-ui/3-event-details/4-mousewheel/wheel.view/index.html b/2-ui/3-event-details/6-mousewheel/wheel.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/4-mousewheel/wheel.view/index.html rename to 2-ui/3-event-details/6-mousewheel/wheel.view/index.html diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/index.html b/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/index.html deleted file mode 100755 index 4e3b9a95..00000000 --- a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - -

    Браузер переносить сюда:

    - -
    -
    - - - - diff --git a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/lib.js b/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/lib.js deleted file mode 100755 index 5d08fb5b..00000000 --- a/2-ui/3-event-details/7-drag-and-drop-objects/dragDemo.view/lib.js +++ /dev/null @@ -1,30 +0,0 @@ - -function getCoords(elem) { - var box = elem.getBoundingClientRect(); - - var body = document.body; - var docElem = document.documentElement; - - var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop; - var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft; - - var clientTop = docElem.clientTop || body.clientTop || 0; - var clientLeft = docElem.clientLeft || body.clientLeft || 0; - - var top = box.top + scrollTop - clientTop; - var left = box.left + scrollLeft - clientLeft; - - return { top: Math.round(top), left: Math.round(left) }; -} - -function getElementUnderClientXY(elem, clientX, clientY) { - var display = elem.style.display || ''; - elem.style.display = 'none'; - - var target = document.elementFromPoint(clientX, clientY); - - elem.style.display = display; - - return target; -} - diff --git a/2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/solution.md b/2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/solution.md deleted file mode 100644 index e69de29b..00000000 diff --git a/2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.md b/2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/solution.md similarity index 100% rename from 2-ui/3-event-details/6-drag-and-drop/2-drag-heroes/solution.md rename to 2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/solution.md diff --git a/2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/solution.view/index.html b/2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/solution.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/solution.view/index.html rename to 2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/solution.view/index.html diff --git a/2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/source.view/index.html b/2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/source.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/source.view/index.html rename to 2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/source.view/index.html diff --git a/2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/task.md b/2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/task.md similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/1-avatar-above-scroll/task.md rename to 2-ui/3-event-details/9-onscroll/1-avatar-above-scroll/task.md diff --git a/2-ui/3-event-details/9-event-onscroll/2-updown-button/solution.md b/2-ui/3-event-details/9-onscroll/2-updown-button/solution.md similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/2-updown-button/solution.md rename to 2-ui/3-event-details/9-onscroll/2-updown-button/solution.md diff --git a/2-ui/3-event-details/9-event-onscroll/2-updown-button/solution.view/index.html b/2-ui/3-event-details/9-onscroll/2-updown-button/solution.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/2-updown-button/solution.view/index.html rename to 2-ui/3-event-details/9-onscroll/2-updown-button/solution.view/index.html diff --git a/2-ui/3-event-details/9-event-onscroll/2-updown-button/source.view/index.html b/2-ui/3-event-details/9-onscroll/2-updown-button/source.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/2-updown-button/source.view/index.html rename to 2-ui/3-event-details/9-onscroll/2-updown-button/source.view/index.html diff --git a/2-ui/3-event-details/9-event-onscroll/2-updown-button/task.md b/2-ui/3-event-details/9-onscroll/2-updown-button/task.md similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/2-updown-button/task.md rename to 2-ui/3-event-details/9-onscroll/2-updown-button/task.md diff --git a/2-ui/3-event-details/9-event-onscroll/3-load-visible-img/solution.md b/2-ui/3-event-details/9-onscroll/3-load-visible-img/solution.md similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/3-load-visible-img/solution.md rename to 2-ui/3-event-details/9-onscroll/3-load-visible-img/solution.md diff --git a/2-ui/3-event-details/9-event-onscroll/3-load-visible-img/solution.view/index.html b/2-ui/3-event-details/9-onscroll/3-load-visible-img/solution.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/3-load-visible-img/solution.view/index.html rename to 2-ui/3-event-details/9-onscroll/3-load-visible-img/solution.view/index.html diff --git a/2-ui/3-event-details/9-event-onscroll/3-load-visible-img/source.view/index.html b/2-ui/3-event-details/9-onscroll/3-load-visible-img/source.view/index.html old mode 100755 new mode 100644 similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/3-load-visible-img/source.view/index.html rename to 2-ui/3-event-details/9-onscroll/3-load-visible-img/source.view/index.html diff --git a/2-ui/3-event-details/9-event-onscroll/3-load-visible-img/task.md b/2-ui/3-event-details/9-onscroll/3-load-visible-img/task.md similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/3-load-visible-img/task.md rename to 2-ui/3-event-details/9-onscroll/3-load-visible-img/task.md diff --git a/2-ui/3-event-details/9-event-onscroll/article.md b/2-ui/3-event-details/9-onscroll/article.md similarity index 100% rename from 2-ui/3-event-details/9-event-onscroll/article.md rename to 2-ui/3-event-details/9-onscroll/article.md diff --git a/3-more/11-css-for-js/6-css-center/1-center-ball-css/solution.view/index.html b/3-more/11-css-for-js/6-css-center/1-center-ball-css/solution.view/index.html index 5cf76695..a431611d 100755 --- a/3-more/11-css-for-js/6-css-center/1-center-ball-css/solution.view/index.html +++ b/3-more/11-css-for-js/6-css-center/1-center-ball-css/solution.view/index.html @@ -22,7 +22,7 @@
    - + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
    diff --git a/3-more/11-css-for-js/6-css-center/1-center-ball-css/source.view/index.html b/3-more/11-css-for-js/6-css-center/1-center-ball-css/source.view/index.html index 397cf9e1..5a17ab77 100755 --- a/3-more/11-css-for-js/6-css-center/1-center-ball-css/source.view/index.html +++ b/3-more/11-css-for-js/6-css-center/1-center-ball-css/source.view/index.html @@ -18,7 +18,7 @@
    - + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
    diff --git a/3-more/2-animation/1-js-animation/3-animate-ball/solution.view/index.html b/3-more/2-animation/1-js-animation/3-animate-ball/solution.view/index.html index de89a4e7..4a7fad6f 100755 --- a/3-more/2-animation/1-js-animation/3-animate-ball/solution.view/index.html +++ b/3-more/2-animation/1-js-animation/3-animate-ball/solution.view/index.html @@ -18,7 +18,7 @@
    - +
    \n\n\n", "_id" : { "$oid" : "54c29be6f1f6dbff33a78ffc" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29be7f1f6dbff33a79047" }, "plunkId" : "JXt15iP3lQF2sgDr7chE", "webPath" : "/article/debugging-chrome/debugging", "files" : [ { "filename" : "pow.js", "content" : "function pow(x, n) {\n if (n == 1) {\n return x;\n }\n\n var result = x * pow(x, n-1);\n return result;\n}", "_id" : { "$oid" : "54c29be7f1f6dbff33a79048" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n \n\n Пример для отладчика.\n\n \n\n\n", "_id" : { "$oid" : "54c29be7f1f6dbff33a79049" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29be8f1f6dbff33a7904a" }, "plunkId" : "Jqi6UB1eZOiAo6XROgPp", "webPath" : "/article/debugging-chrome/error", "files" : [ { "filename" : "pow.js", "content" : "function pow(x, n) {\n if (n == 1) {\n return y;\n }\n\n var result = x * pow(x, n-1);\n return result;\n}", "_id" : { "$oid" : "54c29be8f1f6dbff33a7904b" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n \n\n Пример для отладчика.\n\n \n\n\n", "_id" : { "$oid" : "54c29be8f1f6dbff33a7904c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29be8f1f6dbff33a79052" }, "plunkId" : "wj6R3aEKhvGGdIsdBeHI", "webPath" : "/task/pow-nan-spec/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29be8f1f6dbff33a79053" } }, { "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() { \n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ), \"pow(2, -1) не NaN\" );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ), \"pow(2, -1.5) не NaN\" );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29be8f1f6dbff33a79054" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29be9f1f6dbff33a79055" }, "plunkId" : "UUGOyt6YjpIQzWWQl7g0", "webPath" : "/task/pow-nan-spec/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29be9f1f6dbff33a79056" } }, { "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() { \n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ), \"pow(2, -1) не NaN\" );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ), \"pow(2, -1.5) не NaN\" );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29be9f1f6dbff33a79057" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29be9f1f6dbff33a79059" }, "plunkId" : "EvgZMmUqKRhkOgbwgTqX", "webPath" : "/task/pow-test-0/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29be9f1f6dbff33a7905a" } }, { "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() { \n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ), \"pow(2, -1) не NaN\" );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ), \"pow(2, -1.5) не NaN\" );\n });\n\n describe(\"любое число, кроме нуля, в степени 0 равно 1\", function() {\n\n function makeTest(x) {\n it(\"при возведении \" + x + \" в степень 0 результат: 1\", function() { \n assert.equal( pow(x, 0), 1);\n });\n }\n\n for(var x = -5; x <= 5; x+=2) {\n makeTest(x);\n }\n\n });\n \n it(\"ноль в нулевой степени даёт NaN\", function() {\n assert( isNaN( pow(0,0) ), \"0 в степени 0 не NaN\");\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29be9f1f6dbff33a7905b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beaf1f6dbff33a7905c" }, "plunkId" : "5mLcclqwzclxKKC5MKyi", "webPath" : "/task/pow-test-0/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beaf1f6dbff33a7905d" } }, { "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() { \n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ), \"pow(2, -1) не NaN\" );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ), \"pow(2, -1.5) не NaN\" );\n });\n\n describe(\"любое число, кроме нуля, в степени 0 равно 1\", function() {\n\n function makeTest(x) {\n it(\"при возведении \" + x + \" в степень 0 результат: 1\", function() { \n assert.equal( pow(x, 0), 1);\n });\n }\n\n for(var x = -5; x <= 5; x+=2) {\n makeTest(x);\n }\n\n });\n \n it(\"ноль в нулевой степени даёт NaN\", function() {\n assert( isNaN( pow(0,0) ), \"0 в степени 0 не NaN\");\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beaf1f6dbff33a7905e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beaf1f6dbff33a79060" }, "plunkId" : "wcxcVPoqZ2TvD0d0eMvC", "webPath" : "/article/testing/beforeafter", "files" : [ { "filename" : "test.js", "content" : "describe(\"Тест\", function() {\n\n before(function() { alert(\"Начало всех тестов\"); });\n after(function() { alert(\"Окончание всех тестов\"); });\n\n beforeEach(function() { alert(\"Вход в тест\"); });\n afterEach(function() { alert(\"Выход из теста\"); });\n\n it('тест 1', function() { alert('1'); });\n it('тест 2', function() { alert('2'); });\n\n});", "_id" : { "$oid" : "54c29beaf1f6dbff33a79061" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n\n\n\n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29beaf1f6dbff33a79062" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bebf1f6dbff33a79063" }, "plunkId" : "BRTxPBwU90IVY101AWp9", "webPath" : "/article/testing/pow-1", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n it(\"возводит в n-ю степень\", function() {\n assert.equal( pow(2, 3), 8);\n });\n\n});", "_id" : { "$oid" : "54c29bebf1f6dbff33a79064" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29bebf1f6dbff33a79065" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bebf1f6dbff33a79066" }, "plunkId" : "pZcAl1SDyOnJcpQqhnGG", "webPath" : "/article/testing/pow-2", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n it(\"при возведении 2 в 3ю степень результат 8\", function() {\n assert.equal( pow(2, 3), 8);\n });\n\n it(\"при возведении 3 в 4ю степень равен 81\", function() {\n assert.equal( pow(3, 4), 81);\n });\n\n});", "_id" : { "$oid" : "54c29bebf1f6dbff33a79067" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29bebf1f6dbff33a79068" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bebf1f6dbff33a79069" }, "plunkId" : "TfSoGJNH3nMLkcRu9kFs", "webPath" : "/article/testing/pow-3", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() {\n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n});", "_id" : { "$oid" : "54c29bebf1f6dbff33a7906a" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29bebf1f6dbff33a7906b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29becf1f6dbff33a7906c" }, "plunkId" : "Mu7pOjHzI64Kib6C1Qo9", "webPath" : "/article/testing/pow-4", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() {\n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n // ...\n\n});", "_id" : { "$oid" : "54c29becf1f6dbff33a7906d" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29becf1f6dbff33a7906e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29becf1f6dbff33a7906f" }, "plunkId" : "4rpPTXSp1gkKSr15aRcP", "webPath" : "/article/testing/pow-full", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() {\n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ), \"pow(2, -1) не NaN\" );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ), \"pow(2, -1.5) не NaN\" );\n });\n\n describe(\"любое число, кроме нуля, в степени 0 равно 1\", function() {\n\n function makeTest(x) {\n it(\"при возведении \" + x + \" в степень 0 результат: 1\", function() {\n assert.equal( pow(x, 0), 1);\n });\n }\n\n for(var x = -5; x <= 5; x+=2) {\n makeTest(x);\n }\n\n });\n\n it(\"ноль в нулевой степени даёт NaN\", function() {\n assert( isNaN( pow(0,0) ), \"0 в степени 0 не NaN\");\n });\n\n});", "_id" : { "$oid" : "54c29becf1f6dbff33a79070" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29becf1f6dbff33a79071" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29becf1f6dbff33a79072" }, "plunkId" : "DIYCWcygQGYSedglXtaw", "webPath" : "/article/testing/pow-min", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n it(\"возводит в n-ю степень\", function() {\n assert.equal( pow(2, 3), 8);\n });\n\n});", "_id" : { "$oid" : "54c29becf1f6dbff33a79073" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29becf1f6dbff33a79074" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bedf1f6dbff33a79075" }, "plunkId" : "Kbu6DKN4lIlyQRlT3iPb", "webPath" : "/article/testing/pow-nan-assert", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() {\n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ), \"pow(2, -1) не NaN\" );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ), \"pow(2, -1.5) не NaN\" );\n });\n\n});", "_id" : { "$oid" : "54c29bedf1f6dbff33a79076" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29bedf1f6dbff33a79077" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bedf1f6dbff33a79078" }, "plunkId" : "CgiMHkmIqPytKY6vYxJC", "webPath" : "/article/testing/pow-nan", "files" : [ { "filename" : "test.js", "content" : "describe(\"pow\", function() {\n\n describe(\"возводит x в степень n\", function() {\n\n function makeTest(x) {\n var expected = x*x*x;\n it(\"при возведении \"+x+\" в степень 3 результат: \" + expected, function() {\n assert.equal( pow(x, 3), expected);\n });\n }\n\n for(var x = 1; x <= 5; x++) {\n makeTest(x);\n }\n\n });\n\n it(\"при возведении в отрицательную степень результат NaN\", function() {\n assert( isNaN( pow(2, -1) ) );\n });\n\n it(\"при возведении в дробную степень результат NaN\", function() {\n assert( isNaN( pow(2, 1.5) ) );\n });\n\n});", "_id" : { "$oid" : "54c29bedf1f6dbff33a79079" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n \n\n \n \n\n \n
    \n\n \n \n\n", "_id" : { "$oid" : "54c29bedf1f6dbff33a7907a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bedf1f6dbff33a79085" }, "plunkId" : "fGUz2IW103pRPABKlynw", "webPath" : "/task/get-week-day/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bedf1f6dbff33a79086" } }, { "content" : "describe(\"getWeekDay\", function() {\n it(\"3 января 2014 - пятница\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 3)), 'пт');\n });\n\n it(\"4 января 2014 - суббота\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 4)), 'сб');\n });\n\n it(\"5 января 2014 - воскресенье\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 5)), 'вс');\n });\n\n it(\"6 января 2014 - понедельник\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 6)), 'пн');\n });\n\n it(\"7 января 2014 - вторник\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 7)), 'вт');\n });\n\n it(\"8 января 2014 - среда\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 8)), 'ср');\n });\n\n it(\"9 января 2014 - четверг\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 9)), 'чт');\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bedf1f6dbff33a79087" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beef1f6dbff33a79088" }, "plunkId" : "gxiHwbLOdMNvxIoM30B3", "webPath" : "/task/get-week-day/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beef1f6dbff33a79089" } }, { "content" : "describe(\"getWeekDay\", function() {\n it(\"3 января 2014 - пятница\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 3)), 'пт');\n });\n\n it(\"4 января 2014 - суббота\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 4)), 'сб');\n });\n\n it(\"5 января 2014 - воскресенье\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 5)), 'вс');\n });\n\n it(\"6 января 2014 - понедельник\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 6)), 'пн');\n });\n\n it(\"7 января 2014 - вторник\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 7)), 'вт');\n });\n\n it(\"8 января 2014 - среда\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 8)), 'ср');\n });\n\n it(\"9 января 2014 - четверг\", function() {\n assert.equal( getWeekDay(new Date(2014, 0, 9)), 'чт');\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beef1f6dbff33a7908a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beef1f6dbff33a7908c" }, "plunkId" : "dNXQF6cXh9YcjfFO9wg8", "webPath" : "/task/weekday/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beef1f6dbff33a7908d" } }, { "content" : "describe(\"getLocalDay возвращает день недели\", function() {\n it(\"3 января 2014 - пятница\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 3)), 5);\n });\n\n it(\"4 января 2014 - суббота\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 4)), 6);\n });\n\n it(\"5 января 2014 - воскресенье\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 5)), 7);\n });\n\n it(\"6 января 2014 - понедельник\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 6)), 1);\n });\n\n it(\"7 января 2014 - вторник\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 7)), 2);\n });\n\n it(\"8 января 2014 - среда\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 8)), 3);\n });\n\n it(\"9 января 2014 - четверг\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 9)), 4);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beef1f6dbff33a7908e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beef1f6dbff33a7908f" }, "plunkId" : "l0iIrVdLglsJXbSrs0O5", "webPath" : "/task/weekday/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beef1f6dbff33a79090" } }, { "content" : "describe(\"getLocalDay возвращает день недели\", function() {\n it(\"3 января 2014 - пятница\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 3)), 5);\n });\n\n it(\"4 января 2014 - суббота\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 4)), 6);\n });\n\n it(\"5 января 2014 - воскресенье\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 5)), 7);\n });\n\n it(\"6 января 2014 - понедельник\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 6)), 1);\n });\n\n it(\"7 января 2014 - вторник\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 7)), 2);\n });\n\n it(\"8 января 2014 - среда\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 8)), 3);\n });\n\n it(\"9 января 2014 - четверг\", function() {\n assert.equal( getLocalDay(new Date(2014, 0, 9)), 4);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beef1f6dbff33a79091" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beef1f6dbff33a79093" }, "plunkId" : "DbaSZgtEYslVIFAqaQMp", "webPath" : "/task/get-date-ago/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beef1f6dbff33a79094" } }, { "content" : "describe(\"getDateAgo\", function() {\n\n it(\"1 день до 02.01.2015 -> число 1\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 1), 1 );\n });\n\n\n it(\"2 день до 02.01.2015 -> число 31\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 2), 31 );\n });\n\n it(\"100 дней от 02.01.2015 -> число 24\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 100), 24 );\n });\n\n it(\"365 дней от 02.01.2015 -> число 2\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 365), 2 );\n });\n\n it(\"не меняет переданный объект Date\", function() {\n var date = new Date(2015, 0, 2);\n var dateCopy = new Date(date);\n getDateAgo(dateCopy, 100);\n assert.equal(date.getTime(), dateCopy.getTime());\n });\n \n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beef1f6dbff33a79095" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beff1f6dbff33a79096" }, "plunkId" : "kbMcueSHQAOIq5XXqX8L", "webPath" : "/task/get-date-ago/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beff1f6dbff33a79097" } }, { "content" : "describe(\"getDateAgo\", function() {\n\n it(\"1 день до 02.01.2015 -> число 1\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 1), 1 );\n });\n\n\n it(\"2 день до 02.01.2015 -> число 31\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 2), 31 );\n });\n\n it(\"100 дней от 02.01.2015 -> число 24\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 100), 24 );\n });\n\n it(\"365 дней от 02.01.2015 -> число 2\", function() {\n assert.equal( getDateAgo(new Date(2015, 0, 2), 365), 2 );\n });\n\n it(\"не меняет переданный объект Date\", function() {\n var date = new Date(2015, 0, 2);\n var dateCopy = new Date(date);\n getDateAgo(dateCopy, 100);\n assert.equal(date.getTime(), dateCopy.getTime());\n });\n \n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beff1f6dbff33a79098" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29beff1f6dbff33a7909a" }, "plunkId" : "TThEf1Cq5Jw7aIxGEokl", "webPath" : "/task/last-day-of-month/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29beff1f6dbff33a7909b" } }, { "content" : "describe(\"getLastDayOfMonth\", function() {\n it(\"последний день 01.01.2012 - 31\", function() {\n assert.equal( getLastDayOfMonth(2012, 0), 31);\n });\n\n it(\"последний день 01.02.2012 - 29 (високосный год)\", function() {\n assert.equal( getLastDayOfMonth(2012, 1), 29);\n });\n\n it(\"последний день 01.02.2013 - 28\", function() {\n assert.equal( getLastDayOfMonth(2013, 1), 28);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29beff1f6dbff33a7909c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf0f1f6dbff33a7909d" }, "plunkId" : "nBODZdcm1zySLsHLr5y9", "webPath" : "/task/last-day-of-month/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf0f1f6dbff33a7909e" } }, { "content" : "describe(\"getLastDayOfMonth\", function() {\n it(\"последний день 01.01.2012 - 31\", function() {\n assert.equal( getLastDayOfMonth(2012, 0), 31);\n });\n\n it(\"последний день 01.02.2012 - 29 (високосный год)\", function() {\n assert.equal( getLastDayOfMonth(2012, 1), 29);\n });\n\n it(\"последний день 01.02.2013 - 28\", function() {\n assert.equal( getLastDayOfMonth(2013, 1), 28);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf0f1f6dbff33a7909f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf0f1f6dbff33a790a3" }, "plunkId" : "i4qMM0BHacTJaZOvsZEp", "webPath" : "/task/format-date-ddmmyy/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf0f1f6dbff33a790a4" } }, { "content" : "describe(\"formatDate\", function() {\n it(\"правильно форматирует дату 30.01.14\", function() {\n assert.equal( formatDate(new Date(2014, 0, 30)), '30.01.14');\n });\n\n it(\"правильно форматирует дату 01.01.01\", function() {\n assert.equal( formatDate(new Date(2001, 0, 1)), '01.01.01');\n });\n\n it(\"правильно форматирует дату 01.01.00\", function() {\n assert.equal( formatDate(new Date(2000, 0, 1)), '01.01.00');\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf0f1f6dbff33a790a5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf1f1f6dbff33a790a6" }, "plunkId" : "56u7g6fp0lt2wJUmtExn", "webPath" : "/task/format-date-ddmmyy/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf1f1f6dbff33a790a7" } }, { "content" : "describe(\"formatDate\", function() {\n it(\"правильно форматирует дату 30.01.14\", function() {\n assert.equal( formatDate(new Date(2014, 0, 30)), '30.01.14');\n });\n\n it(\"правильно форматирует дату 01.01.01\", function() {\n assert.equal( formatDate(new Date(2001, 0, 1)), '01.01.01');\n });\n\n it(\"правильно форматирует дату 01.01.00\", function() {\n assert.equal( formatDate(new Date(2000, 0, 1)), '01.01.00');\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf1f1f6dbff33a790a8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf2f1f6dbff33a790aa" }, "plunkId" : "mhJxWaIODMqOWXMYa6Bw", "webPath" : "/task/format-date-relative/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf2f1f6dbff33a790ab" } }, { "content" : "describe(\"formatDate\", function() {\n it(\"выводит дату 1мс назад как \\\"только что\\\"\", function() {\n assert.equal( formatDate( new Date(new Date - 1) ), 'только что' );\n });\n\n it('выводит дату \"30 сек назад\"', function() {\n assert.equal( formatDate( new Date( new Date - 30*1000) ), \"30 сек. назад\" );\n });\n\n it('выводит дату \"5 мин назад\"', function() {\n assert.equal( formatDate( new Date( new Date- 5*60*1000) ), \"5 мин. назад\");\n });\n\n it(\"выводит старую дату в формате дд.мм.гг чч:мм\", function() {\n assert.equal( formatDate( new Date(2014, 2, 1, 11, 22, 33) ), \"01.03.14 11:22\" ); \n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf2f1f6dbff33a790ac" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf2f1f6dbff33a790ad" }, "plunkId" : "pX78csZkjHN1hmaT5LVw", "webPath" : "/task/format-date-relative/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf2f1f6dbff33a790ae" } }, { "content" : "describe(\"formatDate\", function() {\n it(\"выводит дату 1мс назад как \\\"только что\\\"\", function() {\n assert.equal( formatDate( new Date(new Date - 1) ), 'только что' );\n });\n\n it('выводит дату \"30 сек назад\"', function() {\n assert.equal( formatDate( new Date( new Date - 30*1000) ), \"30 сек. назад\" );\n });\n\n it('выводит дату \"5 мин назад\"', function() {\n assert.equal( formatDate( new Date( new Date- 5*60*1000) ), \"5 мин. назад\");\n });\n\n it(\"выводит старую дату в формате дд.мм.гг чч:мм\", function() {\n assert.equal( formatDate( new Date(2014, 2, 1, 11, 22, 33) ), \"01.03.14 11:22\" ); \n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf2f1f6dbff33a790af" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf3f1f6dbff33a790b3" }, "plunkId" : "ZwGwBJfDpVDHd6McavjZ", "webPath" : "/task/format-date-polymorphic/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf3f1f6dbff33a790b4" } }, { "content" : "describe(\"formatDate\", function() {\n it(\"читает дату вида гггг-мм-дд из строки\", function() {\n assert.equal( formatDate( '2011-10-02' ), \"02.10.11\" );\n });\n\n it(\"читает дату из числа 1234567890 (миллисекунды)\", function() {\n assert.equal( formatDate( 1234567890 ), \"14.02.09\" );\n });\n\n it(\"читает дату из массива вида [гггг, м, д]\", function() {\n assert.equal( formatDate( [2014,0,1] ), \"01.01.14\" );\n });\n\n it(\"читает дату из объекта Date\", function() {\n assert.equal( formatDate( new Date(2014,0,1) ), \"01.01.14\" );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf3f1f6dbff33a790b5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf4f1f6dbff33a790b6" }, "plunkId" : "T6VXXKvb2lzRhvLGx96Q", "webPath" : "/task/format-date-polymorphic/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf4f1f6dbff33a790b7" } }, { "content" : "describe(\"formatDate\", function() {\n it(\"читает дату вида гггг-мм-дд из строки\", function() {\n assert.equal( formatDate( '2011-10-02' ), \"02.10.11\" );\n });\n\n it(\"читает дату из числа 1234567890 (миллисекунды)\", function() {\n assert.equal( formatDate( 1234567890 ), \"14.02.09\" );\n });\n\n it(\"читает дату из массива вида [гггг, м, д]\", function() {\n assert.equal( formatDate( [2014,0,1] ), \"01.01.14\" );\n });\n\n it(\"читает дату из объекта Date\", function() {\n assert.equal( formatDate( new Date(2014,0,1) ), \"01.01.14\" );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf4f1f6dbff33a790b8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf5f1f6dbff33a790bf" }, "plunkId" : "dI0e24Z26dEsPb76smZm", "webPath" : "/task/get-decimal/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf5f1f6dbff33a790c0" } }, { "content" : "describe(\"getDecimal\", function() {\n it(\"возвращает дробную часть 1.2 как 0.2\", function() {\n assert.equal( getDecimal(1.2), 0.2 );\n });\n\n it(\"возвращает дробную часть 1.3 как 0.3\", function() {\n assert.equal( getDecimal(1.3), 0.3 );\n });\n\n it(\"возвращает дробную часть 12.345 как 0.345\", function() {\n assert.equal( getDecimal(12.345), 0.345 );\n });\n\n it(\"возвращает дробную часть -1.2 как 0.2\", function() {\n assert.equal( getDecimal(-1.2), 0.2 );\n });\n\n it(\"возвращает дробную часть 5 как 0\", function() {\n assert.equal( getDecimal(5), 0 );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf5f1f6dbff33a790c1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf7f1f6dbff33a790c2" }, "plunkId" : "OEHVDOsrktb0iNqZbAl6", "webPath" : "/task/get-decimal/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf7f1f6dbff33a790c3" } }, { "content" : "describe(\"getDecimal\", function() {\n it(\"возвращает дробную часть 1.2 как 0.2\", function() {\n assert.equal( getDecimal(1.2), 0.2 );\n });\n\n it(\"возвращает дробную часть 1.3 как 0.3\", function() {\n assert.equal( getDecimal(1.3), 0.3 );\n });\n\n it(\"возвращает дробную часть 12.345 как 0.345\", function() {\n assert.equal( getDecimal(12.345), 0.345 );\n });\n\n it(\"возвращает дробную часть -1.2 как 0.2\", function() {\n assert.equal( getDecimal(-1.2), 0.2 );\n });\n\n it(\"возвращает дробную часть 5 как 0\", function() {\n assert.equal( getDecimal(5), 0 );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf7f1f6dbff33a790c4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf7f1f6dbff33a790cb" }, "plunkId" : "XR2NCjSLjmoL6mXMIfK0", "webPath" : "/task/ucfirst/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf7f1f6dbff33a790cc" } }, { "content" : "describe(\"ucFirst\", function() {\n it('делает первый символ заглавным', function() {\n assert.strictEqual( ucFirst(\"вася\"), \"Вася\" );\n });\n \n it('для пустой строки возвращает пустую строку', function() {\n assert.strictEqual( ucFirst(\"\"), \"\" );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf7f1f6dbff33a790cd" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf8f1f6dbff33a790ce" }, "plunkId" : "yYIdS2ssYEi24EWAUtVg", "webPath" : "/task/ucfirst/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf8f1f6dbff33a790cf" } }, { "content" : "describe(\"ucFirst\", function() {\n it('делает первый символ заглавным', function() {\n assert.strictEqual( ucFirst(\"вася\"), \"Вася\" );\n });\n \n it('для пустой строки возвращает пустую строку', function() {\n assert.strictEqual( ucFirst(\"\"), \"\" );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf8f1f6dbff33a790d0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bf8f1f6dbff33a790d2" }, "plunkId" : "IMUHBftr2fHGwdjXt5xo", "webPath" : "/task/check-spam/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bf8f1f6dbff33a790d3" } }, { "content" : "describe(\"checkSpam\", function() {\n it('считает спамом \"buy ViAgRA now\"', function() {\n assert.isTrue( checkSpam('buy ViAgRA now') );\n });\n\n it('считает спамом \"free xxxxx\"', function() {\n assert.isTrue( checkSpam('free xxxxx') );\n });\n\n it('не считает спамом \"innocent rabbit\"', function() {\n assert.isFalse( checkSpam('innocent rabbit') );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bf8f1f6dbff33a790d4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfaf1f6dbff33a790d5" }, "plunkId" : "bi8jqIL2b9hb0labsHoE", "webPath" : "/task/check-spam/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfaf1f6dbff33a790d6" } }, { "content" : "describe(\"checkSpam\", function() {\n it('считает спамом \"buy ViAgRA now\"', function() {\n assert.isTrue( checkSpam('buy ViAgRA now') );\n });\n\n it('считает спамом \"free xxxxx\"', function() {\n assert.isTrue( checkSpam('free xxxxx') );\n });\n\n it('не считает спамом \"innocent rabbit\"', function() {\n assert.isFalse( checkSpam('innocent rabbit') );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfaf1f6dbff33a790d7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfaf1f6dbff33a790d9" }, "plunkId" : "M91IJNY971ZyCR6R1ywj", "webPath" : "/task/truncate/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfaf1f6dbff33a790da" } }, { "content" : "describe(\"truncate\", function() {\n it(\"обрезает строку до указанной длины (включая троеточие)\", function() {\n assert.equal( \n truncate(\"Вот, что мне хотелось бы сказать на эту тему:\", 20),\n \"Вот, что мне хоте...\"\n );\n });\n\n it(\"не меняет короткие строки\", function() {\n assert.equal( \n truncate(\"Всем привет!\", 20), \n \"Всем привет!\"\n );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfaf1f6dbff33a790db" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfbf1f6dbff33a790dc" }, "plunkId" : "mAhamvQCfrejkLGtpJ1f", "webPath" : "/task/truncate/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfbf1f6dbff33a790dd" } }, { "content" : "describe(\"truncate\", function() {\n it(\"обрезает строку до указанной длины (включая троеточие)\", function() {\n assert.equal( \n truncate(\"Вот, что мне хотелось бы сказать на эту тему:\", 20),\n \"Вот, что мне хоте...\"\n );\n });\n\n it(\"не меняет короткие строки\", function() {\n assert.equal( \n truncate(\"Всем привет!\", 20), \n \"Всем привет!\"\n );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfbf1f6dbff33a790de" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfbf1f6dbff33a790e4" }, "plunkId" : "Kq5IjJHxWmiStR335j1a", "webPath" : "/task/is-empty/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfbf1f6dbff33a790e5" } }, { "content" : "describe(\"isEmpty\", function() {\n it(\"если объект пустой - возвращает true\", function() {\n assert.isTrue( isEmpty({}) );\n });\n\n it(\"если у объекта есть любое свойство, не важно какое - возвращает false\", function() {\n assert.isFalse( isEmpty({ anything: false }) );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfbf1f6dbff33a790e6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfcf1f6dbff33a790e7" }, "plunkId" : "IULv5iIrhtyVl2VHcSLT", "webPath" : "/task/is-empty/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfcf1f6dbff33a790e8" } }, { "content" : "describe(\"isEmpty\", function() {\n it(\"если объект пустой - возвращает true\", function() {\n assert.isTrue( isEmpty({}) );\n });\n\n it(\"если у объекта есть любое свойство, не важно какое - возвращает false\", function() {\n assert.isFalse( isEmpty({ anything: false }) );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfcf1f6dbff33a790e9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfcf1f6dbff33a790ed" }, "plunkId" : "aiU8nDF7DpRFMjgFT8Wl", "webPath" : "/task/multiply-numeric/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfcf1f6dbff33a790ee" } }, { "content" : "describe(\"multiplyNumeric\", function() {\n it(\"умножает численные свойства на 2\", function() {\n var menu = {\n width: 200,\n height: \"300\",\n title: \"Моё меню\"\n };\n multiplyNumeric(menu);\n assert.equal( menu.width, 400 );\n assert.equal( menu.height, 600 );\n assert.equal( menu.title, \"Моё меню\" );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfcf1f6dbff33a790ef" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfcf1f6dbff33a790f0" }, "plunkId" : "fTVHgjHG6dSSfQ5sGlgu", "webPath" : "/task/multiply-numeric/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfcf1f6dbff33a790f1" } }, { "content" : "describe(\"multiplyNumeric\", function() {\n it(\"умножает численные свойства на 2\", function() {\n var menu = {\n width: 200,\n height: \"300\",\n title: \"Моё меню\"\n };\n multiplyNumeric(menu);\n assert.equal( menu.width, 400 );\n assert.equal( menu.height, 600 );\n assert.equal( menu.title, \"Моё меню\" );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfcf1f6dbff33a790f2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29bfff1f6dbff33a790f8" }, "plunkId" : "TrDAjJbGpXmV3EoDwehV", "webPath" : "/task/maximal-subarray/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29bfff1f6dbff33a790f9" } }, { "content" : "describe(\"getMaxSubSum\", function() {\n it(\"максимальная подсумма [1, 2, 3] равна 6\", function() {\n assert.equal( getMaxSubSum([1, 2, 3]), 6);\n });\n\n it(\"максимальная подсумма [-1, 2, 3, -9] равна 5\", function() {\n assert.equal( getMaxSubSum([-1, 2, 3, -9]), 5);\n });\n\n it(\"максимальная подсумма [-1, 2, 3, -9, 11] равна 11\", function() {\n assert.equal( getMaxSubSum([-1, 2, 3, -9, 11]), 11);\n });\n\n it(\"максимальная подсумма [-2, -1, 1, 2] равна 3\", function() {\n assert.equal( getMaxSubSum([-2, -1, 1, 2]), 3);\n });\n\n it(\"максимальная подсумма [100, -9, 2, -3, 5] равна 100\", function() {\n assert.equal( getMaxSubSum([100, -9, 2, -3, 5]), 100);\n });\n\n it(\"максимальная подсумма [] равна 0\", function() {\n assert.equal( getMaxSubSum([]), 0);\n });\n\n it(\"максимальная подсумма [-1] равна 0\", function() {\n assert.equal( getMaxSubSum([-1]), 0);\n });\n\n it(\"максимальная подсумма [-1, -2] равна 0\", function() {\n assert.equal( getMaxSubSum([-1, -2]), 0);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29bfff1f6dbff33a790fa" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c00f1f6dbff33a790fb" }, "plunkId" : "fD9iQ7r9E8wkgqnPnGE5", "webPath" : "/task/maximal-subarray/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c00f1f6dbff33a790fc" } }, { "content" : "describe(\"getMaxSubSum\", function() {\n it(\"максимальная подсумма [1, 2, 3] равна 6\", function() {\n assert.equal( getMaxSubSum([1, 2, 3]), 6);\n });\n\n it(\"максимальная подсумма [-1, 2, 3, -9] равна 5\", function() {\n assert.equal( getMaxSubSum([-1, 2, 3, -9]), 5);\n });\n\n it(\"максимальная подсумма [-1, 2, 3, -9, 11] равна 11\", function() {\n assert.equal( getMaxSubSum([-1, 2, 3, -9, 11]), 11);\n });\n\n it(\"максимальная подсумма [-2, -1, 1, 2] равна 3\", function() {\n assert.equal( getMaxSubSum([-2, -1, 1, 2]), 3);\n });\n\n it(\"максимальная подсумма [100, -9, 2, -3, 5] равна 100\", function() {\n assert.equal( getMaxSubSum([100, -9, 2, -3, 5]), 100);\n });\n\n it(\"максимальная подсумма [] равна 0\", function() {\n assert.equal( getMaxSubSum([]), 0);\n });\n\n it(\"максимальная подсумма [-1] равна 0\", function() {\n assert.equal( getMaxSubSum([-1]), 0);\n });\n\n it(\"максимальная подсумма [-1, -2] равна 0\", function() {\n assert.equal( getMaxSubSum([-1, -2]), 0);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c00f1f6dbff33a790fd" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c01f1f6dbff33a79104" }, "plunkId" : "v29865qdBfc8KtQlncDT", "webPath" : "/task/array-find/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c01f1f6dbff33a79105" } }, { "content" : "describe(\"find\", function() {\n\n describe(\"возвращает позицию, на которой найден элемент\", function() {\n it(\"в массиве [1,2,3] находит 1 на позиции 0\", function() {\n assert.equal( find([1, 2, 3], 1), 0);\n });\n it(\"в массиве [1,2,3] находит 2 на позиции 1\", function() {\n assert.equal( find([1, 2, 3], 2), 1);\n }); \n it(\"в массиве [1,2,3] находит 3 на позиции 2\", function() {\n assert.equal( find([1, 2, 3], 3), 2);\n });\n });\n\n it(\"если элемент не найден, возвращает -1\", function() {\n assert.equal( find([1,2,3], 0), -1);\n });\n\n it(\"отличает false или null от 0\", function() {\n assert.equal( find([false, true, null], 0), -1);\n });\n\n it(\"отличает 1 от true\", function() {\n assert.equal( find([1, 2, 3], true), -1);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c01f1f6dbff33a79106" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c02f1f6dbff33a79107" }, "plunkId" : "leMOvSmQpd0IOfknllaN", "webPath" : "/task/array-find/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c02f1f6dbff33a79108" } }, { "content" : "describe(\"find\", function() {\n\n describe(\"возвращает позицию, на которой найден элемент\", function() {\n it(\"в массиве [1,2,3] находит 1 на позиции 0\", function() {\n assert.equal( find([1, 2, 3], 1), 0);\n });\n it(\"в массиве [1,2,3] находит 2 на позиции 1\", function() {\n assert.equal( find([1, 2, 3], 2), 1);\n }); \n it(\"в массиве [1,2,3] находит 3 на позиции 2\", function() {\n assert.equal( find([1, 2, 3], 3), 2);\n });\n });\n\n it(\"если элемент не найден, возвращает -1\", function() {\n assert.equal( find([1,2,3], 0), -1);\n });\n\n it(\"отличает false или null от 0\", function() {\n assert.equal( find([false, true, null], 0), -1);\n });\n\n it(\"отличает 1 от true\", function() {\n assert.equal( find([1, 2, 3], true), -1);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c02f1f6dbff33a79109" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c02f1f6dbff33a7910b" }, "plunkId" : "vQjOTBw73UEjeMnz8wLU", "webPath" : "/task/filter-range/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c02f1f6dbff33a7910c" } }, { "content" : "describe(\"filterRange\", function() {\n it(\"не меняет исходный массив\", function() {\n var arr = [5, 4, 3, 8, 0];\n \n filterRange(arr, 0, 10);\n assert.deepEqual(arr, [5,4,3,8,0]);\n });\n\n it(\"оставляет только значения указанного интервала\", function() {\n var arr = [5, 4, 3, 8, 0];\n \n var result = filterRange(arr, 3, 5);\n assert.deepEqual(result, [5,4,3]);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c02f1f6dbff33a7910d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c02f1f6dbff33a7910e" }, "plunkId" : "R03DLuj3IfwBMzTdlvAh", "webPath" : "/task/filter-range/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c02f1f6dbff33a7910f" } }, { "content" : "describe(\"filterRange\", function() {\n it(\"не меняет исходный массив\", function() {\n var arr = [5, 4, 3, 8, 0];\n \n filterRange(arr, 0, 10);\n assert.deepEqual(arr, [5,4,3,8,0]);\n });\n\n it(\"оставляет только значения указанного интервала\", function() {\n var arr = [5, 4, 3, 8, 0];\n \n var result = filterRange(arr, 3, 5);\n assert.deepEqual(result, [5,4,3]);\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c02f1f6dbff33a79110" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c03f1f6dbff33a79114" }, "plunkId" : "3e59YzIjNYJsjj4glDTC", "webPath" : "/task/add-class/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c03f1f6dbff33a79115" } }, { "content" : "describe(\"addClass\", function() {\n\n it(\"добавляет класс, которого нет\", function() {\n var obj = { className: 'open menu' };\n addClass(obj, 'new');\n assert.deepEqual(obj, {\n className: 'open menu new'\n });\n });\n\n it(\"не добавляет класс, который уже есть\", function() {\n var obj = { className: 'open menu' };\n addClass(obj, 'open');\n assert.deepEqual(obj, {\n className: 'open menu'\n });\n });\n\n it(\"не добавляет лишних пробелов, который уже есть\", function() {\n var obj = { className: '' };\n addClass(obj, 'open');\n assert.deepEqual(obj, {\n className: 'open'\n });\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c03f1f6dbff33a79116" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c03f1f6dbff33a79117" }, "plunkId" : "wIHUOaonXMqv3bxxXut8", "webPath" : "/task/add-class/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c03f1f6dbff33a79118" } }, { "content" : "describe(\"addClass\", function() {\n\n it(\"добавляет класс, которого нет\", function() {\n var obj = { className: 'open menu' };\n addClass(obj, 'new');\n assert.deepEqual(obj, {\n className: 'open menu new'\n });\n });\n\n it(\"не добавляет класс, который уже есть\", function() {\n var obj = { className: 'open menu' };\n addClass(obj, 'open');\n assert.deepEqual(obj, {\n className: 'open menu'\n });\n });\n\n it(\"не добавляет лишних пробелов, который уже есть\", function() {\n var obj = { className: '' };\n addClass(obj, 'open');\n assert.deepEqual(obj, {\n className: 'open'\n });\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c03f1f6dbff33a79119" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c03f1f6dbff33a7911b" }, "plunkId" : "7wD7Q9z6WiactEWN9OU6", "webPath" : "/task/filter-anagrams/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c03f1f6dbff33a7911c" } }, { "content" : "function intersection(arr1, arr2) {\n return arr1.filter(function(item) {\n return arr2.indexOf(item) != -1;\n });\n}\n\ndescribe(\"aclean\", function() {\n \n it(\"содержит ровно по 1 слову из каждого набора анаграмм\", function() {\n var arr = [\"воз\", \"киборг\", \"корсет\", \"зов\", \"гробик\", \"костер\", \"сектор\"];\n \n var result = aclean(arr);\n assert.equal(result.length, 3);\n\n assert.equal(intersection(result, [\"гробик\", \"киборг\"]).length, 1);\n assert.equal(intersection(result, [\"воз\", \"зов\"]).length, 1);\n assert.equal(intersection(result, [\"корсет\", \"сектор\", \"костер\"]).length, 1);\n \n });\n \n it(\"не различает регистр символов\", function() {\n var arr = [\"воз\", \"ЗОВ\"];\n assert.equal( aclean(arr).length, 1 );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c03f1f6dbff33a7911d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c04f1f6dbff33a7911e" }, "plunkId" : "kKzFt41kR2RedD7SdeaS", "webPath" : "/task/filter-anagrams/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c04f1f6dbff33a7911f" } }, { "content" : "function intersection(arr1, arr2) {\n return arr1.filter(function(item) {\n return arr2.indexOf(item) != -1;\n });\n}\n\ndescribe(\"aclean\", function() {\n \n it(\"содержит ровно по 1 слову из каждого набора анаграмм\", function() {\n var arr = [\"воз\", \"киборг\", \"корсет\", \"зов\", \"гробик\", \"костер\", \"сектор\"];\n \n var result = aclean(arr);\n assert.equal(result.length, 3);\n\n assert.equal(intersection(result, [\"гробик\", \"киборг\"]).length, 1);\n assert.equal(intersection(result, [\"воз\", \"зов\"]).length, 1);\n assert.equal(intersection(result, [\"корсет\", \"сектор\", \"костер\"]).length, 1);\n \n });\n \n it(\"не различает регистр символов\", function() {\n var arr = [\"воз\", \"ЗОВ\"];\n assert.equal( aclean(arr).length, 1 );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c04f1f6dbff33a79120" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c04f1f6dbff33a79122" }, "plunkId" : "P4qmSeQYBcOshL9darWi", "webPath" : "/task/array-unique/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c04f1f6dbff33a79123" } }, { "content" : "describe(\"unique\", function() {\n it(\"убирает неуникальные элементы из массива\", function() {\n var strings = [\"кришна\", \"кришна\", \"харе\", \"харе\", \n \"харе\", \"харе\", \"кришна\", \"кришна\", \"8-()\"];\n\n assert.deepEqual( unique(strings), [\"кришна\", \"харе\", \"8-()\"] ); \n });\n\n it(\"не изменяет исходный массив\", function() {\n var strings = [\"кришна\", \"кришна\", \"харе\", \"харе\"];\n unique(strings);\n assert.deepEqual( strings, [\"кришна\", \"кришна\", \"харе\", \"харе\"] ); \n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c04f1f6dbff33a79124" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c05f1f6dbff33a79125" }, "plunkId" : "DhbroUAFZq7a6IpB9ccr", "webPath" : "/task/array-unique/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c05f1f6dbff33a79126" } }, { "content" : "describe(\"unique\", function() {\n it(\"убирает неуникальные элементы из массива\", function() {\n var strings = [\"кришна\", \"кришна\", \"харе\", \"харе\", \n \"харе\", \"харе\", \"кришна\", \"кришна\", \"8-()\"];\n\n assert.deepEqual( unique(strings), [\"кришна\", \"харе\", \"8-()\"] ); \n });\n\n it(\"не изменяет исходный массив\", function() {\n var strings = [\"кришна\", \"кришна\", \"харе\", \"харе\"];\n unique(strings);\n assert.deepEqual( strings, [\"кришна\", \"кришна\", \"харе\", \"харе\"] ); \n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c05f1f6dbff33a79127" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c05f1f6dbff33a79129" }, "plunkId" : "ETfO6JaeoyaLMBMdYCJL", "webPath" : "/task/camelcase/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c05f1f6dbff33a7912a" } }, { "content" : "describe(\"camelize\", function() {\n\n it(\"оставляет пустую строку \\\"как есть\\\"\", function() {\n assert.equal( camelize(\"\"), \"\");\n });\n\n describe(\"делает заглавным первый символ после дефиса\", function() {\n\n it(\"превращает background-color в backgroundColor\", function() {\n assert.equal( camelize(\"background-color\"), \"backgroundColor\");\n });\n\n it(\"превращает list-style-image в listStyleImage\", function() {\n assert.equal( camelize(\"list-style-image\"), \"listStyleImage\");\n });\n\n it(\"превращает -webkit-transition в WebkitTransition\", function() {\n assert.equal( camelize(\"-webkit-transition\"), \"WebkitTransition\");\n });\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c05f1f6dbff33a7912b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c06f1f6dbff33a7912c" }, "plunkId" : "XBDbNQUcfsXJDImdkD1L", "webPath" : "/task/camelcase/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c06f1f6dbff33a7912d" } }, { "content" : "describe(\"camelize\", function() {\n\n it(\"оставляет пустую строку \\\"как есть\\\"\", function() {\n assert.equal( camelize(\"\"), \"\");\n });\n\n describe(\"делает заглавным первый символ после дефиса\", function() {\n\n it(\"превращает background-color в backgroundColor\", function() {\n assert.equal( camelize(\"background-color\"), \"backgroundColor\");\n });\n\n it(\"превращает list-style-image в listStyleImage\", function() {\n assert.equal( camelize(\"list-style-image\"), \"listStyleImage\");\n });\n\n it(\"превращает -webkit-transition в WebkitTransition\", function() {\n assert.equal( camelize(\"-webkit-transition\"), \"WebkitTransition\");\n });\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c06f1f6dbff33a7912e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c06f1f6dbff33a79130" }, "plunkId" : "7BeE2Nkn7GsLE6VBKiUF", "webPath" : "/task/remove-class/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c06f1f6dbff33a79131" } }, { "content" : "describe(\"removeClass\", function() {\n\n it(\"ничего не делает, если класса нет\", function() {\n var obj = { className: 'open menu' };\n removeClass(obj, 'new');\n assert.deepEqual(obj, {\n className: 'open menu'\n });\n });\n\n it(\"не меняет пустое свойство\", function() {\n var obj = { className: '' };\n removeClass(obj, 'new');\n assert.deepEqual(obj, {\n className: \"\"\n });\n });\n\n it(\"удаляет класс, не оставляя лишних пробелов\", function() {\n var obj = { className: 'open menu' };\n removeClass(obj, 'open');\n assert.deepEqual(obj, {\n className: \"menu\"\n });\n });\n\n it(\"если класс один и он удалён, то результат - пустая строка\", function() {\n var obj = { className: \"menu\" };\n removeClass(obj, 'menu');\n assert.deepEqual(obj, {\n className: \"\"\n });\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c06f1f6dbff33a79132" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c07f1f6dbff33a79133" }, "plunkId" : "IYUlwQQ7HxoVKPB0PNVI", "webPath" : "/task/remove-class/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c07f1f6dbff33a79134" } }, { "content" : "describe(\"removeClass\", function() {\n\n it(\"ничего не делает, если класса нет\", function() {\n var obj = { className: 'open menu' };\n removeClass(obj, 'new');\n assert.deepEqual(obj, {\n className: 'open menu'\n });\n });\n\n it(\"не меняет пустое свойство\", function() {\n var obj = { className: '' };\n removeClass(obj, 'new');\n assert.deepEqual(obj, {\n className: \"\"\n });\n });\n\n it(\"удаляет класс, не оставляя лишних пробелов\", function() {\n var obj = { className: 'open menu' };\n removeClass(obj, 'open');\n assert.deepEqual(obj, {\n className: \"menu\"\n });\n });\n\n it(\"если класс один и он удалён, то результат - пустая строка\", function() {\n var obj = { className: \"menu\" };\n removeClass(obj, 'menu');\n assert.deepEqual(obj, {\n className: \"\"\n });\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c07f1f6dbff33a79135" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c07f1f6dbff33a79137" }, "plunkId" : "KXt4CYcUbrlPfy9X4cSM", "webPath" : "/task/filter-in-place/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c07f1f6dbff33a79138" } }, { "content" : "describe(\"filterRangeInPlace\", function() {\n\n it(\"меняет массив, оставляя только значения из диапазона\", function() {\n var arr = [5, 3, 8, 1];\n filterRangeInPlace(arr, 1, 4);\n assert.deepEqual(arr, [3, 1]);\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c07f1f6dbff33a79139" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c07f1f6dbff33a7913a" }, "plunkId" : "SGRhufpDBe5ZqRXREaRX", "webPath" : "/task/filter-in-place/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c07f1f6dbff33a7913b" } }, { "content" : "describe(\"filterRangeInPlace\", function() {\n\n it(\"меняет массив, оставляя только значения из диапазона\", function() {\n var arr = [5, 3, 8, 1];\n filterRangeInPlace(arr, 1, 4);\n assert.deepEqual(arr, [3, 1]);\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c07f1f6dbff33a7913c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c08f1f6dbff33a79145" }, "plunkId" : "HpTo7DYhs3lspyMVmBhs", "webPath" : "/task/partial-sums-array/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c08f1f6dbff33a79146" } }, { "content" : "describe(\"getSums\", function() {\n\n it(\"частичные суммы [1,2,3,4,5] равны [1,3,6,10,15]\", function() {\n assert.deepEqual( getSums([1,2,3,4,5]), [1,3,6,10,15]);\n });\n\n it(\"частичные суммы [-2,-1,0,1] равны [-2,-3,-3,-2]\", function() {\n assert.deepEqual( getSums([-2,-1,0,1]), [-2,-3,-3,-2]);\n });\n\n it(\"частичные суммы [] равны []\", function() {\n assert.deepEqual( getSums([]), [] );\n });\n\n it(\"частичные суммы [1] равны [1]\", function() {\n assert.deepEqual( getSums([1]), [1] );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c08f1f6dbff33a79147" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c08f1f6dbff33a79148" }, "plunkId" : "Han01Xo5OmPkw0469gnw", "webPath" : "/task/partial-sums-array/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c08f1f6dbff33a79149" } }, { "content" : "describe(\"getSums\", function() {\n\n it(\"частичные суммы [1,2,3,4,5] равны [1,3,6,10,15]\", function() {\n assert.deepEqual( getSums([1,2,3,4,5]), [1,3,6,10,15]);\n });\n\n it(\"частичные суммы [-2,-1,0,1] равны [-2,-3,-3,-2]\", function() {\n assert.deepEqual( getSums([-2,-1,0,1]), [-2,-3,-3,-2]);\n });\n\n it(\"частичные суммы [] равны []\", function() {\n assert.deepEqual( getSums([]), [] );\n });\n\n it(\"частичные суммы [1] равны [1]\", function() {\n assert.deepEqual( getSums([1]), [1] );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c08f1f6dbff33a7914a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c09f1f6dbff33a7915d" }, "plunkId" : "iJ5PTwmmVm1D856uAgbP", "webPath" : "/task/stringbuffer/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c09f1f6dbff33a7915e" } }, { "content" : "var buffer;\nbeforeEach(function() {\n buffer = makeBuffer();\n});\n\nit(\"возвращает пустую строку по умолчанию\", function() {\n assert.strictEqual( buffer(), \"\");\n});\n\nit(\"добавляет аргументы в буффер\", function() {\n buffer('Замыкания'); \n buffer(' Использовать'); \n buffer(' Нужно!'); \n assert.equal( buffer(), 'Замыкания Использовать Нужно!');\n});\n\nit(\"приводит всё к строке\", function() {\n buffer(null);\n buffer(false);\n assert.equal( buffer(), \"nullfalse\");\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c09f1f6dbff33a7915f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c09f1f6dbff33a79160" }, "plunkId" : "Vu94b72JuMmlQ0n9h0Cy", "webPath" : "/task/stringbuffer/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c09f1f6dbff33a79161" } }, { "content" : "var buffer;\nbeforeEach(function() {\n buffer = makeBuffer();\n});\n\nit(\"возвращает пустую строку по умолчанию\", function() {\n assert.strictEqual( buffer(), \"\");\n});\n\nit(\"добавляет аргументы в буффер\", function() {\n buffer('Замыкания'); \n buffer(' Использовать'); \n buffer(' Нужно!'); \n assert.equal( buffer(), 'Замыкания Использовать Нужно!');\n});\n\nit(\"приводит всё к строке\", function() {\n buffer(null);\n buffer(false);\n assert.equal( buffer(), \"nullfalse\");\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c09f1f6dbff33a79162" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c09f1f6dbff33a79164" }, "plunkId" : "I9yHeMWcIdYC4mPYQbuO", "webPath" : "/task/stringbuffer-with-clear/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c09f1f6dbff33a79165" } }, { "content" : "var buffer;\n\nbeforeEach(function() {\n buffer = makeBuffer();\n});\n\nit(\"возвращает пустую строку по умолчанию\", function() {\n assert.strictEqual( buffer(), \"\");\n});\n\nit(\"добавляет аргументы в буффер\", function() {\n buffer('Замыкания'); \n buffer(' Использовать'); \n buffer(' Нужно!'); \n assert.equal( buffer(), 'Замыкания Использовать Нужно!');\n});\n\nit(\"приводит всё к строке\", function() {\n buffer(null);\n buffer(false);\n assert.equal( buffer(), \"nullfalse\");\n});\n\nit(\"очищает буфер вызовом clear\", function() {\n buffer(\"test\");\n buffer.clear();\n buffer(\"первый\");\n buffer(\"второй\");\n assert.equal( buffer(), \"первыйвторой\");\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c09f1f6dbff33a79166" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0af1f6dbff33a79167" }, "plunkId" : "rbLL3i14r1kLdk4rbMmX", "webPath" : "/task/stringbuffer-with-clear/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0af1f6dbff33a79168" } }, { "content" : "var buffer;\n\nbeforeEach(function() {\n buffer = makeBuffer();\n});\n\nit(\"возвращает пустую строку по умолчанию\", function() {\n assert.strictEqual( buffer(), \"\");\n});\n\nit(\"добавляет аргументы в буффер\", function() {\n buffer('Замыкания'); \n buffer(' Использовать'); \n buffer(' Нужно!'); \n assert.equal( buffer(), 'Замыкания Использовать Нужно!');\n});\n\nit(\"приводит всё к строке\", function() {\n buffer(null);\n buffer(false);\n assert.equal( buffer(), \"nullfalse\");\n});\n\nit(\"очищает буфер вызовом clear\", function() {\n buffer(\"test\");\n buffer.clear();\n buffer(\"первый\");\n buffer(\"второй\");\n assert.equal( buffer(), \"первыйвторой\");\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0af1f6dbff33a79169" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0bf1f6dbff33a7916c" }, "plunkId" : "18YhmRZn7Lb7RUSMy0SN", "webPath" : "/task/filter-through-function/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0bf1f6dbff33a7916d" } }, { "content" : "var arr;\n\nbefore(function() {\n arr = [1, 2, 3, 4, 5, 6, 7];\n});\n\ndescribe(\"inArray\", function() {\n var checkInArr;\n\n before(function() {\n checkInArr = inArray(arr);\n });\n \n it(\"возвращает фильтр для значений в массиве\", function() {\n assert.isTrue( checkInArr(5) );\n assert.isFalse( checkInArr(0) );\n });\n});\n\n\ndescribe(\"inBetween\", function() {\n var checkBetween36;\n\n before(function() {\n checkBetween36 = inBetween(3, 6);\n });\n\n it(\"возвращает фильтрa для значений в промежутке\", function() {\n assert.isTrue( checkBetween36(5) );\n assert.isFalse( checkBetween36(0) );\n });\n});\n\n\ndescribe(\"filter\", function() {\n\n it(\"фильтрует через func\", function() {\n assert.deepEqual( filter(arr, function(a) { return a % 2 == 0; }), [2,4,6] ); \n });\n\n it(\"не модифицирует исходный массив\", function() {\n filter(arr, function(a) { return a % 2 == 0; });\n assert.deepEqual( arr, [1, 2, 3, 4, 5, 6, 7] ); \n });\n\n it(\"поддерживает фильтр inBetween\", function() {\n assert.deepEqual( filter(arr,inBetween(3,6)), [3,4,5,6]);\n });\n\n it(\"поддерживает фильтр inArray\", function() {\n assert.deepEqual( filter(arr, inArray([1,2,3])), [1,2,3]);\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0bf1f6dbff33a7916e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0bf1f6dbff33a7916f" }, "plunkId" : "pIwTumCLOtoz20c4s8a0", "webPath" : "/task/filter-through-function/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0bf1f6dbff33a79170" } }, { "content" : "var arr;\n\nbefore(function() {\n arr = [1, 2, 3, 4, 5, 6, 7];\n});\n\ndescribe(\"inArray\", function() {\n var checkInArr;\n\n before(function() {\n checkInArr = inArray(arr);\n });\n \n it(\"возвращает фильтр для значений в массиве\", function() {\n assert.isTrue( checkInArr(5) );\n assert.isFalse( checkInArr(0) );\n });\n});\n\n\ndescribe(\"inBetween\", function() {\n var checkBetween36;\n\n before(function() {\n checkBetween36 = inBetween(3, 6);\n });\n\n it(\"возвращает фильтрa для значений в промежутке\", function() {\n assert.isTrue( checkBetween36(5) );\n assert.isFalse( checkBetween36(0) );\n });\n});\n\n\ndescribe(\"filter\", function() {\n\n it(\"фильтрует через func\", function() {\n assert.deepEqual( filter(arr, function(a) { return a % 2 == 0; }), [2,4,6] ); \n });\n\n it(\"не модифицирует исходный массив\", function() {\n filter(arr, function(a) { return a % 2 == 0; });\n assert.deepEqual( arr, [1, 2, 3, 4, 5, 6, 7] ); \n });\n\n it(\"поддерживает фильтр inBetween\", function() {\n assert.deepEqual( filter(arr,inBetween(3,6)), [3,4,5,6]);\n });\n\n it(\"поддерживает фильтр inArray\", function() {\n assert.deepEqual( filter(arr, inArray([1,2,3])), [1,2,3]);\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0bf1f6dbff33a79171" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0bf1f6dbff33a79173" }, "plunkId" : "nEsVfHiT8gzXW2K9QpIU", "webPath" : "/task/make-army/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0bf1f6dbff33a79174" } }, { "content" : "var army;\nbefore(function() {\n army = makeArmy();\n window.alert = sinon.stub(window, \"alert\");\n});\n\nit(\"army[0] выводит 0\", function() {\n army[0]();\n assert(alert.calledWith(0));\n});\n\n\nit(\"army[5] функция выводит 5\", function() {\n army[5]();\n assert(alert.calledWith(5));\n});\n\nafter(function() {\n window.alert.restore();\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0bf1f6dbff33a79175" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0cf1f6dbff33a79176" }, "plunkId" : "gmbzG91MDjEz1PR4rhxL", "webPath" : "/task/make-army/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0cf1f6dbff33a79177" } }, { "content" : "var army;\nbefore(function() {\n army = makeArmy();\n window.alert = sinon.stub(window, \"alert\");\n});\n\nit(\"army[0] выводит 0\", function() {\n army[0]();\n assert(alert.calledWith(0));\n});\n\n\nit(\"army[5] функция выводит 5\", function() {\n army[5]();\n assert(alert.calledWith(5));\n});\n\nafter(function() {\n window.alert.restore();\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0cf1f6dbff33a79178" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0cf1f6dbff33a7917a" }, "plunkId" : "oixv56aLpSBNx4mFMddd", "webPath" : "/article/closures-module/hello-conflict", "files" : [ { "filename" : "hello.js", "content" : "// глобальная переменная нашего скрипта\nvar message = \"Привет\";\n\n// функция для вывода этой переменной\nfunction showMessage() {\n alert(message);\n}\n\n// выводим сообщение\nshowMessage();", "_id" : { "$oid" : "54c29c0cf1f6dbff33a7917b" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c0cf1f6dbff33a7917c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0cf1f6dbff33a7917d" }, "plunkId" : "0zOmAJ3d8LRtJknudgyK", "webPath" : "/article/closures-module/hello-module", "files" : [ { "filename" : "hello.js", "content" : "(function() {\n\n // глобальная переменная нашего скрипта\n var message = \"Привет\";\n\n // функция для вывода этой переменной\n function showMessage() {\n alert(message);\n }\n\n // выводим сообщение\n showMessage();\n\n})();", "_id" : { "$oid" : "54c29c0cf1f6dbff33a7917e" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c0cf1f6dbff33a7917f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0df1f6dbff33a7918d" }, "plunkId" : "rSGoC7CXkXqM7iI3XqWy", "webPath" : "/task/calculator/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0df1f6dbff33a7918e" } }, { "content" : "sinon.stub(window, \"prompt\");\n\nprompt.onCall(0).returns(\"2\");\nprompt.onCall(1).returns(\"3\");\n\ndescribe(\"calculator\", function() {\n before(function() {\n calculator.read();\n });\n\n it(\"при вводе 2 и 3 сумма равна 5\", function() {\n assert.equal( calculator.sum(), 5 );\n });\n\n it(\"при вводе 2 и 3 произведение равно 6\", function() {\n assert.equal( calculator.mul(), 6 );\n });\n});\n\nafter(function() {\n prompt.restore();\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0df1f6dbff33a7918f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0df1f6dbff33a79190" }, "plunkId" : "sGQteuKq1bhZtmzAlkVt", "webPath" : "/task/calculator/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0df1f6dbff33a79191" } }, { "content" : "sinon.stub(window, \"prompt\");\n\nprompt.onCall(0).returns(\"2\");\nprompt.onCall(1).returns(\"3\");\n\ndescribe(\"calculator\", function() {\n before(function() {\n calculator.read();\n });\n\n it(\"при вводе 2 и 3 сумма равна 5\", function() {\n assert.equal( calculator.sum(), 5 );\n });\n\n it(\"при вводе 2 и 3 произведение равно 6\", function() {\n assert.equal( calculator.mul(), 6 );\n });\n});\n\nafter(function() {\n prompt.restore();\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0df1f6dbff33a79192" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0df1f6dbff33a7919d" }, "plunkId" : "dxYF2AXUrK8VZkZQ3vyI", "webPath" : "/task/calculator-constructor/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0df1f6dbff33a7919e" } }, { "content" : "sinon.stub(window, \"prompt\")\n\nprompt.onCall(0).returns(\"2\");\nprompt.onCall(1).returns(\"3\");\n\ndescribe(\"calculator\", function() {\n var calculator;\n before(function() {\n calculator = new Calculator();\n calculator.read();\n });\n\n it(\"при вводе 2 и 3 сумма равна 5\", function() {\n assert.equal( calculator.sum(), 5 );\n });\n\n it(\"при вводе 2 и 3 произведение равно 6\", function() {\n assert.equal( calculator.mul(), 6 );\n });\n\n});\n\nafter(function() {\n prompt.restore();\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0df1f6dbff33a7919f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0ef1f6dbff33a791a0" }, "plunkId" : "uMdDRxPyKUFoRLsAa3kB", "webPath" : "/task/calculator-constructor/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0ef1f6dbff33a791a1" } }, { "content" : "sinon.stub(window, \"prompt\")\n\nprompt.onCall(0).returns(\"2\");\nprompt.onCall(1).returns(\"3\");\n\ndescribe(\"calculator\", function() {\n var calculator;\n before(function() {\n calculator = new Calculator();\n calculator.read();\n });\n\n it(\"при вводе 2 и 3 сумма равна 5\", function() {\n assert.equal( calculator.sum(), 5 );\n });\n\n it(\"при вводе 2 и 3 произведение равно 6\", function() {\n assert.equal( calculator.mul(), 6 );\n });\n\n});\n\nafter(function() {\n prompt.restore();\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0ef1f6dbff33a791a2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0ef1f6dbff33a791a4" }, "plunkId" : "Jf3JV3d5dv0yLssokdkD", "webPath" : "/task/accumulator/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0ef1f6dbff33a791a5" } }, { "content" : "describe(\"Accumulator(1)\", function() {\n var accumulator;\n before(function() {\n accumulator = new Accumulator(1);\n });\n\n beforeEach(function() {\n sinon.stub(window, \"prompt\")\n });\n\n afterEach(function() {\n prompt.restore();\n });\n\n it(\"начальное значение 1\", function() {\n assert.equal( accumulator.value, 1 );\n });\n\n it(\"после ввода 0 значение 1\", function() {\n prompt.returns(\"0\");\n accumulator.read();\n assert.equal( accumulator.value, 1 );\n });\n\n it(\"после ввода 1 значение 2\", function() {\n prompt.returns(\"1\");\n accumulator.read();\n assert.equal( accumulator.value, 2 );\n });\n\n it(\"после ввода 2 значение 4\", function() {\n prompt.returns(\"2\");\n accumulator.read();\n assert.equal( accumulator.value, 4 );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0ef1f6dbff33a791a6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c0ff1f6dbff33a791a7" }, "plunkId" : "zVVKSiC6M18tXo5e2RDo", "webPath" : "/task/accumulator/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c0ff1f6dbff33a791a8" } }, { "content" : "describe(\"Accumulator(1)\", function() {\n var accumulator;\n before(function() {\n accumulator = new Accumulator(1);\n });\n\n beforeEach(function() {\n sinon.stub(window, \"prompt\")\n });\n\n afterEach(function() {\n prompt.restore();\n });\n\n it(\"начальное значение 1\", function() {\n assert.equal( accumulator.value, 1 );\n });\n\n it(\"после ввода 0 значение 1\", function() {\n prompt.returns(\"0\");\n accumulator.read();\n assert.equal( accumulator.value, 1 );\n });\n\n it(\"после ввода 1 значение 2\", function() {\n prompt.returns(\"1\");\n accumulator.read();\n assert.equal( accumulator.value, 2 );\n });\n\n it(\"после ввода 2 значение 4\", function() {\n prompt.returns(\"2\");\n accumulator.read();\n assert.equal( accumulator.value, 4 );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c0ff1f6dbff33a791a9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c10f1f6dbff33a791ab" }, "plunkId" : "7Kr4SqdGswrHFawxnfXZ", "webPath" : "/task/calculator-extendable/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c10f1f6dbff33a791ac" } }, { "content" : "var calculator;\nbefore(function() {\n calculator = new Calculator;\n});\n\nit(\"calculate(12 + 34) = 46\", function() {\n assert.equal( calculator.calculate(\"12 + 34\"), 46 );\n});\n\nit(\"calculate(34 - 12) = 22\", function() {\n assert.equal( calculator.calculate(\"34 - 12\"), 22 );\n});\n\nit(\"добавили умножение: calculate(2 * 3) = 6\", function() {\n calculator.addMethod(\"*\", function(a, b) {\n return a * b;\n });\n assert.equal( calculator.calculate(\"2 * 3\"), 6 );\n});\n\nit(\"добавили возведение в степень: calculate(2 ** 3) = 8\", function() {\n calculator.addMethod(\"**\", function(a, b) {\n return Math.pow(a, b);\n });\n assert.equal( calculator.calculate(\"2 ** 3\"), 8 );\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c10f1f6dbff33a791ad" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c11f1f6dbff33a791ae" }, "plunkId" : "qLIUHM0wWRPwcAHVdptD", "webPath" : "/task/calculator-extendable/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c11f1f6dbff33a791af" } }, { "content" : "var calculator;\nbefore(function() {\n calculator = new Calculator;\n});\n\nit(\"calculate(12 + 34) = 46\", function() {\n assert.equal( calculator.calculate(\"12 + 34\"), 46 );\n});\n\nit(\"calculate(34 - 12) = 22\", function() {\n assert.equal( calculator.calculate(\"34 - 12\"), 22 );\n});\n\nit(\"добавили умножение: calculate(2 * 3) = 6\", function() {\n calculator.addMethod(\"*\", function(a, b) {\n return a * b;\n });\n assert.equal( calculator.calculate(\"2 * 3\"), 6 );\n});\n\nit(\"добавили возведение в степень: calculate(2 ** 3) = 8\", function() {\n calculator.addMethod(\"**\", function(a, b) {\n return Math.pow(a, b);\n });\n assert.equal( calculator.calculate(\"2 ** 3\"), 8 );\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c11f1f6dbff33a791b0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c11f1f6dbff33a791b5" }, "plunkId" : "0Ue1faDKzrmiWspHAvEg", "webPath" : "/task/objects-counter/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c11f1f6dbff33a791b6" } }, { "content" : "describe(\"Article.showStats\", function() {\n before(function() {\n sinon.stub(window, \"alert\");\n this.clock = sinon.useFakeTimers();\n });\n \n after(function() {\n window.alert.restore();\n this.clock.restore();\n });\n\n it(\"Выводит число статей и дату создания последней\", function() {\n new Article();\n this.clock.tick(100);\n new Article();\n Article.showStats(); \n \n assert( alert.calledWith('Всего: 2, Последняя: ' + new Date() ) );\n });\n\n it(\"и ещё одна статья...\", function() {\n this.clock.tick(100);\n new Article();\n Article.showStats();\n\n assert( alert.calledWith('Всего: 3, Последняя: ' + new Date() ) );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c11f1f6dbff33a791b7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c13f1f6dbff33a791b8" }, "plunkId" : "PtcxV610fq1icV893wrp", "webPath" : "/task/objects-counter/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c13f1f6dbff33a791b9" } }, { "content" : "describe(\"Article.showStats\", function() {\n before(function() {\n sinon.stub(window, \"alert\");\n this.clock = sinon.useFakeTimers();\n });\n \n after(function() {\n window.alert.restore();\n this.clock.restore();\n });\n\n it(\"Выводит число статей и дату создания последней\", function() {\n new Article();\n this.clock.tick(100);\n new Article();\n Article.showStats(); \n \n assert( alert.calledWith('Всего: 2, Последняя: ' + new Date() ) );\n });\n\n it(\"и ещё одна статья...\", function() {\n this.clock.tick(100);\n new Article();\n Article.showStats();\n\n assert( alert.calledWith('Всего: 3, Последняя: ' + new Date() ) );\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c13f1f6dbff33a791ba" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c13f1f6dbff33a791be" }, "plunkId" : "diQYgX8gSwMgrxY15sfi", "webPath" : "/task/apply-function-skip-first-argument/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c13f1f6dbff33a791bf" } }, { "content" : "describe(\"applyAll\", function() {\n\n it(\"применяет функцию ко всем аргументам, начиная со 2го\", function() {\n var min = applyAll(Math.min, 1, 2, 3);\n assert.equal( min, 1 );\n });\n\n it(\"при отсутствии аргументов просто вызывает функцию\", function() {\n var spy = sinon.spy();\n applyAll(spy);\n assert( spy.calledOnce );\n assert.equal( spy.firstCall.args.length, 0 );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c13f1f6dbff33a791c0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c14f1f6dbff33a791c1" }, "plunkId" : "PJFRnrc3oGIK7IHRoio6", "webPath" : "/task/apply-function-skip-first-argument/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c14f1f6dbff33a791c2" } }, { "content" : "describe(\"applyAll\", function() {\n\n it(\"применяет функцию ко всем аргументам, начиная со 2го\", function() {\n var min = applyAll(Math.min, 1, 2, 3);\n assert.equal( min, 1 );\n });\n\n it(\"при отсутствии аргументов просто вызывает функцию\", function() {\n var spy = sinon.spy();\n applyAll(spy);\n assert( spy.calledOnce );\n assert.equal( spy.firstCall.args.length, 0 );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c14f1f6dbff33a791c3" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c14f1f6dbff33a791ce" }, "plunkId" : "RF0AAeevV3Xn01FLcMji", "webPath" : "/task/logging-decorator/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c14f1f6dbff33a791cf" } }, { "content" : "describe(\"makeLogging\", function() {\n it(\"записывает вызовы в массив log\", function() {\n var work = sinon.spy();\n\n var log = [];\n work = makeLogging(work, log);\n assert.deepEqual( log, []);\n\n work(1);\n assert.deepEqual( log, [1]);\n\n work(2);\n assert.deepEqual( log, [1, 2]);\n });\n\n it(\"передаёт вызов функции, возвращает её результат\", function() {\n var log = [];\n \n function work(x) {\n return x*2;\n }\n\n work = sinon.spy(work);\n var spy = work;\n work = makeLogging(work, log);\n \n assert.equal( work(1), 2 );\n assert(spy.calledWith(1));\n });\n \n\n it(\"сохраняет контекст вызова для методов объекта\", function() {\n var log = [];\n \n var calculator = {\n double: function(x) { return x*2; }\n }\n\n calculator.double = sinon.spy(calculator.double);\n var spy = calculator.double;\n calculator.double = makeLogging(calculator.double, log);\n\n assert.equal( calculator.double(1), 2 );\n assert(spy.calledWith(1));\n assert(spy.calledOn(calculator));\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c14f1f6dbff33a791d0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c15f1f6dbff33a791d1" }, "plunkId" : "X1kG437NYklFa0CgEAYD", "webPath" : "/task/logging-decorator/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c15f1f6dbff33a791d2" } }, { "content" : "describe(\"makeLogging\", function() {\n it(\"записывает вызовы в массив log\", function() {\n var work = sinon.spy();\n\n var log = [];\n work = makeLogging(work, log);\n assert.deepEqual( log, []);\n\n work(1);\n assert.deepEqual( log, [1]);\n\n work(2);\n assert.deepEqual( log, [1, 2]);\n });\n\n it(\"передаёт вызов функции, возвращает её результат\", function() {\n var log = [];\n \n function work(x) {\n return x*2;\n }\n\n work = sinon.spy(work);\n var spy = work;\n work = makeLogging(work, log);\n \n assert.equal( work(1), 2 );\n assert(spy.calledWith(1));\n });\n \n\n it(\"сохраняет контекст вызова для методов объекта\", function() {\n var log = [];\n \n var calculator = {\n double: function(x) { return x*2; }\n }\n\n calculator.double = sinon.spy(calculator.double);\n var spy = calculator.double;\n calculator.double = makeLogging(calculator.double, log);\n\n assert.equal( calculator.double(1), 2 );\n assert(spy.calledWith(1));\n assert(spy.calledOn(calculator));\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c15f1f6dbff33a791d3" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c16f1f6dbff33a791d5" }, "plunkId" : "0dr4vW4j8EYHWRMSSe8J", "webPath" : "/task/logging-decorator-arguments/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c16f1f6dbff33a791d6" } }, { "content" : "describe(\"makeLogging\", function() {\n it(\"записывает вызовы в массив log\", function() {\n var work = sinon.spy();\n\n var log = [];\n work = makeLogging(work, log);\n assert.deepEqual( log, []);\n\n work(1, 2);\n assert.deepEqual( log, [[1, 2]]);\n\n work(3, 4);\n assert.deepEqual( log, [[1, 2], [3,4]]);\n });\n\n it(\"передаёт вызов функции, возвращает её результат\", function() {\n var log = [];\n \n function sum(a, b) {\n return a + b;\n }\n\n sum = sinon.spy(sum);\n var spy = sum;\n sum = makeLogging(sum, log);\n \n assert.equal( sum(1, 2), 3 );\n assert(spy.calledWith(1, 2));\n });\n \n\n it(\"сохраняет контекст вызова для методов объекта\", function() {\n var log = [];\n \n var calculator = {\n sum: function(a, b) { return a + b; }\n }\n\n calculator.sum = sinon.spy(calculator.sum);\n var spy = calculator.sum;\n calculator.sum = makeLogging(calculator.sum, log);\n\n assert.equal( calculator.sum(1, 2), 3 );\n assert(spy.calledWith(1, 2));\n assert(spy.calledOn(calculator));\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c16f1f6dbff33a791d7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c16f1f6dbff33a791d8" }, "plunkId" : "udSvcQsMOS7N4O4sREvI", "webPath" : "/task/logging-decorator-arguments/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c16f1f6dbff33a791d9" } }, { "content" : "describe(\"makeLogging\", function() {\n it(\"записывает вызовы в массив log\", function() {\n var work = sinon.spy();\n\n var log = [];\n work = makeLogging(work, log);\n assert.deepEqual( log, []);\n\n work(1, 2);\n assert.deepEqual( log, [[1, 2]]);\n\n work(3, 4);\n assert.deepEqual( log, [[1, 2], [3,4]]);\n });\n\n it(\"передаёт вызов функции, возвращает её результат\", function() {\n var log = [];\n \n function sum(a, b) {\n return a + b;\n }\n\n sum = sinon.spy(sum);\n var spy = sum;\n sum = makeLogging(sum, log);\n \n assert.equal( sum(1, 2), 3 );\n assert(spy.calledWith(1, 2));\n });\n \n\n it(\"сохраняет контекст вызова для методов объекта\", function() {\n var log = [];\n \n var calculator = {\n sum: function(a, b) { return a + b; }\n }\n\n calculator.sum = sinon.spy(calculator.sum);\n var spy = calculator.sum;\n calculator.sum = makeLogging(calculator.sum, log);\n\n assert.equal( calculator.sum(1, 2), 3 );\n assert(spy.calledWith(1, 2));\n assert(spy.calledOn(calculator));\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c16f1f6dbff33a791da" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c17f1f6dbff33a791dc" }, "plunkId" : "fhkKufsxygQjNGI7YDDJ", "webPath" : "/task/caching-decorator/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c17f1f6dbff33a791dd" } }, { "content" : "describe(\"makeCaching\", function() {\n\n it(\"запоминает предыдущее значение функции с таким аргументом\", function() {\n function f(x) { \n return Math.random()*x; \n }\n\n f = makeCaching(f);\n\n var a = f(1);\n var b = f(1);\n assert.equal(a, b);\n \n var anotherValue = f(2); \n // почти наверняка другое значение\n assert.notEqual( a, anotherValue );\n });\n\n it(\"сохраняет контекст вызова\", function() {\n var obj = {\n spy: sinon.spy()\n };\n\n var spy = obj.spy;\n obj.spy = makeCaching(obj.spy);\n obj.spy(123);\n assert( spy.calledWith(123) );\n assert( spy.calledOn(obj) );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c17f1f6dbff33a791de" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c18f1f6dbff33a791df" }, "plunkId" : "Ybjccby33S9t5SOxgOWT", "webPath" : "/task/caching-decorator/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c18f1f6dbff33a791e0" } }, { "content" : "describe(\"makeCaching\", function() {\n\n it(\"запоминает предыдущее значение функции с таким аргументом\", function() {\n function f(x) { \n return Math.random()*x; \n }\n\n f = makeCaching(f);\n\n var a = f(1);\n var b = f(1);\n assert.equal(a, b);\n \n var anotherValue = f(2); \n // почти наверняка другое значение\n assert.notEqual( a, anotherValue );\n });\n\n it(\"сохраняет контекст вызова\", function() {\n var obj = {\n spy: sinon.spy()\n };\n\n var spy = obj.spy;\n obj.spy = makeCaching(obj.spy);\n obj.spy(123);\n assert( spy.calledWith(123) );\n assert( spy.calledOn(obj) );\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c18f1f6dbff33a791e1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c19f1f6dbff33a791ef" }, "plunkId" : "rSBS0RNfs11eoXF3g2Cz", "webPath" : "/task/delay/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c19f1f6dbff33a791f0" } }, { "content" : "describe(\"delay\", function() {\n before(function() {\n this.clock = sinon.useFakeTimers();\n });\n\n after(function() {\n this.clock.restore();\n });\n\n it(\"вызывает функцию через указанный таймаут\", function() {\n var start = Date.now();\n function f(x) {\n assert.equal(Date.now() - start, 1000);\n }\n f = sinon.spy(f);\n \n var f1000 = delay(f, 1000);\n f1000(\"test\");\n this.clock.tick(2000);\n assert(f.calledOnce, 'calledOnce check fails');\n });\n\n it(\"передаёт аргументы и контекст\", function() {\n var start = Date.now();\n var user = {\n sayHi: function(phrase, who) {\n assert.equal(this, user);\n assert.equal(phrase, \"Привет\");\n assert.equal(who, \"Вася\");\n assert.equal(Date.now() - start, 1500);\n }\n };\n \n user.sayHi = sinon.spy(user.sayHi);\n \n var spy = user.sayHi;\n user.sayHi = delay(user.sayHi, 1500);\n \n user.sayHi(\"Привет\", \"Вася\");\n \n this.clock.tick(2000);\n \n assert(spy.calledOnce, 'проверка calledOnce не сработала');\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c19f1f6dbff33a791f1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1af1f6dbff33a791f2" }, "plunkId" : "miUgzq2GIkRGbkR3qPPZ", "webPath" : "/task/delay/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c1af1f6dbff33a791f3" } }, { "content" : "describe(\"delay\", function() {\n before(function() {\n this.clock = sinon.useFakeTimers();\n });\n\n after(function() {\n this.clock.restore();\n });\n\n it(\"вызывает функцию через указанный таймаут\", function() {\n var start = Date.now();\n function f(x) {\n assert.equal(Date.now() - start, 1000);\n }\n f = sinon.spy(f);\n \n var f1000 = delay(f, 1000);\n f1000(\"test\");\n this.clock.tick(2000);\n assert(f.calledOnce, 'calledOnce check fails');\n });\n\n it(\"передаёт аргументы и контекст\", function() {\n var start = Date.now();\n var user = {\n sayHi: function(phrase, who) {\n assert.equal(this, user);\n assert.equal(phrase, \"Привет\");\n assert.equal(who, \"Вася\");\n assert.equal(Date.now() - start, 1500);\n }\n };\n \n user.sayHi = sinon.spy(user.sayHi);\n \n var spy = user.sayHi;\n user.sayHi = delay(user.sayHi, 1500);\n \n user.sayHi(\"Привет\", \"Вася\");\n \n this.clock.tick(2000);\n \n assert(spy.calledOnce, 'проверка calledOnce не сработала');\n });\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c1af1f6dbff33a791f4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1bf1f6dbff33a791f6" }, "plunkId" : "3wdxWhGrRp8rgzOQZ7fs", "webPath" : "/task/debounce/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c1bf1f6dbff33a791f7" } }, { "content" : "describe(\"debounce\", function() {\n before(function() {\n this.clock = sinon.useFakeTimers();\n });\n \n after(function() {\n this.clock.restore();\n });\n\n it(\"вызывает функцию не чаще чем раз в ms миллисекунд\", function() {\n var log = '';\n function f(a) { log += a; }\n\n f = debounce(f, 1000);\n\n f(1); // выполнится сразу же\n f(2); // игнор\n\n setTimeout(function() { f(3) }, 100); // игнор (рановато)\n setTimeout(function() { f(4) }, 1100); // выполнится (таймаут прошёл)\n setTimeout(function() { f(5) }, 1500); // игнор\n\n this.clock.tick(5000);\n assert.equal(log, \"14\");\n });\n\n it(\"сохраняет контекст вызова\", function() {\n var obj = {\n f: function() { \n assert.equal(this, obj);\n }\n };\n \n obj.f = debounce(obj.f, 1000);\n obj.f(\"test\");\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c1bf1f6dbff33a791f8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1cf1f6dbff33a791f9" }, "plunkId" : "7PAr0GpUuHAlmDjIrZj1", "webPath" : "/task/debounce/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c1cf1f6dbff33a791fa" } }, { "content" : "describe(\"debounce\", function() {\n before(function() {\n this.clock = sinon.useFakeTimers();\n });\n \n after(function() {\n this.clock.restore();\n });\n\n it(\"вызывает функцию не чаще чем раз в ms миллисекунд\", function() {\n var log = '';\n function f(a) { log += a; }\n\n f = debounce(f, 1000);\n\n f(1); // выполнится сразу же\n f(2); // игнор\n\n setTimeout(function() { f(3) }, 100); // игнор (рановато)\n setTimeout(function() { f(4) }, 1100); // выполнится (таймаут прошёл)\n setTimeout(function() { f(5) }, 1500); // игнор\n\n this.clock.tick(5000);\n assert.equal(log, \"14\");\n });\n\n it(\"сохраняет контекст вызова\", function() {\n var obj = {\n f: function() { \n assert.equal(this, obj);\n }\n };\n \n obj.f = debounce(obj.f, 1000);\n obj.f(\"test\");\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c1cf1f6dbff33a791fb" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1df1f6dbff33a791fd" }, "plunkId" : "lX0ccKs5gMtlXPe6XfnC", "webPath" : "/task/throttle/source", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c1df1f6dbff33a791fe" } }, { "content" : "describe(\"throttle(f, 1000)\", function() {\n var f1000;\n var log = \"\";\n function f(a) { log += a; } \n\n before(function() {\n f1000 = throttle(f, 1000);\n this.clock = sinon.useFakeTimers();\n });\n\n it(\"первый вызов срабатывает тут же\", function() {\n f1000(1); // такой вызов должен сработать тут же\n assert.equal(log, \"1\");\n });\n\n it(\"тормозит второе срабатывание до 1000мс\", function() {\n f1000(2); // (тормозим, не прошло 1000мс)\n f1000(3); // (тормозим, не прошло 1000мс)\n // через 1000 мс запланирован вызов с последним аргументом \n\n assert.equal(log, \"1\"); // пока что сработал только первый вызов\n \n this.clock.tick(1000); // прошло 1000мс времени\n assert.equal(log, \"13\"); // log==13, т.к. сработал вызов f1000(3)\n });\n\n it(\"тормозит третье срабатывание до 1000мс после второго\", function() {\n this.clock.tick(100);\n f1000(4); // (тормозим, с последнего вызова прошло 100мс - менее 1000мс)\n this.clock.tick(100);\n f1000(5); // (тормозим, с последнего вызова прошло 200мс - менее 1000мс)\n this.clock.tick(700);\n f1000(6); // (тормозим, с последнего вызова прошло 900мс - менее 1000мс)\n \n this.clock.tick(100); // сработал вызов с 6\n\n assert.equal(log, \"136\");\n });\n\n after(function() {\n this.clock.restore();\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c1df1f6dbff33a791ff" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1df1f6dbff33a79200" }, "plunkId" : "tvJUxdUpwgxdrOD4Di8L", "webPath" : "/task/throttle/solution", "files" : [ { "content" : "\n\n\n \n \n \n\n\n\n \n\n\n", "filename" : "index.html", "_id" : { "$oid" : "54c29c1df1f6dbff33a79201" } }, { "content" : "describe(\"throttle(f, 1000)\", function() {\n var f1000;\n var log = \"\";\n function f(a) { log += a; } \n\n before(function() {\n f1000 = throttle(f, 1000);\n this.clock = sinon.useFakeTimers();\n });\n\n it(\"первый вызов срабатывает тут же\", function() {\n f1000(1); // такой вызов должен сработать тут же\n assert.equal(log, \"1\");\n });\n\n it(\"тормозит второе срабатывание до 1000мс\", function() {\n f1000(2); // (тормозим, не прошло 1000мс)\n f1000(3); // (тормозим, не прошло 1000мс)\n // через 1000 мс запланирован вызов с последним аргументом \n\n assert.equal(log, \"1\"); // пока что сработал только первый вызов\n \n this.clock.tick(1000); // прошло 1000мс времени\n assert.equal(log, \"13\"); // log==13, т.к. сработал вызов f1000(3)\n });\n\n it(\"тормозит третье срабатывание до 1000мс после второго\", function() {\n this.clock.tick(100);\n f1000(4); // (тормозим, с последнего вызова прошло 100мс - менее 1000мс)\n this.clock.tick(100);\n f1000(5); // (тормозим, с последнего вызова прошло 200мс - менее 1000мс)\n this.clock.tick(700);\n f1000(6); // (тормозим, с последнего вызова прошло 900мс - менее 1000мс)\n \n this.clock.tick(100); // сработал вызов с 6\n\n assert.equal(log, \"136\");\n });\n\n after(function() {\n this.clock.restore();\n });\n\n});", "filename" : "test.js", "_id" : { "$oid" : "54c29c1df1f6dbff33a79202" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1ef1f6dbff33a79203" }, "plunkId" : "xSEcNSBtNYRVJxBMjR5S", "webPath" : "/article/setTimeout-setInterval/setInterval-anim", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c1ef1f6dbff33a79204" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1ff1f6dbff33a79216" }, "plunkId" : "oBYeNVTNa7MofiF5c2cD", "webPath" : "/task/coffeemachine-fix-run/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c1ff1f6dbff33a79217" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c1ff1f6dbff33a79218" }, "plunkId" : "rYcm45y3rh58KEqJQKax", "webPath" : "/task/coffeemachine-fix-run/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c1ff1f6dbff33a79219" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c20f1f6dbff33a7921b" }, "plunkId" : "udmOzo0dGfAMNBeLVMyb", "webPath" : "/task/coffeemachine-disable-stop/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c20f1f6dbff33a7921c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c20f1f6dbff33a79236" }, "plunkId" : "u2ezArcWwcAliMf98FAk", "webPath" : "/task/clock-class/solution", "files" : [ { "filename" : "clock.js", "content" : "function Clock(options) {\n this._template = options.template;\n}\n\nClock.prototype._render = function render() {\n var date = new Date();\n\n var hours = date.getHours();\n if (hours < 10) hours = '0' + hours;\n\n var min = date.getMinutes();\n if (min < 10) min = '0' + min;\n\n var sec = date.getSeconds();\n if (sec < 10) sec = '0' + sec;\n\n var output = this._template.replace('h', hours).replace('m', min).replace('s', sec);\n\n console.log(output);\n};\n\nClock.prototype.stop = function() {\n clearInterval(this._timer);\n};\n\nClock.prototype.start = function() {\n this._render();\n var self = this;\n this._timer = setInterval(function() {\n self._render();\n }, 1000);\n};", "_id" : { "$oid" : "54c29c20f1f6dbff33a79237" } }, { "filename" : "index.html", "content" : "\n\n\n Часики в консоли\n \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c20f1f6dbff33a79238" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c21f1f6dbff33a79239" }, "plunkId" : "tSsDFVisI1trctIgn5x6", "webPath" : "/task/clock-class/source", "files" : [ { "filename" : "clock.js", "content" : "function Clock(options) {\n\n var template = options.template;\n var timer;\n\n function render() {\n var date = new Date();\n\n var hours = date.getHours();\n if (hours < 10) hours = '0' + hours;\n\n var min = date.getMinutes();\n if (min < 10) min = '0' + min;\n\n var sec = date.getSeconds();\n if (sec < 10) sec = '0' + sec;\n\n var output = template.replace('h', hours).replace('m', min).replace('s', sec);\n\n console.log(output);\n }\n\n this.stop = function() {\n clearInterval(timer);\n };\n\n this.start = function() {\n render();\n timer = setInterval(render, 1000);\n }\n\n}", "_id" : { "$oid" : "54c29c21f1f6dbff33a7923a" } }, { "filename" : "index.html", "content" : "\n\n\n Часики в консоли\n \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c21f1f6dbff33a7923b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c22f1f6dbff33a7923d" }, "plunkId" : "oEDhGBRjgLWbjv77F8DQ", "webPath" : "/task/clock-class-extended/solution", "files" : [ { "filename" : "clock.js", "content" : "function Clock(options) {\n this._template = options.template;\n}\n\nClock.prototype._render = function render() {\n var date = new Date();\n\n var hours = date.getHours();\n if (hours < 10) hours = '0' + hours;\n\n var min = date.getMinutes();\n if (min < 10) min = '0' + min;\n\n var sec = date.getSeconds();\n if (sec < 10) sec = '0' + sec;\n\n var output = this._template.replace('h', hours).replace('m', min).replace('s', sec);\n\n console.log(output);\n};\n\nClock.prototype.stop = function() {\n clearInterval(this._timer);\n};\n\nClock.prototype.start = function() {\n this._render();\n var self = this;\n this._timer = setInterval(function() {\n self._render();\n }, 1000);\n};", "_id" : { "$oid" : "54c29c22f1f6dbff33a7923e" } }, { "filename" : "extended-clock.js", "content" : "function ExtendedClock(options) {\n Clock.apply(this, arguments);\n this._precision = +options.precision || 1000;\n}\n\nExtendedClock.prototype = Object.create(Clock.prototype);\n\nExtendedClock.prototype.start = function() {\n this._render();\n var self = this;\n this._timer = setInterval(function() {\n self._render();\n }, this._precision);\n};", "_id" : { "$oid" : "54c29c22f1f6dbff33a7923f" } }, { "filename" : "index.html", "content" : "\n\n\n Часики в консоли\n \n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c22f1f6dbff33a79240" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c23f1f6dbff33a79241" }, "plunkId" : "rbSEOUU7FHuRXxCmIVDo", "webPath" : "/task/clock-class-extended/source", "files" : [ { "filename" : "clock.js", "content" : "function Clock(options) {\n this._template = options.template;\n}\n\nClock.prototype._render = function render() {\n var date = new Date();\n\n var hours = date.getHours();\n if (hours < 10) hours = '0' + hours;\n\n var min = date.getMinutes();\n if (min < 10) min = '0' + min;\n\n var sec = date.getSeconds();\n if (sec < 10) sec = '0' + sec;\n\n var output = this._template.replace('h', hours).replace('m', min).replace('s', sec);\n\n console.log(output);\n};\n\nClock.prototype.stop = function() {\n clearInterval(this._timer);\n};\n\nClock.prototype.start = function() {\n this._render();\n var self = this;\n this._timer = setInterval(function() {\n self._render();\n }, 1000);\n};", "_id" : { "$oid" : "54c29c23f1f6dbff33a79242" } }, { "filename" : "extended-clock.js", "content" : "function extend(Child, Parent) {\n Child.prototype = inherit(Parent.prototype);\n Child.prototype.constructor = Child;\n Child.parent = Parent.prototype;\n}\nfunction inherit(proto) {\n function F() {}\n F.prototype = proto;\n return new F;\n}\n\n// ваш код", "_id" : { "$oid" : "54c29c23f1f6dbff33a79243" } }, { "filename" : "index.html", "content" : "\n\n\n Часики в консоли\n \n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c23f1f6dbff33a79244" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c24f1f6dbff33a79246" }, "plunkId" : "jtQRu4XYbDX8MZQCmH7m", "webPath" : "/task/menu-timer-animated/solution", "files" : [ { "filename" : "menu.js", "content" : "function Menu(state) {\n this._state = state || this.STATE_CLOSED;\n};\n\nMenu.prototype.STATE_OPEN = 1;\nMenu.prototype.STATE_CLOSED = 0;\n\nMenu.prototype.open = function() {\n this._state = this.STATE_OPEN;\n};\n\nMenu.prototype.close = function() {\n this._state = this.STATE_CLOSED;\n};\n\nMenu.prototype._stateAsString = function() {\n switch(this._state) {\n case this.STATE_OPEN:\n return 'открыто';\n\n case this.STATE_CLOSED:\n return 'закрыто';\n }\n};\n\nMenu.prototype.showState = function() {\n alert( this._stateAsString() );\n}", "_id" : { "$oid" : "54c29c24f1f6dbff33a79247" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c24f1f6dbff33a79248" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c25f1f6dbff33a79249" }, "plunkId" : "byPVkPwyAsw0EqHQWsvw", "webPath" : "/task/menu-timer-animated/source", "files" : [ { "filename" : "menu.js", "content" : "function Menu(state) {\n this._state = state || Menu.STATE_CLOSED;\n};\n\nMenu.STATE_OPEN = 1;\nMenu.STATE_CLOSED = 0;\n\nMenu.prototype.open = function() {\n this._state = Menu.STATE_OPEN;\n};\n\nMenu.prototype.close = function() {\n this._state = Menu.STATE_CLOSED;\n};\n\nMenu.prototype._stateAsString = function() {\n switch(this._state) {\n case Menu.STATE_OPEN:\n return 'открыто';\n\n case Menu.STATE_CLOSED:\n return 'закрыто';\n }\n};\n\nMenu.prototype.showState = function() {\n alert( this._stateAsString() );\n};", "_id" : { "$oid" : "54c29c25f1f6dbff33a7924a" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c25f1f6dbff33a7924b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c26f1f6dbff33a7925a" }, "plunkId" : "tJhdegOl6pLynngiTZb2", "webPath" : "/task/clock-settimeout/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n
    \n hh:mm:ss\n
    \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c26f1f6dbff33a7925b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c26f1f6dbff33a7925c" }, "plunkId" : "vthHk4HLlf7TgOQu3erH", "webPath" : "/task/clock-settimeout/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c26f1f6dbff33a7925d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c27f1f6dbff33a79263" }, "plunkId" : "F7tWButLm4TZLd1QYF0f", "webPath" : "/task/create-list/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n

    Создание списка

    \n\n\n\n\n", "_id" : { "$oid" : "54c29c27f1f6dbff33a79264" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c27f1f6dbff33a79266" }, "plunkId" : "5PqFj9ef2aOl5D0omLcY", "webPath" : "/task/create-object-tree/build-tree-dom", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c27f1f6dbff33a79267" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c28f1f6dbff33a79268" }, "plunkId" : "JVLctklWIxlQNorBkae4", "webPath" : "/task/create-object-tree/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c28f1f6dbff33a79269" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c28f1f6dbff33a7926a" }, "plunkId" : "HqaLLUoU5fDSdBGu4z5g", "webPath" : "/task/create-object-tree/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
    \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c28f1f6dbff33a7926b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c28f1f6dbff33a7926d" }, "plunkId" : "XunHA8n1iwaBjWjhB4H3", "webPath" : "/task/calendar-table/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c28f1f6dbff33a7926e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c29f1f6dbff33a7926f" }, "plunkId" : "Yt5P4tj12Jx9A4PdeanQ", "webPath" : "/task/calendar-table/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c29f1f6dbff33a79270" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c29f1f6dbff33a79272" }, "plunkId" : "H3U0mnSwkbitA5SEsHsU", "webPath" : "/task/clock-setinterval/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n
    \n hh:mm:ss\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c29f1f6dbff33a79273" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c29f1f6dbff33a79274" }, "plunkId" : "jPTzckA5F1eWIBwAli1F", "webPath" : "/task/clock-setinterval/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c29f1f6dbff33a79275" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2af1f6dbff33a7927b" }, "plunkId" : "Q70Vwckanbslk8vHU3XU", "webPath" : "/task/sort-table-performance/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n
    \n Алгоритм 1.\n
      \n
    1. Все TR удалить из таблицы, при этом собрав их в JavaScript-массив.
    2. \n
    3. Отсортировать этот массив, используя свою функцию в sort(...) для сравнения TR
    4. \n
    5. Добавить TR из массива в таблицу в нужном порядке
    6. \n
    \n\n
    \n\n
    \n Алгоритм 2.\n
      \n
    1. Скопировать TR в JavaScript-массив.
    2. \n
    3. Отсортировать этот массив, используя свою функцию в sort(...) для сравнения TR
    4. \n
    5. Добавить TR из массива в таблицу в нужном порядке. При добавлении каждый TR сам удалится с предыдущего места.
    6. \n
    \n\n
    \n\n\n
    \n Алгоритм 3.\n
      \n
    1. Создать массив из объектов вида {elem: ссылка на TR, value: содержимое TR}.
    2. \n
    3. Отсортировать массив по value. Функция сравнения во время сортировки теперь будет обращаться не к innerHTML, а к свойству объекта, это быстрее. Сортировка может потребовать многократных сравнений одного и того же элемента, отсюда выигрыш.
    4. \n
    5. Добавить TR в таблицу в нужном порядке (автоудалятся с предыдущего места).
    6. \n
    \n\n
    \n\n\n
    \n Алгоритм 4.\n
      \n
    1. Выполнить алгоритм 3, но перед этим удалить таблицу из документа, а после - вставить обратно.
    2. \n
    \n\n
    \n\n
    \n Алгоритм 5.\n
      \n
    1. Замерить время генерации таблицы (создаётся строка и пишется в innerHTML).
    2. \n
    \n\n
    \n\n
    \n\n\n\n\n\n\n

    Содержимое документа для придания \"реалистичности\"

    \n\n
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    01234567890123456789012345678901234567890123456789
    \n\n\n\n", "_id" : { "$oid" : "54c29c2af1f6dbff33a7927c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2af1f6dbff33a79280" }, "plunkId" : "pMYbUJImGotbNbeT5mua", "webPath" : "/task/round-button-javascript/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n
    \n Кнопка:\n \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2af1f6dbff33a79281" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2bf1f6dbff33a79282" }, "plunkId" : "hNPPo8Q6XQ8LYmOkLcXG", "webPath" : "/task/round-button-javascript/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n
    \n Кнопка:\n \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2bf1f6dbff33a79283" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2bf1f6dbff33a79285" }, "plunkId" : "FlpA1OlmNuQ8V3FH5Bay", "webPath" : "/task/create-notification/solution", "files" : [ { "filename" : "index.css", "content" : ".notification {\n position: fixed;\n z-index: 1000;\n padding: 5px;\n border: 1px solid black;\n font: normal 20px Georgia;\n background: white;\n text-align: center;\n}\n\n.welcome {\n background: red;\n color: yellow;\n}", "_id" : { "$oid" : "54c29c2bf1f6dbff33a79286" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Уведомление

    \n\n

    \n Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum aspernatur quam ex eaque inventore quod voluptatem adipisci omnis nemo nulla fugit iste numquam ducimus cumque minima porro ea quidem maxime necessitatibus beatae labore soluta voluptatum magnam consequatur sit laboriosam velit excepturi laborum sequi eos placeat et quia deleniti? Corrupti velit impedit autem et obcaecati fuga debitis nemo ratione iste veniam amet dicta hic ipsam unde cupiditate incidunt aut iure ipsum officiis soluta temporibus. Tempore dicta ullam delectus numquam consectetur quisquam explicabo culpa excepturi placeat quo sequi molestias reprehenderit hic at nemo cumque voluptates quidem repellendus maiores unde earum molestiae ad.\n

    \n\n \n\n\n\n", "_id" : { "$oid" : "54c29c2bf1f6dbff33a79287" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2bf1f6dbff33a79288" }, "plunkId" : "4EEuyAVLSxwTCj40eJ8g", "webPath" : "/task/create-notification/source", "files" : [ { "filename" : "index.css", "content" : ".notification {\n position: fixed;\n z-index: 1000;\n padding: 5px;\n border: 1px solid black;\n font: normal 20px Georgia;\n background: white;\n text-align: center;\n}\n\n.welcome {\n background: red;\n color: yellow;\n}", "_id" : { "$oid" : "54c29c2bf1f6dbff33a79289" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Уведомление

    \n\n

    \n Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum aspernatur quam ex eaque inventore quod voluptatem adipisci omnis nemo nulla fugit iste numquam ducimus cumque minima porro ea quidem maxime necessitatibus beatae labore soluta voluptatum magnam consequatur sit laboriosam velit excepturi laborum sequi eos placeat et quia deleniti? Corrupti velit impedit autem et obcaecati fuga debitis nemo ratione iste veniam amet dicta hic ipsam unde cupiditate incidunt aut iure ipsum officiis soluta temporibus. Tempore dicta ullam delectus numquam consectetur quisquam explicabo culpa excepturi placeat quo sequi molestias reprehenderit hic at nemo cumque voluptates quidem repellendus maiores unde earum molestiae ad.\n

    \n\n

    В CSS есть готовый класс notification, который можно ставить уведомлению.

    \n\n \n\n\n\n", "_id" : { "$oid" : "54c29c2bf1f6dbff33a7928a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2cf1f6dbff33a7928f" }, "plunkId" : "agVRzj1cu0v7gCOr2lW7", "webPath" : "/task/div-placeholder/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\nBefore Before Before\n\n
    \nText Text Text
    \nText Text Text
    \n
    \n\nAfter After After\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2cf1f6dbff33a79290" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2cf1f6dbff33a79291" }, "plunkId" : "4GGP2XKhQV0t0JPHpKoJ", "webPath" : "/task/div-placeholder/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\nBefore Before Before\n\n
    \nText Text Text
    \nText Text Text
    \n
    \n\nAfter After After\n\n\n\n\n", "_id" : { "$oid" : "54c29c2cf1f6dbff33a79292" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2cf1f6dbff33a79294" }, "plunkId" : "3NhlR9wqDYsIwqAEa3nO", "webPath" : "/task/put-ball-in-center/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
    \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
    \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2cf1f6dbff33a79295" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2df1f6dbff33a79296" }, "plunkId" : "rx12PQnBYcr5dGTPddpV", "webPath" : "/task/put-ball-in-center/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
    \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c2df1f6dbff33a79297" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2df1f6dbff33a79299" }, "plunkId" : "yJN9LMAdB7IGO76GJP7j", "webPath" : "/task/expand-element/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2df1f6dbff33a7929a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2ef1f6dbff33a7929b" }, "plunkId" : "j8GrpaZtl8a7JUmAPMtw", "webPath" : "/task/expand-element/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст\n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2ef1f6dbff33a7929c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2ef1f6dbff33a7929e" }, "plunkId" : "cSnS2hICjJYJjm4E4Ngv", "webPath" : "/article/metrics/cssWidthScroll", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n
    \nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\nтекст текст текст текст текст текст текст текст текст текст текст текст текст текст\n
    \n\n\n\nУ элемента стоит style=\"width:300px\"
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c2ef1f6dbff33a7929f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2ef1f6dbff33a792a0" }, "plunkId" : "vCptLm0jmD4HhIBrAbox", "webPath" : "/article/metrics/metric", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n
    \n

    Introduction

    \n

    This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company's Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997.

    \n\n

    That Ecma Standard was submitted to ISO/IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.

    \n\n

    The third edition of the Standard introduced powerful regular expressions, better string handling, new control statements, try/catch exception handling, tighter definition of errors, formatting for numeric output and minor changes in anticipation of forthcoming internationalisation facilities and future language growth. The third edition of the ECMAScript standard was adopted by the Ecma General Assembly of December 1999 and published as ISO/IEC 16262:2002 in June 2002.

    \n\n
    \n\n\n
    Координаты мыши: ...
    \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c2ef1f6dbff33a792a1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2ef1f6dbff33a792aa" }, "plunkId" : "AfmgDgBQUIf34hul9bNl", "webPath" : "/task/find-point-coordinates/solution", "files" : [ { "filename" : "index.css", "content" : "body {\n padding: 20px 0 0 20px;\n cursor: pointer;\n}\n\n#field {\n overflow: hidden;\n width: 200px;\n height: 150px;\n border-top: 10px solid black;\n border-right: 10px solid gray;\n border-bottom: 10px solid gray;\n border-left: 10px solid black;\n background-color: #00FF00;\n font: 10px/1.2 monospace;\n}\n\n.triangle-right {\n position: relative;\n width: 0;\n height: 0;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-left: 20px solid red;\n text-indent: -20px;\n font: 12px/1 monospace;\n}", "_id" : { "$oid" : "54c29c2ef1f6dbff33a792ab" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n Кликните на любое место, чтобы получить координаты относительно окна.
    \n Это для удобства тестирования, чтобы проверить результат, который вы получите из DOM.
    \n
    (координаты появятся тут)
    \n\n\n
    \n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
    \n\n\n
    1
    \n
    3
    \n
    4
    \n
    2
    \n\n\n \n\n\n", "_id" : { "$oid" : "54c29c2ef1f6dbff33a792ac" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2ff1f6dbff33a792ad" }, "plunkId" : "NZIayQiYRluzwjUrRbjW", "webPath" : "/task/find-point-coordinates/source", "files" : [ { "filename" : "index.css", "content" : "body {\n padding: 20px 0 0 20px;\n cursor: pointer;\n}\n\n#field {\n overflow: hidden;\n width: 200px;\n height: 150px;\n border-top: 10px solid black;\n border-right: 10px solid gray;\n border-bottom: 10px solid gray;\n border-left: 10px solid black;\n background-color: #00FF00;\n font: 10px/1.2 monospace;\n}\n\n.triangle-right {\n position: relative;\n width: 0;\n height: 0;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-left: 20px solid red;\n text-indent: -20px;\n font: 12px/1 monospace;\n}", "_id" : { "$oid" : "54c29c2ff1f6dbff33a792ae" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n Кликните на любое место, чтобы получить координаты относительно окна.
    \n Это для удобства тестирования, чтобы проверить результат, который вы получите из DOM.
    \n
    (координаты появятся тут)
    \n\n\n
    \n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
    \n\n\n
    1
    \n
    3
    \n
    4
    \n
    2
    \n\n\n \n\n\n", "_id" : { "$oid" : "54c29c2ff1f6dbff33a792af" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c2ff1f6dbff33a792b1" }, "plunkId" : "noZWEyFq45DbKvKngg01", "webPath" : "/task/position-at/solution", "files" : [ { "filename" : "index.css", "content" : ".note {\n position: fixed;\n z-index: 1000;\n padding: 5px;\n border: 1px solid black;\n background: white;\n text-align: center;\n font: italic 14px Georgia;\n}\n\nblockquote {\n background:#f9f9f9;\n border-left:10px solid #ccc;\n margin: 0 0 0 100px;\n padding:.5em 10px;\n quotes:\"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n display: inline-block;\n white-space: pre;\n}\n\nblockquote:before {\n color: #ccc;\n content: open-quote;\n font-size:4em;\n line-height:.1em;\n margin-right:.25em;\n vertical-align:-.4em;\n}", "_id" : { "$oid" : "54c29c2ff1f6dbff33a792b2" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n
    \n- Что на завтрак, Бэрримор?\n- Овсянка, сэр.\n- А на обед?\n- Овсянка, сэр.\n- Ну а на ужин?\n- Котлеты, сэр.\n- Уррра!!!\n- Из овсянки, сэр!!!\n
    \n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n \n\n\n\n", "_id" : { "$oid" : "54c29c2ff1f6dbff33a792b3" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c30f1f6dbff33a792b4" }, "plunkId" : "WocAlcvRq3cWPTzvoGOg", "webPath" : "/task/position-at/source", "files" : [ { "filename" : "index.css", "content" : ".note {\n position: fixed;\n z-index: 1000;\n padding: 5px;\n border: 1px solid black;\n background: white;\n text-align: center;\n font: italic 14px Georgia;\n}\n\nblockquote {\n background:#f9f9f9;\n border-left:10px solid #ccc;\n margin: 0 0 0 100px;\n padding:.5em 10px;\n quotes:\"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n display: inline-block;\n white-space: pre;\n}\n\nblockquote:before {\n color: #ccc;\n content: open-quote;\n font-size:4em;\n line-height:.1em;\n margin-right:.25em;\n vertical-align:-.4em;\n}", "_id" : { "$oid" : "54c29c30f1f6dbff33a792b5" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n
    \n- Что на завтрак, Бэрримор?\n- Овсянка, сэр.\n- А на обед?\n- Овсянка, сэр.\n- Ну а на ужин?\n- Котлеты, сэр.\n- Уррра!!!\n- Из овсянки, сэр!!!\n
    \n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n \n\n\n\n", "_id" : { "$oid" : "54c29c30f1f6dbff33a792b6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c30f1f6dbff33a792ba" }, "plunkId" : "hYLQngKQqrmIANjOr1rZ", "webPath" : "/task/position-at-absolute/solution", "files" : [ { "filename" : "index.css", "content" : ".note {\n position: absolute;\n z-index: 1000;\n padding: 5px;\n border: 1px solid black;\n background: white;\n text-align: center;\n font: italic 14px Georgia;\n}\n\nblockquote {\n background:#f9f9f9;\n border-left:10px solid #ccc;\n margin: 0 0 0 100px;\n padding:.5em 10px;\n quotes:\"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n display: inline-block;\n white-space: pre;\n}\n\nblockquote:before {\n color: #ccc;\n content: open-quote;\n font-size:4em;\n line-height:.1em;\n margin-right:.25em;\n vertical-align:-.4em;\n}", "_id" : { "$oid" : "54c29c30f1f6dbff33a792bb" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Исправления два:

    \n\n
      \n
    1. Использование функции getCoords() из учебника для получения абсолютных координат.
    2. \n
    3. Изменение position:fixed на position:absolute в стилях.
    4. \n
    \n\n
    \n- Что на завтрак, Бэрримор?\n- Овсянка, сэр.\n- А на обед?\n- Овсянка, сэр.\n- Ну а на ужин?\n- Котлеты, сэр.\n- Уррра!!!\n- Из овсянки, сэр!!!\n
    \n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n \n\n\n\n", "_id" : { "$oid" : "54c29c30f1f6dbff33a792bc" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c31f1f6dbff33a792be" }, "plunkId" : "y6x3OJzRWPlAMN5MOyUq", "webPath" : "/task/position-at-2/solution", "files" : [ { "filename" : "index.css", "content" : ".note {\n position: absolute;\n z-index: 1000;\n padding: 5px;\n border: 1px solid black;\n background: white;\n text-align: center;\n font: italic 14px Georgia;\n opacity: .8;\n}\n\nblockquote {\n background: #f9f9f9;\n border-left: 10px solid #ccc;\n margin: 0 0 0 100px;\n padding: .5em 10px;\n quotes: \"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n display: inline-block;\n white-space: pre;\n}\n\nblockquote:before {\n color: #ccc;\n content: open-quote;\n font-size: 4em;\n line-height: .1em;\n margin-right: .25em;\n vertical-align: -.4em;\n}", "_id" : { "$oid" : "54c29c31f1f6dbff33a792bf" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n
    \n- Что на завтрак, Бэрримор?\n- Овсянка, сэр.\n- А на обед?\n- Овсянка, сэр.\n- Ну а на ужин?\n- Котлеты, сэр.\n- Уррра!!!\n- Из овсянки, сэр!!!\n
    \n\n

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit sint atque dolorum fuga ad incidunt voluptatum error fugiat animi amet! Odio temporibus nulla id unde quaerat dignissimos enim nisi rem provident molestias sit tempore omnis recusandae esse sequi officia sapiente.

    \n\n\n \n\n\n\n", "_id" : { "$oid" : "54c29c31f1f6dbff33a792c0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c31f1f6dbff33a792c9" }, "plunkId" : "lCTJhYpudGyHV4YoEPyh", "webPath" : "/task/dom-children/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n \n \n
    Пользователи:
    \n \n\n \n\n \n\n \n\n", "_id" : { "$oid" : "54c29c31f1f6dbff33a792ca" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c31f1f6dbff33a792cf" }, "plunkId" : "esBOizHyFu34mQdqWG3i", "webPath" : "/task/select-diagonal-cells/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n \n \n \n \n \n \n
    1:12:13:14:15:1
    1:22:23:24:25:2
    1:32:33:34:35:3
    1:42:43:44:45:4
    1:52:53:54:55:5
    \n \n\n", "_id" : { "$oid" : "54c29c31f1f6dbff33a792d0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c32f1f6dbff33a792d1" }, "plunkId" : "LDgXzAjMqs7xK8T2jUtW", "webPath" : "/task/select-diagonal-cells/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n \n \n \n \n \n \n
    1:12:13:14:15:1
    1:22:23:24:25:2
    1:32:33:34:35:3
    1:42:43:44:45:4
    1:52:53:54:55:5
    \n \n\n", "_id" : { "$oid" : "54c29c32f1f6dbff33a792d2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c33f1f6dbff33a792d7" }, "plunkId" : "S4x67ZsMH14Nz9uKJLZv", "webPath" : "/task/find-next-element/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
    Первый
    \n\n

    Второй

    \n\n\n\n\n", "_id" : { "$oid" : "54c29c33f1f6dbff33a792d8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c33f1f6dbff33a792dc" }, "plunkId" : "MYFCTnRA7mqphgFPvlKW", "webPath" : "/task/get-user-attribute/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n
    Выберите жанр
    \n\n \n\n\n", "_id" : { "$oid" : "54c29c33f1f6dbff33a792dd" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c33f1f6dbff33a792e3" }, "plunkId" : "wi2RhrPuIoGKSW1PVpOa", "webPath" : "/task/tree/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c33f1f6dbff33a792e4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c34f1f6dbff33a792e5" }, "plunkId" : "qxP2wkhxDSr9MDKrKRbM", "webPath" : "/task/tree/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c34f1f6dbff33a792e6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c34f1f6dbff33a792e8" }, "plunkId" : "ZF7OtkPIb0nLpxfxDv0q", "webPath" : "/task/set-class-links/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\nсписок\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c34f1f6dbff33a792e9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c34f1f6dbff33a792ee" }, "plunkId" : "pwvwy5mkrRLctMnisZgB", "webPath" : "/task/benchmark-search-dom/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\t\n \n\n\n\n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c35f1f6dbff33a792ef" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c35f1f6dbff33a792f0" }, "plunkId" : "RiHL4QZekmIHpvR0Zah4", "webPath" : "/task/benchmark-search-dom/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\t\n\n\n\n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n

    1

    2

    3

    4

    5

    6

    7

    8

    9

    \n\n\n\n\n", "_id" : { "$oid" : "54c29c35f1f6dbff33a792f1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c35f1f6dbff33a792f6" }, "plunkId" : "jNbDIUSwTa2kap21z10g", "webPath" : "/task/hide-other/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n
    Текст
    \n\n\n\n", "_id" : { "$oid" : "54c29c35f1f6dbff33a792f7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c35f1f6dbff33a792f8" }, "plunkId" : "6dBwlhctQKazDlV6EYd5", "webPath" : "/task/hide-other/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n
    Текст
    \n\n\n\n", "_id" : { "$oid" : "54c29c35f1f6dbff33a792f9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c36f1f6dbff33a792fd" }, "plunkId" : "xt0tlsHPImPFYe6eNciv", "webPath" : "/task/sliding-menu/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
    \n Сладости (нажми меня)!\n \n\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c36f1f6dbff33a792fe" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c36f1f6dbff33a792ff" }, "plunkId" : "elevrnQf9J6hWwIb5Acc", "webPath" : "/task/sliding-menu/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n▶ ▼ Сладости (нажми меня)!\n\n\n\n\n", "_id" : { "$oid" : "54c29c36f1f6dbff33a79300" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c37f1f6dbff33a79302" }, "plunkId" : "YrqjyCEVrZcWxkeoWAXS", "webPath" : "/task/hide-message/solution", "files" : [ { "filename" : "messages.css", "content" : "body {\n\tmargin: 10px auto;\n\twidth: 470px;\n}\n\nh3 {\n\tmargin: 0;\n\tpadding-bottom: .3em;\n\tpadding-right: 20px;\n\tfont-size: 1.1em;\n}\n\np {\n\tmargin: 0;\n\tpadding: 0 0 .5em;\n}\n\n.pane {\n\tbackground: #edf5e1;\n\tpadding: 10px 20px 10px;\n\tborder-top: solid 2px #c4df9b;\n position: relative;\n}\n\n.remove-button {\n position: absolute;\n font-size: 110%;\n top: 0;\n color: red;\n right: 10px;\n display: block;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n}", "_id" : { "$oid" : "54c29c37f1f6dbff33a79303" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
    \n
    \n

    Лошадь

    \n

    Домашняя лошадь — животное семейства непарнокопытных, одомашненный и единственный сохранившийся подвид дикой лошади, вымершей в дикой природе, за исключением небольшой популяции лошади Пржевальского.

    \n \n
    \n
    \n

    Осёл

    \n

    Домашний осёл или ишак — одомашненный подвид дикого осла, сыгравший важную историческую роль в развитии хозяйства и культуры человека. Все одомашненные ослы относятся к африканским ослам.

    \n \n
    \n
    \n

    Корова, а также пара слов о диком быке, о волах и о тёлках.

    \n

    Коро́ва — самка домашнего быка, одомашненного подвида дикого быка, парнокопытного жвачного животного семейства полорогих. Самцы вида называются быками, молодняк — телятами, кастрированные самцы — волами. Молодых (до первой стельности) самок называют тёлками.

    \n \n
    \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c37f1f6dbff33a79304" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c38f1f6dbff33a79305" }, "plunkId" : "MnOvEv9W99cF3ivXHtLu", "webPath" : "/task/hide-message/source", "files" : [ { "filename" : "messages.css", "content" : "body {\n\tmargin: 10px auto;\n\twidth: 470px;\n}\n\nh3 {\n\tmargin: 0;\n\tpadding-bottom: .3em;\n\tfont-size: 1.1em;\n}\n\np {\n\tmargin: 0;\n\tpadding: 0 0 .5em;\n}\n\n.pane {\n\tbackground: #edf5e1;\n\tpadding: 10px 20px 10px;\n\tborder-top: solid 2px #c4df9b;\n}\n\n.remove-button {\n font-size: 110%;\n color: red;\n right: 10px;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n}", "_id" : { "$oid" : "54c29c38f1f6dbff33a79306" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\nКнопка для удаления: \n\n
    \n\t
    \n

    Лошадь

    \n

    Домашняя лошадь — животное семейства непарнокопытных, одомашненный и единственный сохранившийся подвид дикой лошади, вымершей в дикой природе, за исключением небольшой популяции лошади Пржевальского.

    \n\t
    \n\t
    \n

    Осёл

    \n

    Домашний осёл или ишак — одомашненный подвид дикого осла, сыгравший важную историческую роль в развитии хозяйства и культуры человека. Все одомашненные ослы относятся к африканским ослам.

    \n\t
    \n\t
    \n

    Корова, а также пара слов о диком быке, о волах и о тёлках.

    \n

    Коро́ва — самка домашнего быка, одомашненного подвида дикого быка, парнокопытного жвачного животного семейства полорогих. Самцы вида называются быками, молодняк — телятами, кастрированные самцы — волами. Молодых (до первой стельности) самок называют тёлками.

    \n\t
    \n
    \n\n\n", "_id" : { "$oid" : "54c29c38f1f6dbff33a79307" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c38f1f6dbff33a79309" }, "plunkId" : "RfSDywOvuMvdN2rikTDo", "webPath" : "/task/carousel/solution", "files" : [ { "filename" : "style.css", "content" : "body {\n padding: 10px;\n}\n\n.carousel {\n position: relative;\n width: 398px;\n padding: 10px 40px;\n border: 1px solid #CCC;\n border-radius: 15px;\n background: #eee;\n}\n\n.carousel img {\n width: 130px;\n height: 130px;\n /* по умолчанию inline, в ряде браузеров это даст лишнее пространство вокруг элементов */\n display: block;\n}\n\n.arrow {\n position: absolute;\n top: 60px;\n padding: 0;\n background: #ddd;\n border-radius: 15px;\n border: 1px solid gray;\n font-size: 24px;\n line-height: 24px;\n color: #444;\n display: block;\n}\n\n.arrow:focus {\n outline: none;\n}\n\n.arrow:hover {\n background: #ccc;\n cursor: pointer;\n}\n.prev {\n left: 7px;\n}\n.next {\n right: 7px;\n}\n\n.gallery {\n width: 390px;\n overflow: hidden;\n}\n\n.gallery ul {\n height: 130px;\n width: 9999px;\n margin: 0;\n padding: 0;\n list-style: none;\n transition: margin-left 250ms;\n}\n\n.gallery li {\n display: inline-block;\n}", "_id" : { "$oid" : "54c29c38f1f6dbff33a7930a" } }, { "filename" : "index.html", "content" : "\n\n \n \n\n\n\n\n
    \n \n
    \n
      \n
    • \n
    • \n
    • \n
    • \n
    • \n
    • \n
    • \n
    • \n
    • \n
    • \n
    \n
    \n \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c38f1f6dbff33a7930b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c38f1f6dbff33a7930c" }, "plunkId" : "Map1RiS7QZbzgyVXtTtc", "webPath" : "/task/carousel/source", "files" : [ { "filename" : "index.html", "content" : "\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c38f1f6dbff33a7930d" } }, { "filename" : "style.css", "content" : ".arrow {\n padding: 0;\n background: #ddd;\n border-radius: 15px;\n border: 1px solid gray;\n font-size: 24px;\n line-height: 24px;\n color: #444;\n display: block;\n}\n\n.arrow:focus {\n outline: none;\n}\n\n.arrow:hover {\n background: #ccc;\n cursor: pointer;\n}\n\nul {\n height: 130px;\n width: 9999px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\nul img {\n width: 130px;\n height: 130px;\n /* по умолчанию inline, но в ряде браузеров это даст лишнее пространство вокруг элементов */\n display: block;\n}\n\nul li {\n /* если в HTML между элементами
  • ..
  • есть пробелы, то они будут видны на странице,\n чтобы их избежать, нужно либо писать
  • ..
  • ..
  • вплотную, либо не ставить закрывающие */\n display: inline-block;\n}", "_id" : { "$oid" : "54ca84aa9b063897722659d7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 1 },{ "_id" : { "$oid" : "54c29c39f1f6dbff33a79311" }, "plunkId" : "ZYzc1F2NIdXnwgUtE742", "webPath" : "/task/move-ball-field/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n Кликните на любое место поля, чтобы мяч перелетел туда.
    \n\n\n
    \n \n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
    \n\n \n\n\n", "_id" : { "$oid" : "54c29c39f1f6dbff33a79312" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3af1f6dbff33a79313" }, "plunkId" : "9QPslRxNlMbDjXfA9laf", "webPath" : "/task/move-ball-field/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\nКликните на любое место поля, чтобы мяч перелетел туда.
    \nМяч никогда не вылетит за границы поля.\n\n\n
    \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c3af1f6dbff33a79314" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3af1f6dbff33a79316" }, "plunkId" : "k2HMXq6i69Zqjt57OU3d", "webPath" : "/article/event-bubbling/both", "files" : [ { "filename" : "script.js", "content" : "var elems = document.querySelectorAll('form,div,p');\n\nfor(var i=0; i\n\n\n \n \n\n\n\n
    FORM\n
    DIV\n

    P

    \n
    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c3af1f6dbff33a79319" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3af1f6dbff33a7931a" }, "plunkId" : "ybtdPlaEtabgI3PMAJf3", "webPath" : "/article/event-bubbling/bubble-target", "files" : [ { "filename" : "script.js", "content" : "var form = document.querySelector('form');\n\nform.onclick = function(event) {\n event.target.style.backgroundColor = 'yellow';\n\n alert(\"target = \" + event.target.tagName + \", this=\" + this.tagName);\n\n event.target.style.backgroundColor = '';\n};", "_id" : { "$oid" : "54c29c3af1f6dbff33a7931b" } }, { "filename" : "example.css", "content" : "form {\n background-color: green;\n position: relative;\n width: 150px;\n height: 150px;\n text-align: center;\n cursor: pointer;\n}\n\ndiv {\n background-color: blue;\n position: absolute;\n top: 25px;\n left: 25px;\n width: 100px;\n height: 100px;\n}\n\np {\n background-color: red;\n position: absolute;\n top: 25px;\n left: 25px;\n width: 50px;\n height: 50px;\n line-height: 50px;\n margin: 0;\n}\n\nbody {\n line-height: 25px;\n font-size: 16px;\n}", "_id" : { "$oid" : "54c29c3af1f6dbff33a7931c" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\nКлик выведет event.target и this:\n\n
    FORM\n
    DIV\n

    P

    \n
    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c3af1f6dbff33a7931d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3bf1f6dbff33a7931e" }, "plunkId" : "IZh7DWcFn9ejxqOymYfR", "webPath" : "/article/event-bubbling/capture", "files" : [ { "filename" : "script.js", "content" : "var elems = document.querySelectorAll('form,div,p');\n\nfor(var i=0; i\n\n\n\n\n
    FORM\n
    DIV\n

    P

    \n
    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c3bf1f6dbff33a79321" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3bf1f6dbff33a79324" }, "plunkId" : "Ss33BkIloiBkp0HqHoCe", "webPath" : "/task/hide-message-delegate/solution", "files" : [ { "filename" : "messages.css", "content" : "body {\n\tmargin: 10px auto;\n\twidth: 470px;\n}\n\nh3 {\n\tmargin: 0;\n\tpadding-bottom: .3em;\n\tpadding-right: 20px;\n\tfont-size: 1.1em;\n}\n\np {\n\tmargin: 0;\n\tpadding: 0 0 .5em;\n}\n\n.pane {\n\tbackground: #edf5e1;\n\tpadding: 10px 20px 10px;\n\tborder-top: solid 2px #c4df9b;\n position: relative;\n}\n\n.remove-button {\n position: absolute;\n font-size: 110%;\n top: 0;\n color: red;\n right: 10px;\n display: block;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n cursor: pointer;\n}", "_id" : { "$oid" : "54c29c3bf1f6dbff33a79325" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
    \n
    \n

    Лошадь

    \n

    Домашняя лошадь — животное семейства непарнокопытных, одомашненный и единственный сохранившийся подвид дикой лошади, вымершей в дикой природе, за исключением небольшой популяции лошади Пржевальского.

    \n \n
    \n
    \n

    Осёл

    \n

    Домашний осёл или ишак — одомашненный подвид дикого осла, сыгравший важную историческую роль в развитии хозяйства и культуры человека. Все одомашненные ослы относятся к африканским ослам.

    \n \n
    \n
    \n

    Корова, а также пара слов о диком быке, о волах и о тёлках.

    \n

    Коро́ва — самка домашнего быка, одомашненного подвида дикого быка, парнокопытного жвачного животного семейства полорогих. Самцы вида называются быками, молодняк — телятами, кастрированные самцы — волами. Молодых (до первой стельности) самок называют тёлками.

    \n \n
    \n
    \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c3bf1f6dbff33a79326" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3bf1f6dbff33a79327" }, "plunkId" : "LSi00MiGBxSaYDDQgd3P", "webPath" : "/task/hide-message-delegate/source", "files" : [ { "filename" : "messages.css", "content" : "body {\n\tmargin: 10px auto;\n\twidth: 470px;\n}\n\nh3 {\n\tmargin: 0;\n\tpadding-bottom: .3em;\n\tfont-size: 1.1em;\n}\n\np {\n\tmargin: 0;\n\tpadding: 0 0 .5em;\n}\n\n.pane {\n\tbackground: #edf5e1;\n\tpadding: 10px 20px 10px;\n\tborder-top: solid 2px #c4df9b;\n}\n\n.remove-button {\n font-size: 110%;\n color: red;\n right: 10px;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n cursor: pointer;\n}", "_id" : { "$oid" : "54c29c3bf1f6dbff33a79328" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\nКнопка для удаления: \n\n
    \n\t
    \n

    Лошадь

    \n

    Домашняя лошадь — животное семейства непарнокопытных, одомашненный и единственный сохранившийся подвид дикой лошади, вымершей в дикой природе, за исключением небольшой популяции лошади Пржевальского.

    \n\t
    \n\t
    \n

    Осёл

    \n

    Домашний осёл или ишак — одомашненный подвид дикого осла, сыгравший важную историческую роль в развитии хозяйства и культуры человека. Все одомашненные ослы относятся к африканским ослам.

    \n\t
    \n\t
    \n

    Корова, а также пара слов о диком быке, о волах и о тёлках.

    \n

    Коро́ва — самка домашнего быка, одомашненного подвида дикого быка, парнокопытного жвачного животного семейства полорогих. Самцы вида называются быками, молодняк — телятами, кастрированные самцы — волами. Молодых (до первой стельности) самок называют тёлками.

    \n\t
    \n
    \n\n\n", "_id" : { "$oid" : "54c29c3bf1f6dbff33a79329" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3cf1f6dbff33a7932b" }, "plunkId" : "McFhdgI8SpvL6BK4ySVC", "webPath" : "/task/sliding-tree/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
      \n
    • Животные\n
        \n
      • Млекопитающие\n
          \n
        • Коровы
        • \n
        • Ослы
        • \n
        • Собаки
        • \n
        • Тигры
        • \n
        \n
      • \n
      • Другие\n
          \n
        • Змеи
        • \n
        • Птицы
        • \n
        • Ящерицы
        • \n
        \n
      • \n
      \n
    • \n
    • Рыбы\n
        \n
      • Аквариумные\n
          \n
        • Гуппи
        • \n
        • Скалярии
        • \n
        \n\n
      • \n
      • Морские\n
          \n
        • Морская форель
        • \n
        \n
      • \n
      \n
    • \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c3cf1f6dbff33a7932c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3cf1f6dbff33a7932d" }, "plunkId" : "tXVJR4Y0iPXDBaAKQTHN", "webPath" : "/task/sliding-tree/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n
      \n
    • Животные\n
        \n
      • Млекопитающие\n
          \n
        • Коровы
        • \n
        • Ослы
        • \n
        • Собаки
        • \n
        • Тигры
        • \n
        \n
      • \n
      • Другие\n
          \n
        • Змеи
        • \n
        • Птицы
        • \n
        • Ящерицы
        • \n
        \n
      • \n
      \n
    • \n
    • Рыбы\n
        \n
      • Аквариумные\n
          \n
        • Гуппи
        • \n
        • Скалярии
        • \n
        \n\n
      • \n
      • Морские\n
          \n
        • Морская форель
        • \n
        \n
      • \n
      \n
    • \n
    \n\n\n", "_id" : { "$oid" : "54c29c3cf1f6dbff33a7932e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3cf1f6dbff33a79330" }, "plunkId" : "PO5epWLVmbmzDU2XNf16", "webPath" : "/task/sort-table/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    ВозрастИмя
    5Вася
    2Петя
    12Женя
    9Маша
    1Илья
    \n\n \n\n \n", "_id" : { "$oid" : "54c29c3cf1f6dbff33a79331" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3df1f6dbff33a79332" }, "plunkId" : "r6HRlPub5Ex3KL6MmT3K", "webPath" : "/task/sort-table/source", "files" : [ { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    ВозрастИмя
    5Вася
    2Петя
    12Женя
    9Маша
    1Илья
    \n\n \n\n \n", "_id" : { "$oid" : "54c29c3df1f6dbff33a79333" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3df1f6dbff33a79334" }, "plunkId" : "ANqCTSCSgFYTrWdW5S6l", "webPath" : "/article/event-delegation/bagua", "files" : [ { "filename" : "bagua.css", "content" : "#bagua-table th {\n\ttext-align: center;\n\tfont-weight: bold;\n}\n\n#bagua-table td {\n\twidth: 150px;\n\twhite-space: nowrap;\n\ttext-align: center;\n\tvertical-align: bottom;\n\tpadding-top: 5px;\n\tpadding-bottom: 12px;\n}\n\n#bagua-table .nw {\n\tbackground: #999;\n}\n\n#bagua-table .n {\n\tbackground: #03f;\n\tcolor: #fff;\n}\n\n#bagua-table .ne {\n\tbackground: #ff6;\n}\n\n#bagua-table .w {\n\tbackground: #ff0;\n}\n#bagua-table .c {\n\tbackground: #60c;\n\tcolor: #fff;\n}\n#bagua-table .e {\n\tbackground: #09f;\n\tcolor: #fff;\n}\n\n#bagua-table .sw {\n\tbackground: #963;\n\tcolor: #fff;\n}\n\n#bagua-table .s {\n\tbackground: #f60;\n\tcolor: #fff;\n}\n#bagua-table .se {\n\tbackground: #0c3;\n\tcolor: #fff;\n}\n\n#bagua-table .highlight {\n\tbackground: red;\n}", "_id" : { "$oid" : "54c29c3df1f6dbff33a79335" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c3df1f6dbff33a79336" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3ef1f6dbff33a7933b" }, "plunkId" : "WrzW7T14VFftvLilxSJi", "webPath" : "/task/catch-link-navigation/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n #contents\n

    \n Как насчет почитать Википедию, или посетить W3.org и узнать про современные стандарты?\n

    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c3ef1f6dbff33a7933c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3ef1f6dbff33a7933d" }, "plunkId" : "ytRaOhIjaCmCvrPTWCcT", "webPath" : "/task/catch-link-navigation/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n #contents\n

    \n Как насчет почитать Википедию, или посетить W3.org и узнать про современные стандарты?\n

    \n
    \n\n\n", "_id" : { "$oid" : "54c29c3ef1f6dbff33a7933e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3ff1f6dbff33a79340" }, "plunkId" : "iMTFZ2lpulXhAdGYCWsR", "webPath" : "/task/image-gallery/solution", "files" : [ { "filename" : "gallery.css", "content" : "body {\n\tmargin: 0;\n\tpadding: 0;\n\tfont: 75%/120% Arial, Helvetica, sans-serif;\n}\n\nh2 {\n\tfont: bold 190%/100% Arial, Helvetica, sans-serif;\n\tmargin: 0 0 .2em;\n}\nh2 em {\n\tfont: normal 80%/100% Arial, Helvetica, sans-serif;\n\tcolor: #999999;\n}\n\n#largeImg {\n\tborder: solid 1px #ccc;\n\twidth: 550px;\n\theight: 400px;\n\tpadding: 5px;\n}\n\n#thumbs a {\n\tborder: solid 1px #ccc;\n\twidth: 100px;\n\theight: 100px;\n\tpadding: 3px;\n\tmargin: 2px;\n\tfloat: left;\n}\n\n#thumbs a:hover {\n\tborder-color: #FF9900;\n}\n\n#thumbs li {\n\tlist-style: none;\n}\n\n#thumbs {\n\tmargin: 0;\n\tpadding: 0;\n}", "_id" : { "$oid" : "54c29c3ff1f6dbff33a79341" } }, { "filename" : "index.html", "content" : "\n\n\n Галерея\n \n \n\n\n\n\n

    \"Large

    \n\n
      \n \n
    • \n
    • \n
    • \n
    • \n
    • \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c3ff1f6dbff33a79342" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c3ff1f6dbff33a79343" }, "plunkId" : "TTczb80AcoFvF4opmbuR", "webPath" : "/task/image-gallery/source", "files" : [ { "filename" : "gallery.css", "content" : "body {\n\tmargin: 0;\n\tpadding: 0;\n\tfont: 75%/120% Arial, Helvetica, sans-serif;\n}\n\nh2 {\n\tfont: bold 190%/100% Arial, Helvetica, sans-serif;\n\tmargin: 0 0 .2em;\n}\nh2 em {\n\tfont: normal 80%/100% Arial, Helvetica, sans-serif;\n\tcolor: #999999;\n}\n\n#largeImg {\n\tborder: solid 1px #ccc;\n\twidth: 550px;\n\theight: 400px;\n\tpadding: 5px;\n}\n\n#thumbs a {\n\tborder: solid 1px #ccc;\n\twidth: 100px;\n\theight: 100px;\n\tpadding: 3px;\n\tmargin: 2px;\n\tfloat: left;\n}\n\n#thumbs a:hover {\n\tborder-color: #FF9900;\n}", "_id" : { "$oid" : "54c29c3ff1f6dbff33a79344" } }, { "filename" : "index.html", "content" : "\n\n\n Галерея\n \n \n\n\n\n\n

    \"Large

    \n\n
    \n \n \n \n \n \n \n
    \n\n\n", "_id" : { "$oid" : "54c29c3ff1f6dbff33a79345" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c40f1f6dbff33a79346" }, "plunkId" : "RztbodzfPhwOYYKvEWNM", "webPath" : "/article/default-browser-action/menu", "files" : [ { "filename" : "menu.js", "content" : "menu.onclick = function(event) {\n if (event.target.nodeName != 'A') return;\n\n var href = event.target.getAttribute('href');\n alert(href);\n\n return false; // prevent url change\n};", "_id" : { "$oid" : "54c29c40f1f6dbff33a79347" } }, { "filename" : "menu.css", "content" : ".menu li {\n display: inline-block;\n margin: 0;\n}\n\n.menu > li a {\n display: inline-block;\n margin: 0 2px;\n outline: none;\n text-align: center;\n text-decoration: none;\n font: 14px/100% Arial, Helvetica, sans-serif;\n padding: .5em 2em .55em;\n text-shadow: 0 1px 1px rgba(0,0,0,.3);\n border-radius: .5em;\n box-shadow: 0 1px 2px rgba(0,0,0,.2);\n color: #d9eef7;\n border: solid 1px #0076a3;\n background: #0095cd;\n}\n\n.menu > li:hover a {\n text-decoration: none;\n background: #007ead;\n}", "_id" : { "$oid" : "54c29c40f1f6dbff33a79348" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c40f1f6dbff33a79349" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c40f1f6dbff33a7934f" }, "plunkId" : "MSUH2IAa3NkMmgYxBMs0", "webPath" : "/task/selectable-list/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nКлик на элементе выделяет только его.
    \nCtrl(Cmd)+Клик добавляет/убирает элемент из выделенных.
    \nShift+Клик добавляет промежуток от последнего кликнутого к выделению.
    \n\n
      \n
    • Кристофер Робин
    • \n
    • Винни-Пух
    • \n
    • Ослик Иа
    • \n
    • Мудрая Сова
    • \n
    • Кролик. Просто кролик.
    • \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c40f1f6dbff33a79350" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c40f1f6dbff33a79351" }, "plunkId" : "PnXqimXD4ulrI49rGkuv", "webPath" : "/task/selectable-list/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nКлик на элементе выделяет только его.
    \nCtrl(Cmd)+Клик добавляет/убирает элемент из выделенных.
    \nShift+Клик добавляет промежуток от последнего кликнутого к выделению.
    \n\n
      \n
    • Кристофер Робин
    • \n
    • Винни-Пух
    • \n
    • Ослик Иа
    • \n
    • Мудрая Сова
    • \n
    • Кролик. Просто кролик.
    • \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c41f1f6dbff33a79355" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c41f1f6dbff33a79356" }, "plunkId" : "xeqqkupe3lp8wSxLeg9I", "webPath" : "/task/tree-coords/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
      \n
    • Животные\n
        \n
      • Млекопитающие\n
          \n
        • Коровы
        • \n
        • Ослы
        • \n
        • Собаки
        • \n
        • Тигры
        • \n
        \n
      • \n
      • Другие\n
          \n
        • Змеи
        • \n
        • Птицы
        • \n
        • Ящерицы
        • \n
        \n
      • \n
      \n
    • \n
    • Рыбы\n
        \n
      • Аквариумные\n
          \n
        • Гуппи
        • \n
        • Скалярии
        • \n
        \n\n
      • \n
      • Морские\n
          \n
        • Морская форель
        • \n
        \n
      • \n
      \n
    • \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c41f1f6dbff33a79357" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c41f1f6dbff33a7935b" }, "plunkId" : "1QW6v03d6tA5TZUNOFH0", "webPath" : "/article/onload-ondomcontentloaded/window-onbeforeunload", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\nУйти на EXAMPLE.COM\n\n", "_id" : { "$oid" : "54c29c41f1f6dbff33a7935c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c42f1f6dbff33a79362" }, "plunkId" : "9qV9F3JEiZW1M797vdT1", "webPath" : "/task/nice-alt/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
    \n
    \nGoogle\n
    \n\n
    \nЯндекс\n
    \n\n
    bing
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c42f1f6dbff33a79363" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c42f1f6dbff33a79364" }, "plunkId" : "oSeqv0T67Hu7pn6cdGUu", "webPath" : "/task/nice-alt/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n
    \nGoogle\n
    \n\n\n
    \nЯндекс\n
    \n\n\n
    bing
    \n\n
    \n\n\n\"Яндекс\"\n\"Google\"\n\"Файла\n\n\n\n", "_id" : { "$oid" : "54c29c42f1f6dbff33a79365" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c42f1f6dbff33a79367" }, "plunkId" : "PuxdnR92UmaYasp6VysD", "webPath" : "/task/load-img-callback/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c42f1f6dbff33a79368" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c43f1f6dbff33a79369" }, "plunkId" : "q4WRIILEvuwdz8Zf3A85", "webPath" : "/task/load-img-callback/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c43f1f6dbff33a7936a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c44f1f6dbff33a7936c" }, "plunkId" : "ZmiGiDhet3Nlr5xUtTRM", "webPath" : "/task/script-callback/solution", "files" : [ { "filename" : "go.js", "content" : "function go () {\n alert(\"ok\");\n}", "_id" : { "$oid" : "54c29c44f1f6dbff33a7936d" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c44f1f6dbff33a7936e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c44f1f6dbff33a7936f" }, "plunkId" : "wGuQwHBnhvTCRGgQsnz0", "webPath" : "/task/script-callback/source", "files" : [ { "filename" : "go.js", "content" : "function go() {\n alert(\"ok\");\n}", "_id" : { "$oid" : "54c29c44f1f6dbff33a79370" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c44f1f6dbff33a79371" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c44f1f6dbff33a79373" }, "plunkId" : "hdxbKLcRPrdlys1kRyjW", "webPath" : "/task/scripts-callback/solution", "files" : [ { "filename" : "a.js", "content" : "function a() {\n b();\n}", "_id" : { "$oid" : "54c29c44f1f6dbff33a79374" } }, { "filename" : "b.js", "content" : "function b() {\n c();\n}", "_id" : { "$oid" : "54c29c44f1f6dbff33a79375" } }, { "filename" : "c.js", "content" : "function c() {\n alert('ok');\n}", "_id" : { "$oid" : "54c29c44f1f6dbff33a79376" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c44f1f6dbff33a79377" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c45f1f6dbff33a79378" }, "plunkId" : "1mEW36n1ZAg2rOqsKZYZ", "webPath" : "/task/scripts-callback/source", "files" : [ { "filename" : "a.js", "content" : "function a() {\n b();\n}", "_id" : { "$oid" : "54c29c45f1f6dbff33a79379" } }, { "filename" : "b.js", "content" : "function b() {\n c();\n}", "_id" : { "$oid" : "54c29c45f1f6dbff33a7937a" } }, { "filename" : "c.js", "content" : "function c() {\n alert('ok');\n}", "_id" : { "$oid" : "54c29c45f1f6dbff33a7937b" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c45f1f6dbff33a7937c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c46f1f6dbff33a79381" }, "plunkId" : "FpigwJsDvfAPZtsgSQ8k", "webPath" : "/task/behavior-tooltip/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n

    ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

    \n

    ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

    \n\n\n\n\n

    Прокрутите страницу, чтобы ссылки были вверху и проверьте, правильно ли показываются подсказки.

    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c46f1f6dbff33a79382" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c46f1f6dbff33a79383" }, "plunkId" : "BbNrjEzd5F638zLUy3zc", "webPath" : "/task/behavior-tooltip/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n

    ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

    \n

    ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

    \n\n\n\n\n

    Прокрутите страницу, чтобы ссылки были вверху и проверьте, правильно ли показываются подсказки.

    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c46f1f6dbff33a79384" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c46f1f6dbff33a79386" }, "plunkId" : "lXLTLsUm8chrLSg3Rk9z", "webPath" : "/task/behavior-nested-tooltip/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
    \n
    \n\n

    Жили-были на свете три поросёнка. Три брата.

    \n\n

    Все одинакового роста, кругленькие, розовые, с одинаковыми весёлыми хвостиками.

    \n\n

    Даже имена у них были похожи. Звали поросят Ниф-Ниф, Нуф-Нуф и Наф-Наф. Всё лето они кувыркались в зелёной траве, грелись на солнышке, нежились в лужах.

    \n\n

    Но вот наступила осень. Наведи на меня

    \n\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c46f1f6dbff33a79387" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c46f1f6dbff33a79388" }, "plunkId" : "Ag723y2l6pUypiXiSopI", "webPath" : "/task/behavior-nested-tooltip/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
    \n
    \n\n

    Жили-были на свете три поросёнка. Три брата.

    \n\n

    Все одинакового роста, кругленькие, розовые, с одинаковыми весёлыми хвостиками.

    \n\n

    Даже имена у них были похожи. Звали поросят Ниф-Ниф, Нуф-Нуф и Наф-Наф. Всё лето они кувыркались в зелёной траве, грелись на солнышке, нежились в лужах.

    \n\n

    Но вот наступила осень. Наведи на меня

    \n\n
    \n\n\n", "_id" : { "$oid" : "54c29c46f1f6dbff33a79389" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c47f1f6dbff33a7938a" }, "plunkId" : "WcyPiMnnsZrBZW2lLLhc", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2", "files" : [ { "filename" : "script.js", "content" : "// элемент TD, внутри которого сейчас курсор\nvar currentElem = null;\n\ntable.onmouseover = function(event) {\n if (currentElem) {\n // перед тем, как зайти в новый элемент, курсор всегда выходит из предыдущего\n //\n // если мы еще не вышли, значит это переход внутри элемента, отфильтруем его\n return;\n }\n\n // посмотрим, куда пришёл курсор\n var target = event.target;\n\n // уж не на TD ли?\n while (target != this) {\n if (target.tagName == 'TD') break;\n target = target.parentNode;\n }\n if (target == this) return;\n\n // да, элемент перешёл внутрь TD!\n currentElem = target;\n target.style.background = 'pink';\n};\n\n\ntable.onmouseout = function(event) {\n // если курсор и так снаружи - игнорируем это событие\n if (!currentElem) return;\n\n // произошёл уход с элемента - проверим, куда, может быть на потомка?\n var relatedTarget = event.relatedTarget;\n if (relatedTarget) { // может быть relatedTarget = null\n while(relatedTarget) {\n // идём по цепочке родителей и проверяем,\n // если переход внутрь currentElem - игнорируем это событие\n if (relatedTarget == currentElem) return;\n relatedTarget = relatedTarget.parentNode;\n }\n }\n\n // произошло событие mouseout, курсор ушёл\n currentElem.style.background = '';\n currentElem = null;\n};", "_id" : { "$oid" : "54c29c47f1f6dbff33a7938b" } }, { "filename" : "style.css", "content" : "#text {\n display: block;\n height:100px;\n width:400px;\n}\n\n#table th {\n text-align: center;\n font-weight: bold;\n}\n\n#table td {\n width: 150px;\n white-space: nowrap;\n text-align: center;\n vertical-align: bottom;\n padding-top: 5px;\n padding-bottom: 12px;\n}\n\n#table .nw {\n background: #999;\n}\n\n#table .n {\n background: #03f;\n color: #fff;\n}\n\n#table .ne {\n background: #ff6;\n}\n\n#table .w {\n background: #ff0;\n}\n#table .c {\n background: #60c;\n color: #fff;\n}\n#table .e {\n background: #09f;\n color: #fff;\n}\n\n#table .sw {\n background: #963;\n color: #fff;\n}\n\n#table .s {\n background: #f60;\n color: #fff;\n}\n#table .se {\n background: #0c3;\n color: #fff;\n}\n\n#table .highlight {\n background: red;\n}", "_id" : { "$oid" : "54c29c47f1f6dbff33a7938c" } }, { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n \n\n \n\n\n \n\n \n", "_id" : { "$oid" : "54c29c47f1f6dbff33a7938d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c47f1f6dbff33a7938e" }, "plunkId" : "tXgpQbG8hTU7PJBtZhs1", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation", "files" : [ { "filename" : "script.js", "content" : "table.onmouseover = function(event) {\n var target = event.target;\n target.style.background = 'pink';\n text.value += \"mouseover \" + target.tagName + \"\\n\";\n};\n\ntable.onmouseout = function(event) {\n var target = event.target;\n target.style.background = '';\n text.value += \"mouseout \" + target.tagName + \"\\n\";\n};", "_id" : { "$oid" : "54c29c47f1f6dbff33a7938f" } }, { "filename" : "style.css", "content" : "#text {\n display: block;\n height:100px;\n width:400px;\n}\n\n#table th {\n text-align: center;\n font-weight: bold;\n}\n\n#table td {\n width: 150px;\n white-space: nowrap;\n text-align: center;\n vertical-align: bottom;\n padding-top: 5px;\n padding-bottom: 12px;\n}\n\n#table .nw {\n background: #999;\n}\n\n#table .n {\n background: #03f;\n color: #fff;\n}\n\n#table .ne {\n background: #ff6;\n}\n\n#table .w {\n background: #ff0;\n}\n#table .c {\n background: #60c;\n color: #fff;\n}\n#table .e {\n background: #09f;\n color: #fff;\n}\n\n#table .sw {\n background: #963;\n color: #fff;\n}\n\n#table .s {\n background: #f60;\n color: #fff;\n}\n#table .se {\n background: #0c3;\n color: #fff;\n}\n\n#table .highlight {\n background: red;\n}", "_id" : { "$oid" : "54c29c47f1f6dbff33a79390" } }, { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n \n\n \n\n\n \n\n \n", "_id" : { "$oid" : "54c29c47f1f6dbff33a79391" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c47f1f6dbff33a79392" }, "plunkId" : "4jXwIXjuwCkuEVEVOOts", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseleave-table", "files" : [ { "filename" : "script.js", "content" : "table.onmouseenter = table.onmouseleave = log;\n\nfunction log(event) {\n text.value += event.type+' [target: '+event.target.tagName+']\\n';\n text.scrollTop = text.scrollHeight;\n}", "_id" : { "$oid" : "54c29c47f1f6dbff33a79393" } }, { "filename" : "style.css", "content" : "#text {\n display: block;\n height:100px;\n width:400px;\n}\n\n#table th {\n text-align: center;\n font-weight: bold;\n}\n\n#table td {\n width: 150px;\n white-space: nowrap;\n text-align: center;\n vertical-align: bottom;\n padding-top: 5px;\n padding-bottom: 12px;\n}\n\n#table .nw {\n background: #999;\n}\n\n#table .n {\n background: #03f;\n color: #fff;\n}\n\n#table .ne {\n background: #ff6;\n}\n\n#table .w {\n background: #ff0;\n}\n#table .c {\n background: #60c;\n color: #fff;\n}\n#table .e {\n background: #09f;\n color: #fff;\n}\n\n#table .sw {\n background: #963;\n color: #fff;\n}\n\n#table .s {\n background: #f60;\n color: #fff;\n}\n#table .se {\n background: #0c3;\n color: #fff;\n}\n\n#table .highlight {\n background: red;\n}", "_id" : { "$oid" : "54c29c47f1f6dbff33a79394" } }, { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n \n\n \n\n\n \n\n \n", "_id" : { "$oid" : "54c29c47f1f6dbff33a79395" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c48f1f6dbff33a79396" }, "plunkId" : "i4kNFDGouatMe7A9X6tA", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseleave", "files" : [ { "filename" : "script.js", "content" : "function log(event) {\n text.value += event.type+' [target: '+event.target.className+']\\n';\n text.scrollTop = text.scrollHeight;\n}", "_id" : { "$oid" : "54c29c48f1f6dbff33a79397" } }, { "filename" : "style.css", "content" : "#blue {\n background:blue;\n width:160px;\n height:160px;\n position:relative;\n}\n\n#red {\n background:red;\n width:70px;\n height:70px;\n position:absolute;\n left:20px;\n top:20px;\n}\n\n#text {\n display: block;\n height:100px;\n width:400px;\n}", "_id" : { "$oid" : "54c29c48f1f6dbff33a79398" } }, { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n\n
    \n
    \n
    \n\n \n \n\n \n\n \n", "_id" : { "$oid" : "54c29c48f1f6dbff33a79399" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c48f1f6dbff33a7939a" }, "plunkId" : "LVkW66GKx1RAOhLKJ3Si", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-child", "files" : [ { "filename" : "script.js", "content" : "function mouselog(event) {\n text.value += event.type+' [target: '+event.target.className+']\\n'\n text.scrollTop = text.scrollHeight\n}", "_id" : { "$oid" : "54c29c48f1f6dbff33a7939b" } }, { "filename" : "style.css", "content" : ".blue {\n background:blue;\n width:160px;\n height:160px;\n position:relative;\n}\n\n.red {\n background:red;\n width:100px;\n height:100px;\n position:absolute;\n left:30px;\n top:30px;\n}\n\ntextarea {\n height:100px;\n width:400px;\n display: block;\n}", "_id" : { "$oid" : "54c29c48f1f6dbff33a7939c" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n
    \n
    \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c48f1f6dbff33a7939d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c48f1f6dbff33a7939e" }, "plunkId" : "dPARAnHkOvQOi7s4HPXJ", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast", "files" : [ { "filename" : "script.js", "content" : " green.onmouseover = green.onmouseout = green.onmousemove = handler;\n\n function handler(event) {\n var type = event.type;\n while (type < 11) type += ' ';\n\n log(type + \" target=\" + event.target.id)\n return false;\n }\n\n\nfunction clearText() {\n text.value = \"\";\n lastMessage = \"\";\n}\n\nvar lastMessageTime = 0;\nvar lastMessage = \"\";\nvar repeatCounter = 1;\nfunction log(message) {\n if (lastMessageTime == 0) lastMessageTime = new Date();\n\n var time = new Date();\n\n if (time - lastMessageTime > 500) {\n message = '------------------------------\\n' + message;\n }\n\n if (message === lastMessage) {\n repeatCounter++;\n if (repeatCounter == 2) {\n text.value = text.value.trim() + ' x 2\\n';\n } else {\n text.value = text.value.slice(0, text.value.lastIndexOf('x') + 1) + repeatCounter + \"\\n\";\n }\n\n } else {\n repeatCounter = 1;\n text.value += message + \"\\n\";\n }\n\n text.scrollTop = text.scrollHeight;\n\n lastMessageTime = time;\n lastMessage = message;\n}", "_id" : { "$oid" : "54c29c48f1f6dbff33a7939f" } }, { "filename" : "style.css", "content" : "#green {\n height: 50px;\n width: 160px;\n background: green;\n}\n\n#red {\n height: 20px;\n width: 110px;\n background: red;\n color: white;\n font-weight: bold;\n padding: 5px;\n text-align: center;\n margin: 20px;\n}\n\n#text {\n font-size: 12px;\n height: 200px;\n width: 360px;\n display: block;\n}", "_id" : { "$oid" : "54c29c48f1f6dbff33a793a0" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n
    Тест
    \n
    \n\n \n\n \n\n \n\n\n", "_id" : { "$oid" : "54c29c48f1f6dbff33a793a1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c49f1f6dbff33a793a2" }, "plunkId" : "ip7h0ARkrCPc4aMzR5Wd", "webPath" : "/article/mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout", "files" : [ { "filename" : "script.js", "content" : "document.body.onmouseover = document.body.onmouseout = handler;\n\nfunction handler(event) {\n\n function str(el) {\n if (!el) return \"null\"\n return el.className || el.tagName;\n }\n\n log.value += event.type + ': ' +\n 'target=' + str(event.target) +\n ', relatedTarget=' + str(event.relatedTarget) + \"\\n\";\n log.scrollTop = 1e9;\n\n if (event.type == 'mouseover') {\n event.target.style.background = 'pink'\n }\n if (event.type == 'mouseout') {\n event.target.style.background = ''\n }\n}", "_id" : { "$oid" : "54c29c49f1f6dbff33a793a3" } }, { "filename" : "style.css", "content" : "body, html {\n height: 130px;\n margin: 0;\n padding: 0;\n}\n\n[class^=\"smiley-\"]{\n display: inline-block;\n width:70px;\n height:70px;\n border-radius:50%;\n margin-right:20px;\n}\n.smiley-green{\n background:#a9db7a;\n border:5px solid #92c563;\n position: relative;\n}\n.smiley-green .left-eye{\n width:18%;\n height:18%;\n background:#84b458;\n position:relative;\n top:29%;\n left:22%;\n border-radius:50%;\n float: left;\n}\n.smiley-green .right-eye{\n width:18%;\n height:18%;\n border-radius:50%;\n position:relative;\n background:#84b458;\n top: 29%;\n right: 22%;\n float: right;\n}\n.smiley-green .smile{\n position: absolute;\n top:67%;\n left:16.5%;\n width:70%;\n height:20%;\n overflow: hidden;\n}\n .smiley-green .smile:after, .smiley-green .smile:before{\n content:\"\";\n position:absolute;\n top:-50%;\n left:0%;\n border-radius:50%;\n background:#84b458;\n height:100%;\n width:97%;\n }\n .smiley-green .smile:after{\n background: #84b458;\n height: 80%;\n top: -40%;\n left: 0%;\n}\n\n\n.smiley-yellow{\n background:#eed16a;\n border:5px solid #dbae51;\n position: relative;\n}\n.smiley-yellow .left-eye{\n width:18%;\n height:18%;\n background:#dba652;\n position:relative;\n top:29%;\n left:22%;\n border-radius:50%;\n float: left;\n}\n.smiley-yellow .right-eye{\n width:18%;\n height:18%;\n border-radius:50%;\n position:relative;\n background:#dba652;\n top: 29%;\n right: 22%;\n float: right;\n}\n.smiley-yellow .smile{\n position: absolute;\n top:67%;\n left:19%;\n width:65%;\n height:14%;\n background:#dba652;\n overflow: hidden;\n border-radius:8px;\n}\n\n\n.smiley-red{\n background:#ee9295;\n border:5px solid #e27378;\n position: relative;\n}\n.smiley-red .left-eye{\n width:18%;\n height:18%;\n background:#d96065;\n position:relative;\n top:29%;\n left:22%;\n border-radius:50%;\n float: left;\n}\n.smiley-red .right-eye{\n width:18%;\n height:18%;\n border-radius:50%;\n position:relative;\n background:#d96065;\n top: 29%;\n right: 22%;\n float: right;\n}\n.smiley-red .smile{\n position: absolute;\n top:57%;\n left:16.5%;\n width:70%;\n height:20%;\n overflow: hidden;\n}\n .smiley-red .smile:after, .smiley-red .smile:before{\n content:\"\";\n position:absolute;\n top:50%;\n left:0%;\n border-radius:50%;\n background:#d96065;\n height:100%;\n width:97%;\n }\n .smiley-red .smile:after{\n background: #d96065;\n height: 80%;\n top: 60%;\n left: 0%;\n}", "_id" : { "$oid" : "54c29c49f1f6dbff33a793a4" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n\n \n\n\n \n\n\n", "_id" : { "$oid" : "54c29c49f1f6dbff33a793a5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c49f1f6dbff33a793a8" }, "plunkId" : "JZ3ebiRMdHxiCIAEv0jp", "webPath" : "/task/scale-with-mouse-wheel/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n

    \nПри прокрутке колёсика мыши над этим элементом, он будет масштабироваться.\n

    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c49f1f6dbff33a793a9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c49f1f6dbff33a793ab" }, "plunkId" : "GO6AM3OT74ZNKdg72FDl", "webPath" : "/task/no-doc-scroll/solution", "files" : [ { "filename" : "fix-textarea-scroll.js", "content" : "document.onwheel = function(e) {\n if (e.target.tagName != 'TEXTAREA') return;\n var area = e.target;\n\n var delta = e.deltaY || e.detail || e.wheelDelta;\n\n if (delta < 0 && area.scrollTop == 0) {\n e.preventDefault();\n }\n\n if (delta > 0 && area.scrollHeight - area.clientHeight - area.scrollTop <= 1) {\n e.preventDefault();\n }\n};", "_id" : { "$oid" : "54c29c49f1f6dbff33a793ac" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n

    Начало документа

    \n
    \n\n\n\n\n
    \nКонец документа.\n
    \n\n", "_id" : { "$oid" : "54c29c49f1f6dbff33a793ad" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4af1f6dbff33a793ae" }, "plunkId" : "fanfEnKCV6kkfkIxNS2x", "webPath" : "/task/no-doc-scroll/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\t\n\n\n\n
    \n

    Начало документа

    \n
    \n\n\n\n\n
    \nКонец документа.\n
    \n\n", "_id" : { "$oid" : "54c29c4af1f6dbff33a793af" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4af1f6dbff33a793b0" }, "plunkId" : "caro4PBO4ipIS07Mq4Mm", "webPath" : "/article/mousewheel/wheel", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\t\n \n\n\n\nПрокрутка: 0\n
    \nПрокрути надо мной.\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c4af1f6dbff33a793b1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4af1f6dbff33a793b5" }, "plunkId" : "ivdCdW8KxMfx4YwnTk0F", "webPath" : "/task/slider/solution", "files" : [ { "filename" : "lib.js", "content" : "function fixEvent(e) {\n e = e || window.event;\n\n if (!e.target) e.target = e.srcElement;\n\n if (e.pageX == null && e.clientX != null ) { // если нет pageX..\n var html = document.documentElement;\n var body = document.body;\n\n e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);\n e.pageX -= html.clientLeft || 0;\n\n e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);\n e.pageY -= html.clientTop || 0;\n }\n\n if (!e.which && e.button) {\n e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) )\n }\n\n return e;\n}\n\n\nfunction getCoords(elem) {\n var box = elem.getBoundingClientRect();\n\n var body = document.body;\n var docElem = document.documentElement;\n\n var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;\n var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;\n\n var clientTop = docElem.clientTop || body.clientTop || 0;\n var clientLeft = docElem.clientLeft || body.clientLeft || 0;\n\n var top = box.top + scrollTop - clientTop;\n var left = box.left + scrollLeft - clientLeft;\n\n return { top: Math.round(top), left: Math.round(left) };\n}", "_id" : { "$oid" : "54c29c4af1f6dbff33a793b6" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n
    \n
    \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c4af1f6dbff33a793b7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4bf1f6dbff33a793b8" }, "plunkId" : "MQ1nGoG5pHG3GlMrnnnd", "webPath" : "/task/slider/source", "files" : [ { "filename" : "lib.js", "content" : "function fixEvent(e) {\n e = e || window.event;\n\n if (!e.target) e.target = e.srcElement;\n\n if (e.pageX == null && e.clientX != null ) { // если нет pageX..\n var html = document.documentElement;\n var body = document.body;\n\n e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);\n e.pageX -= html.clientLeft || 0;\n\n e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);\n e.pageY -= html.clientTop || 0;\n }\n\n if (!e.which && e.button) {\n e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) )\n }\n\n return e;\n}\n\n\nfunction getCoords(elem) {\n var box = elem.getBoundingClientRect();\n\n var body = document.body;\n var docElem = document.documentElement;\n\n var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;\n var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;\n\n var clientTop = docElem.clientTop || body.clientTop || 0;\n var clientLeft = docElem.clientLeft || body.clientLeft || 0;\n\n var top = box.top + scrollTop - clientTop;\n var left = box.left + scrollLeft - clientLeft;\n\n return { top: Math.round(top), left: Math.round(left) };\n}", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793b9" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793ba" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4bf1f6dbff33a793bc" }, "plunkId" : "NsNM7qK094lNH2FN1DPM", "webPath" : "/task/drag-heroes/solution", "files" : [ { "filename" : "soccer.js", "content" : "document.body.onmousedown = function(e) {\n\n var dragElement = e.target;\n\n if (!dragElement.classList.contains('draggable')) return;\n\n var coords, shiftX, shiftY;\n\n startDrag(e.pageX, e.pageY);\n\n document.onmousemove = function(e) {\n moveAt(e.pageX, e.pageY);\n };\n\n dragElement.onmouseup = function() {\n finishDrag();\n };\n\n\n // -------------------------\n\n function startDrag(pageX, pageY) {\n\n coords = getCoords(dragElement);\n shiftX = pageX - coords.left;\n shiftY = pageY - coords.top;\n\n dragElement.classList.add(\"dragging\");\n dragElement.style.position = 'absolute';\n document.body.appendChild(dragElement);\n\n moveAt(pageX, pageY);\n };\n\n function finishDrag() {\n dragElement.classList.remove('dragging');\n document.onmousemove = dragElement.onmouseup = null;\n }\n\n function moveAt(pageX, pageY) {\n var newX = pageX - shiftX;\n var newY = pageY - shiftY;\n\n var newBottom = newY + dragElement.offsetHeight;\n\n var docScroll = getDocumentScroll();\n\n // прокрутить вниз, если нужно\n if (newBottom > docScroll.bottom) {\n // ...но не за конец документа\n var scrollSizeToEnd = docScroll.height - docScroll.bottom;\n\n // scrollBy, если его не ограничить,\n // может заскроллить за текущую границу страницы\n var toScrollY = Math.min(scrollSizeToEnd, 10);\n window.scrollBy(0, toScrollY );\n\n // при необходимости двигаем элемент вверх, чтобы поместился\n // метод scrollBy асинхронный, поэтому учитываем будущую прокрутку (+toScrollY)\n newY = Math.min(newY, docScroll.bottom - dragElement.offsetHeight + toScrollY);\n }\n\n if (newY < docScroll.top) {\n var toScrollY = Math.min(docScroll.top, 10);\n window.scrollBy(0, -toScrollY );\n newY = Math.max(newY, docScroll.top - toScrollY );\n }\n\n // зажать в границах экрана по горизонтали\n newX = Math.max(newX, 0);\n newX = Math.min(newX, document.documentElement.clientWidth - dragElement.offsetHeight);\n\n dragElement.style.left = newX + 'px';\n dragElement.style.top = newY + 'px';\n }\n\n return false;\n}", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793bd" } }, { "filename" : "soccer.css", "content" : "html, body {\n margin: 0;\n padding: 0;\n}\n\n#field {\n background: url(//js.cx/drag-heroes/field.png);\n width: 800px;\n height: 600px;\n float: left;\n}\n\n.hero {\n background: url(//js.cx/drag-heroes/heroes.png);\n width: 105px;\n height: 128px;\n float: left;\n}\n\n#hero1 {\n background-position: 0 0;\n}\n\n#hero2 {\n background-position: 0 -128px;\n}\n\n#hero3 {\n background-position: -131px 0;\n}\n\n#hero4 {\n background-position: -131px -128px;\n}\n\n#hero5 {\n background-position: -236px 0;\n width: 130px;\n}\n\n#winnie {\n background: url(//js.cx/drag-heroes/winnie.png);\n width: 115px;\n height: 128px;\n float: left;\n}\n\n.draggable {\n cursor: pointer;\n}\n\n.dragging {\n z-index: 1000;\n position: absolute;\n cursor: move;\n}", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793be" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Расставьте супергероев по полю.

    \n\n

    Супергерои -- это элементы с классом \"draggable\". Сделайте так, чтобы их можно было переносить.

    \n\n

    Важно: если супергероя подносят к низу или верху страницы, она должна автоматически прокручиваться. Конечно, можно прокрутить и клавиатурой, но так -- удобнее. Если страница помещается на вашем экране целиком и не имеет вертикальной прокрутки -- сделайте окно браузера меньше, чтобы протестировать эту возможность.

    \n\n

    Да, и ещё: супергерои ни при каких условиях не должны попасть за край экрана.

    \n\n
    \n\n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n\n \n\n
    \n\n \n \n\n \n\n", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793bf" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4bf1f6dbff33a793c0" }, "plunkId" : "RUCdVWzkQdXeqGDeKlW2", "webPath" : "/task/drag-heroes/source", "files" : [ { "filename" : "soccer.js", "content" : "/* ваш код */", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793c1" } }, { "filename" : "soccer.css", "content" : "html, body {\n margin: 0;\n padding: 0;\n}\n\n#field {\n background: url(//js.cx/drag-heroes/field.png);\n width: 800px;\n height: 600px;\n float: left;\n}\n\n.hero {\n background: url(//js.cx/drag-heroes/heroes.png);\n width: 105px;\n height: 128px;\n float: left;\n}\n\n#hero1 {\n background-position: 0 0;\n}\n\n#hero2 {\n background-position: 0 -128px;\n}\n\n#hero3 {\n background-position: -131px 0;\n}\n\n#hero4 {\n background-position: -131px -128px;\n}\n\n#hero5 {\n background-position: -236px 0;\n width: 130px;\n}\n\n#winnie {\n background: url(//js.cx/drag-heroes/winnie.png);\n width: 115px;\n height: 128px;\n float: left;\n}\n\n.draggable {\n cursor: pointer;\n}\n\n.dragging {\n z-index: 1000;\n position: absolute;\n cursor: move;\n}", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793c2" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Расставьте супергероев по полю.

    \n\n

    Супергерои -- это элементы с классом \"draggable\". Сделайте так, чтобы их можно было переносить.

    \n\n

    Важно: если супергероя подносят к низу или верху страницы, она должна автоматически прокручиваться. Конечно, можно прокрутить и клавиатурой, но так -- удобнее. Если страница помещается на вашем экране целиком и не имеет вертикальной прокрутки -- сделайте окно браузера меньше, чтобы протестировать эту возможность.

    \n\n

    Да, и ещё: супергерои ни при каких условиях не должны попасть за край экрана.

    \n\n\n
    \n\n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n\n \n\n
    \n\n \n \n\n \n\n", "_id" : { "$oid" : "54c29c4bf1f6dbff33a793c3" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4cf1f6dbff33a793c5" }, "plunkId" : "AH49yaoOAMDGnuKBG3wH", "webPath" : "/article/drag-and-drop-objects/dragDemo", "files" : [ { "filename" : "DragManager.js", "content" : "var dragManager = new function() {\n\n /**\n * составной объект для хранения информации о переносе:\n * {\n * elem - элемент, на котором была зажата мышь\n * avatar - аватар\n * downX/downY - координаты, на которых был mousedown\n * shiftX/shiftY - относительный сдвиг курсора от угла элемента\n * }\n */\n var dragObject = {};\n\n var self = this;\n\n function onMouseDown(e){\n\n if (e.which != 1) return;\n\n var elem = findDraggable(e);\n if (!elem) return;\n\n dragObject.elem = elem;\n\n // запомним, что элемент нажат на текущих координатах pageX/pageY\n dragObject.downX = e.pageX;\n dragObject.downY = e.pageY;\n\n return false;\n }\n\n function onMouseMove(e) {\n if (!dragObject.elem) return; // элемент не зажат\n\n if ( !dragObject.avatar ) { // если перенос не начат...\n var moveX = e.pageX - dragObject.downX;\n var moveY = e.pageY - dragObject.downY;\n\n // если мышь передвинулась в нажатом состоянии недостаточно далеко\n if ( Math.abs(moveX) < 3 && Math.abs(moveY) < 3 ) {\n return;\n }\n\n // начинаем перенос\n dragObject.avatar = createAvatar(e); // создать аватар\n if (!dragObject.avatar) { // отмена переноса, нельзя \"захватить\" за эту часть элемента\n dragObject = {};\n return;\n }\n\n // аватар создан успешно\n // создать вспомогательные свойства shiftX/shiftY\n var coords = getCoords(dragObject.avatar);\n dragObject.shiftX = dragObject.downX - coords.left;\n dragObject.shiftY = dragObject.downY - coords.top;\n\n startDrag(e); // отобразить начало переноса\n }\n\n // отобразить перенос объекта при каждом движении мыши\n dragObject.avatar.style.left = e.pageX - dragObject.shiftX + 'px';\n dragObject.avatar.style.top = e.pageY - dragObject.shiftY + 'px';\n\n return false;\n }\n\n function onMouseUp(e) {\n if (dragObject.avatar) { // если перенос идет\n finishDrag(e);\n }\n\n // перенос либо не начинался, либо завершился\n // в любом случае очистим \"состояние переноса\" dragObject\n dragObject = {};\n }\n\n function finishDrag(e) {\n var dropElem = findDroppable(e);\n\n if (!dropElem) {\n self.onDragCancel(dragObject);\n } else {\n self.onDragEnd(dragObject, dropElem);\n }\n }\n\n function createAvatar(e) {\n\n // запомнить старые свойства, чтобы вернуться к ним при отмене переноса\n var avatar = dragObject.elem;\n var old = {\n parent: avatar.parentNode,\n nextSibling: avatar.nextSibling,\n position: avatar.position || '',\n left: avatar.left || '',\n top: avatar.top || '',\n zIndex: avatar.zIndex || ''\n };\n\n // функция для отмены переноса\n avatar.rollback = function() {\n old.parent.insertBefore(avatar, old.nextSibling);\n avatar.style.position = old.position;\n avatar.style.left = old.left;\n avatar.style.top = old.top;\n avatar.style.zIndex = old.zIndex\n };\n\n return avatar;\n }\n\n function startDrag(e) {\n var avatar = dragObject.avatar;\n\n // инициировать начало переноса\n document.body.appendChild(avatar);\n avatar.style.zIndex = 9999;\n avatar.style.position = 'absolute';\n }\n\n function findDraggable(event) {\n var elem = event.target;\n while(elem != document && elem.getAttribute('draggable') == null) {\n elem = elem.parentNode;\n }\n return elem == document ? null : elem;\n }\n\n function findDroppable(event) {\n\n var elem = getElementUnderClientXY(dragObject.avatar, event.clientX, event.clientY);\n\n while(elem != document && elem.getAttribute('droppable') == null) {\n elem = elem.parentNode;\n }\n\n return elem == document ? null : elem;\n }\n\n document.onmousemove = onMouseMove;\n document.onmouseup = onMouseUp;\n document.onmousedown = onMouseDown;\n\n this.onDragEnd = function(dragObject, dropElem) { };\n this.onDragCancel = function(dragObject) { };\n\n};", "_id" : { "$oid" : "54c29c4cf1f6dbff33a793c6" } }, { "filename" : "lib.js", "content" : "function getCoords(elem) {\n var box = elem.getBoundingClientRect();\n\n var body = document.body;\n var docElem = document.documentElement;\n\n var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;\n var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;\n\n var clientTop = docElem.clientTop || body.clientTop || 0;\n var clientLeft = docElem.clientLeft || body.clientLeft || 0;\n\n var top = box.top + scrollTop - clientTop;\n var left = box.left + scrollLeft - clientLeft;\n\n return { top: Math.round(top), left: Math.round(left) };\n}\n\nfunction getElementUnderClientXY(elem, clientX, clientY) {\n var display = elem.style.display || '';\n elem.style.display = 'none';\n\n var target = document.elementFromPoint(clientX, clientY);\n\n elem.style.display = display;\n\n return target;\n}", "_id" : { "$oid" : "54c29c4cf1f6dbff33a793c7" } }, { "filename" : "dragDemo.css", "content" : ".computer {\n width: 93px;\n height: 98px;\n background: url(//js.cx/clipart/computer.gif) no-repeat;\n padding: 5px;\n font-style: italic;\n }\n\n.computer-smile {\n background: url(//js.cx/clipart/computer-smile.gif) no-repeat;\n}", "_id" : { "$oid" : "54c29c4cf1f6dbff33a793c8" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n\n\n\n\n\n\n

    Браузер переносить сюда:

    \n\n
    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c4cf1f6dbff33a793c9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4cf1f6dbff33a793cf" }, "plunkId" : "Q3EEHsvWPgORZJIPcJ4u", "webPath" : "/task/numeric-input/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\nВведите ваш возраст: \n\n\n\n\n", "_id" : { "$oid" : "54c29c4cf1f6dbff33a793d0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4cf1f6dbff33a793d1" }, "plunkId" : "D0Bqz0MYvtGknQYjebir", "webPath" : "/task/numeric-input/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\nВведите ваш возраст: \n\n\n\n\n", "_id" : { "$oid" : "54c29c4cf1f6dbff33a793d2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4df1f6dbff33a793d4" }, "plunkId" : "JeSmNSIVynL28IWbu2bk", "webPath" : "/task/check-sync-keydown/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n

    Нажмите одновременно \"Q\" и \"W\" (в любой раскладке).

    \n\n\n\n\n", "_id" : { "$oid" : "54c29c4df1f6dbff33a793d5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4df1f6dbff33a793d6" }, "plunkId" : "gpDGYdlm7CQDzbULJUwF", "webPath" : "/article/keyboard-events/keyboard-dump", "files" : [ { "filename" : "script.js", "content" : "kinput.onkeydown = kinput.onkeyup = kinput.onkeypress = handle;\n\nfunction handle(e) {\n if (form.elements[e.type + 'Ignore'].checked) return;\n\n var evt = e.type\n while (evt.length < 10) evt += ' '\n text.value += evt +\n ' keyCode=' + e.keyCode +\n ' which=' + e.which +\n ' charCode=' + e.charCode +\n ' char=' + String.fromCharCode(e.keyCode || e.charCode) +\n (e.shiftKey ? ' +shift' : '') +\n (e.ctrlKey ? ' +ctrl' : '') +\n (e.altKey ? ' +alt' : '') +\n (e.metaKey ? ' +meta' : '') + \"\\n\";\n\n\n if (form.elements[e.type + 'Stop'].checked) {\n e.preventDefault();\n }\n}", "_id" : { "$oid" : "54c29c4df1f6dbff33a793d7" } }, { "filename" : "style.css", "content" : "form {\n border:solid gray 1px;\n margin:10px;\n padding:10px;\n}\n\n#kinput {\n font-size:150%;\n width:600px;\n}\n\n#text {\n width:600px;\n border:1px solid black;\n display: block;\n}\n\nform label {\n display: inline;\n}", "_id" : { "$oid" : "54c29c4df1f6dbff33a793d8" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
    \n\n Предотвратить действие по умолчанию для:      \n\n

    \n Игнорировать:      

    \n\n

    Сфокусируйтесь на поле и нажмите какую-нибудь клавишу.

    \n\n \n\n \n
    \n \n \n\n\n\n", "_id" : { "$oid" : "54c29c4df1f6dbff33a793d9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4ef1f6dbff33a793dc" }, "plunkId" : "TMBfto6YdFIUx9eepz0r", "webPath" : "/task/avatar-above-scroll/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    Шапка
    \n\n
    \n
    \n

    Персонажи:

    \n
      \n
    • Винни-Пух
    • \n
    • Ослик Иа
    • \n
    • Сова
    • \n
    • Кролик
    • \n
    \n
    \n
    \n
    \n
    \n\n

    Винни-Пух

    \n\n
    \n \n
    Кадр из мультфильма
    \n
    \n\n

    Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

    \n\n

    В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

    \n\n

    Как и многие другие персонажи книги Милна, медвежонок Винни получил имя от одной из реальных игрушек Кристофера Робина (1920—1996), сына писателя. В свою очередь, плюшевый мишка Винни-Пух был назван по имени медведицы по кличке Виннипег (Винни), содержавшейся в 1920-х в Лондонском зоопарке.

    \n\n

    Медведица Виннипег (американский чёрный медведь) попала в Великобританию как живой талисман (маскот) Канадского армейского ветеринарного корпуса из Канады, а именно из окрестностей города Виннипега. Она оказалась в кавалерийском полку «Форт Гарри Хорс» 24 августа 1914 года ещё будучи медвежонком (её купил у канадского охотника-траппера за двадцать долларов 27-летний полковой ветеринар лейтенант Гарри Колборн, заботившийся о ней и в дальнейшем). Уже в октябре того же года медвежонок был привезён вместе с войсками в Британию, а так как полк должен был быть в ходе Первой мировой войны переправлен во Францию, то в декабре было принято решение оставить зверя до конца войны в Лондонском зоопарке. Медведица полюбилась лондонцам, и военные не стали возражать против того, чтобы не забирать её из зоопарка и после войны[1]. До конца дней (она умерла 12 мая 1934 года) медведица находилась на довольствии ветеринарного корпуса, о чём в 1919 году на её клетке сделали соответствующую надпись.

    \n\n

    «Винни-Пух» представляет собой дилогию, но каждая из двух книг Милна распадается на 10 рассказов (stories) с собственным сюжетом, которые могут читаться, экранизироваться и т. д. независимо друг от друга. В некоторых переводах деление на две части не сохранено, в других не переведена вторая («Дом на Пуховой опушке»). Иногда первая и вторая книги выполнены разными переводчиками. Такова необычная судьба немецкого Винни-Пуха: первая книга вышла в немецком переводе в 1928 году, а вторая лишь в 1954; между этими датами — ряд трагических событий германской истории.

    \n\n\n

    Действие книг о Пухе происходит в 500-акровом лесу Эшдаун близ купленной Милнами в 1925 году фермы Кочфорд в графстве Восточный Сассекс, Англия, представленном в книге как Стоакровый лес (англ. The Hundred Acre Wood, в пересказе Заходера — Чудесный лес). Реальными являются также Шесть сосен и ручеёк, у которого был найден Северный Полюс, а также упоминаемая в тексте растительность, в том числе колючий утёсник (gorse-bush, чертополох у Заходера), в который падает Пух[2]. Маленький Кристофер Робин любил забираться в дупла деревьев и играть там с Пухом, поэтому многие персонажи книг живут в дуплах, и значительная часть действия происходит в таких жилищах или на ветвях деревьев[2].\nАлан Милн, Кристофер Робин и Винни-Пух. Фотография из Британской национальной портретной галереи

    \n\n

    Действие «Винни-Пуха» разворачивается одновременно в трёх планах — это мир игрушек в детской, мир зверей «на своей территории» в Стоакровом лесу и мир персонажей в рассказах отца сыну (это наиболее чётко показано в самом начале)[4]. В дальнейшем рассказчик исчезает из повествования, и сказочный мир начинает собственное существование, разрастаясь от главы к главе[6]. Отмечалось сходство пространства и мира персонажей «Винни-Пуха» с классическим античным и средневековым эпосом[6]. Многообещающие эпические начинания персонажей (путешествия, подвиги, охоты, игры) оказываются комически малозначительными, в то время как настоящие события происходят во внутреннем мире героев (помощь в беде, гостеприимство, дружба)[6].

    \n\n

    Книги Милна выросли из устных рассказов и игр с Кристофером Робином; устное происхождение характерно и для многих других знаменитых литературных сказок[6]. «Я, собственно, ничего не придумывал, мне оставалось только описывать», как говорил впоследствии Милн[5]. Реальными игрушками Кристофера Робина были также Пятачок (подарок соседей), Иа-Иа без хвоста (ранний подарок родителей), Кенга с Крошкой Ру в сумке и Тигра (куплены родителями впоследствии специально для развития сюжета вечерних рассказов сыну). В рассказах они появляются именно в таком порядке[2]. Сову и Кролика Милн придумал сам; на иллюстрациях Шепарда они выглядят не как игрушки, а как настоящие животные, Кролик говорит Сове: «Только у меня и тебя есть мозги. У остальных — опилки». В процессе игры все эти персонажи получили индивидуальные повадки, привычки и манеру разговора[6]. На созданный Милном мир животных повлияла повесть Кеннета Грэма «Ветер в ивах», которой он восхищался и которую ранее иллюстрировал Шепард[5], возможна также скрытая полемика с «Книгой джунглей» Киплинга[5]. Текст взят из Википедии.

    \n
    \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c4ef1f6dbff33a793dd" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4ef1f6dbff33a793de" }, "plunkId" : "CT9KLi8nZSp83pmjM4qv", "webPath" : "/task/avatar-above-scroll/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    Шапка
    \n\n
    \n
    \n

    Персонажи:

    \n
      \n
    • Винни-Пух
    • \n
    • Ослик Иа
    • \n
    • Сова
    • \n
    • Кролик
    • \n
    \n
    \n
    \n
    \n
    \n\n

    Винни-Пух

    \n\n
    \n \n
    Кадр из мультфильма
    \n
    \n\n

    Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

    \n\n

    В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

    \n\n

    Как и многие другие персонажи книги Милна, медвежонок Винни получил имя от одной из реальных игрушек Кристофера Робина (1920—1996), сына писателя. В свою очередь, плюшевый мишка Винни-Пух был назван по имени медведицы по кличке Виннипег (Винни), содержавшейся в 1920-х в Лондонском зоопарке.

    \n\n

    Медведица Виннипег (американский чёрный медведь) попала в Великобританию как живой талисман (маскот) Канадского армейского ветеринарного корпуса из Канады, а именно из окрестностей города Виннипега. Она оказалась в кавалерийском полку «Форт Гарри Хорс» 24 августа 1914 года ещё будучи медвежонком (её купил у канадского охотника-траппера за двадцать долларов 27-летний полковой ветеринар лейтенант Гарри Колборн, заботившийся о ней и в дальнейшем). Уже в октябре того же года медвежонок был привезён вместе с войсками в Британию, а так как полк должен был быть в ходе Первой мировой войны переправлен во Францию, то в декабре было принято решение оставить зверя до конца войны в Лондонском зоопарке. Медведица полюбилась лондонцам, и военные не стали возражать против того, чтобы не забирать её из зоопарка и после войны[1]. До конца дней (она умерла 12 мая 1934 года) медведица находилась на довольствии ветеринарного корпуса, о чём в 1919 году на её клетке сделали соответствующую надпись.

    \n\n

    «Винни-Пух» представляет собой дилогию, но каждая из двух книг Милна распадается на 10 рассказов (stories) с собственным сюжетом, которые могут читаться, экранизироваться и т. д. независимо друг от друга. В некоторых переводах деление на две части не сохранено, в других не переведена вторая («Дом на Пуховой опушке»). Иногда первая и вторая книги выполнены разными переводчиками. Такова необычная судьба немецкого Винни-Пуха: первая книга вышла в немецком переводе в 1928 году, а вторая лишь в 1954; между этими датами — ряд трагических событий германской истории.

    \n\n\n

    Действие книг о Пухе происходит в 500-акровом лесу Эшдаун близ купленной Милнами в 1925 году фермы Кочфорд в графстве Восточный Сассекс, Англия, представленном в книге как Стоакровый лес (англ. The Hundred Acre Wood, в пересказе Заходера — Чудесный лес). Реальными являются также Шесть сосен и ручеёк, у которого был найден Северный Полюс, а также упоминаемая в тексте растительность, в том числе колючий утёсник (gorse-bush, чертополох у Заходера), в который падает Пух[2]. Маленький Кристофер Робин любил забираться в дупла деревьев и играть там с Пухом, поэтому многие персонажи книг живут в дуплах, и значительная часть действия происходит в таких жилищах или на ветвях деревьев[2].\nАлан Милн, Кристофер Робин и Винни-Пух. Фотография из Британской национальной портретной галереи

    \n\n

    Действие «Винни-Пуха» разворачивается одновременно в трёх планах — это мир игрушек в детской, мир зверей «на своей территории» в Стоакровом лесу и мир персонажей в рассказах отца сыну (это наиболее чётко показано в самом начале)[4]. В дальнейшем рассказчик исчезает из повествования, и сказочный мир начинает собственное существование, разрастаясь от главы к главе[6]. Отмечалось сходство пространства и мира персонажей «Винни-Пуха» с классическим античным и средневековым эпосом[6]. Многообещающие эпические начинания персонажей (путешествия, подвиги, охоты, игры) оказываются комически малозначительными, в то время как настоящие события происходят во внутреннем мире героев (помощь в беде, гостеприимство, дружба)[6].

    \n\n

    Книги Милна выросли из устных рассказов и игр с Кристофером Робином; устное происхождение характерно и для многих других знаменитых литературных сказок[6]. «Я, собственно, ничего не придумывал, мне оставалось только описывать», как говорил впоследствии Милн[5]. Реальными игрушками Кристофера Робина были также Пятачок (подарок соседей), Иа-Иа без хвоста (ранний подарок родителей), Кенга с Крошкой Ру в сумке и Тигра (куплены родителями впоследствии специально для развития сюжета вечерних рассказов сыну). В рассказах они появляются именно в таком порядке[2]. Сову и Кролика Милн придумал сам; на иллюстрациях Шепарда они выглядят не как игрушки, а как настоящие животные, Кролик говорит Сове: «Только у меня и тебя есть мозги. У остальных — опилки». В процессе игры все эти персонажи получили индивидуальные повадки, привычки и манеру разговора[6]. На созданный Милном мир животных повлияла повесть Кеннета Грэма «Ветер в ивах», которой он восхищался и которую ранее иллюстрировал Шепард[5], возможна также скрытая полемика с «Книгой джунглей» Киплинга[5]. Текст взят из Википедии.

    \n
    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c4ef1f6dbff33a793df" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4ff1f6dbff33a793e1" }, "plunkId" : "YvLefBOj3esqeQ7V1C9B", "webPath" : "/task/updown-button/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    \n \n
    \n\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c4ff1f6dbff33a793e2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4ff1f6dbff33a793e3" }, "plunkId" : "rKzfpYK0SR5PPhyAIVoE", "webPath" : "/task/updown-button/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n
    \n \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c4ff1f6dbff33a793e4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c4ff1f6dbff33a793e6" }, "plunkId" : "GxNsSozSZvy8xpCsfhWo", "webPath" : "/task/load-visible-img/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

    Тексты и картинки взяты с сайта http://etoday.ru.

    \n\n

    Все изображения с realsrc загружаются, когда становятся видимыми.

    \n\n\n
    \n
    Космопорт Америка \\ Architecture
    \n\nБудущее уже сейчас! Скоро фраза из фантастического фильма \"флипнуть до космопорта\" станет реальностью. По крайней мере вторую ее часть человечество обеспечило. В октябре состоялась официальная церемония открытия космопорта «Америка», первой в мире коммерческой площадки для частных космических полетов. Космопорт открылся в пустыне штата Нью-Мексико. Проект был реализован английским бюро Foster and Partners. Космопорт включает в себя зал ожидания и подготовки к полетам, диспетчерский пункт и ангар. Также обеспечена взлетно-посадочная полоса длиной в три километра.\n\n
    \n\n
    \n
    \n\n
    \n
    Рокер и супермодель в Vogue Russia \\ Celebrities
    \n\nСупермодель Анна Вялицына (Anne Vyalitsyna) и музыкант Адам Ливайн (Adam Levine) снялись в ноябрьском номере Vogue Russia. Снимал их Аликс Малка (Alix Malka). Анна и Адам примерили на себя рок-н-ролльные наряды от Alexander Wang, Louis Vuitton, Alexander McQueen, Balmain, Yves Saint Laurent, подобранные для них Катериной Мухиной.\n
    \n\n\n
    \n
    \n\n
    \n
    Старость - не радость в Vogue Italia \\ Fashion Photo
    \n\nСтивен Мейзел (Steven Meisel) снял фотосессию для октябрьского Vogue Italia. В съемках приняли участие: Карен Элсон (Karen Elson), Джиневер ван Синус (Guinevere van Seenus), Эмма Балфур (Emma Balfour), Эн Уст (An Oost), Коринна Ингенлеф (Corinna Ingenleuf), Танга Моро (Tanga Moreau), Кордула Рейер (Cordula Reyer), Гейл о`Нил (Gail O'Neil), Эвелин Кун (Evelyn Kuhn), Каролин де Мэгрэ (Caroline de Maigret), Дэльфин Бафор (Delfine Bafort), Кирстен Оуэн (Kirsten Owen), Гунилла Линдблад (Gunilla Lindblad).\n
    \n\n\n
    \n
    \n\n
    \n
    \"Вышитый рентген\" Matthew Cox \\ Art
    \n\nХудожник из Филадельфии Мэтью Кокс (Matthew Cox) создал серию работ, в которых объединены медицинский рентген и вышивка. Художник взял рентгенограммы и вышил их предполагаемое содержание частично со скелетными элементами. Получилось зловеще и интригующе. Выставка \"Вышитый рентген\" будет демонстрироваться в галерее Packer/Schopf в Майами, в рамках Базельской Художественной Недели.\n\nЭта серия - только треть творческой продукции Кокса. Он также создает традиционные картины и иллюстрации.\n
    \n
    \n\n
    \n
    Подарочный каталог Apple 1983 \\ Creative
    \n\nEtoday предлагает полистать страницы подарочного каталога продукции Apple образца 1983 года. Кажется, это было так давно!\nЭта серия - только треть творческой продукции Кокса. Он также создает традиционные картины и иллюстрации.\n
    \n
    \n\n
    \n
    Винтажные открытки к празднику Halloween \\ Illustrations
    \n\nЗанимательная коллекция старых почтовых открыток праздника Halloween. Открытки взяты из ньюйоркской публичной библиотеки и датируются примерно 1910 г.\n\n
    \n
    \n\n
    \n
    Фотограф Emily Lee \\ Photography
    \n\nМолодой фотограф Эмили Ли (Emily Lee) использует фотографию, чтобы выразить свои чувства. \"Когда я смотрю на жизнь через камеру, вижу все более ясно, - пишет она на своем профиле Flickr. - Фотосъемка - это искусство наблюдения.\" Эмили Ли - обладательница большого таланта и умения глубоко понимать искусство, хотя учится еще только в средней школе.\n\n
    \n
    \n\n
    \n
    Иконы моды в Fashimals \\ Creative
    \n\nFashimals - tumblr-блог, посвященный иконам моды, превращенным в животных. Здесь есть Анна Винтур, Карл Лагерфельд, Терри Ричардсон, а также много других их коллег.\n\n
    \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c4ff1f6dbff33a793e7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c50f1f6dbff33a793e8" }, "plunkId" : "t7vnYkhzhySvEcOw0BGX", "webPath" : "/task/load-visible-img/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\t\n\t\n\n\n\n

    Тексты и картинки взяты с сайта http://etoday.ru.

    \n\n

    Все изображения с realsrc загружаются, когда становятся видимыми.

    \n\n\n
    \n
    Космопорт Америка \\ Architecture
    \n\nБудущее уже сейчас! Скоро фраза из фантастического фильма \"флипнуть до космопорта\" станет реальностью. По крайней мере вторую ее часть человечество обеспечило. В октябре состоялась официальная церемония открытия космопорта «Америка», первой в мире коммерческой площадки для частных космических полетов. Космопорт открылся в пустыне штата Нью-Мексико. Проект был реализован английским бюро Foster and Partners. Космопорт включает в себя зал ожидания и подготовки к полетам, диспетчерский пункт и ангар. Также обеспечена взлетно-посадочная полоса длиной в три километра.\n\n
    \n\n
    \n
    \n\n
    \n
    Рокер и супермодель в Vogue Russia \\ Celebrities
    \n\nСупермодель Анна Вялицына (Anne Vyalitsyna) и музыкант Адам Ливайн (Adam Levine) снялись в ноябрьском номере Vogue Russia. Снимал их Аликс Малка (Alix Malka). Анна и Адам примерили на себя рок-н-ролльные наряды от Alexander Wang, Louis Vuitton, Alexander McQueen, Balmain, Yves Saint Laurent, подобранные для них Катериной Мухиной.\n
    \n\n\n
    \n
    \n\n
    \n
    Старость - не радость в Vogue Italia \\ Fashion Photo
    \n\nСтивен Мейзел (Steven Meisel) снял фотосессию для октябрьского Vogue Italia. В съемках приняли участие: Карен Элсон (Karen Elson), Джиневер ван Синус (Guinevere van Seenus), Эмма Балфур (Emma Balfour), Эн Уст (An Oost), Коринна Ингенлеф (Corinna Ingenleuf), Танга Моро (Tanga Moreau), Кордула Рейер (Cordula Reyer), Гейл о`Нил (Gail O'Neil), Эвелин Кун (Evelyn Kuhn), Каролин де Мэгрэ (Caroline de Maigret), Дэльфин Бафор (Delfine Bafort), Кирстен Оуэн (Kirsten Owen), Гунилла Линдблад (Gunilla Lindblad).\n
    \n\n\n
    \n
    \n\n
    \n
    \"Вышитый рентген\" Matthew Cox \\ Art
    \n\nХудожник из Филадельфии Мэтью Кокс (Matthew Cox) создал серию работ, в которых объединены медицинский рентген и вышивка. Художник взял рентгенограммы и вышил их предполагаемое содержание частично со скелетными элементами. Получилось зловеще и интригующе. Выставка \"Вышитый рентген\" будет демонстрироваться в галерее Packer/Schopf в Майами, в рамках Базельской Художественной Недели.\n\nЭта серия - только треть творческой продукции Кокса. Он также создает традиционные картины и иллюстрации.\n
    \n
    \n\n
    \n
    Подарочный каталог Apple 1983 \\ Creative
    \n\nEtoday предлагает полистать страницы подарочного каталога продукции Apple образца 1983 года. Кажется, это было так давно!\nЭта серия - только треть творческой продукции Кокса. Он также создает традиционные картины и иллюстрации.\n
    \n
    \n\n
    \n
    Винтажные открытки к празднику Halloween \\ Illustrations
    \n\nЗанимательная коллекция старых почтовых открыток праздника Halloween. Открытки взяты из ньюйоркской публичной библиотеки и датируются примерно 1910 г.\n\n
    \n
    \n\n
    \n
    Фотограф Emily Lee \\ Photography
    \n\nМолодой фотограф Эмили Ли (Emily Lee) использует фотографию, чтобы выразить свои чувства. \"Когда я смотрю на жизнь через камеру, вижу все более ясно, - пишет она на своем профиле Flickr. - Фотосъемка - это искусство наблюдения.\" Эмили Ли - обладательница большого таланта и умения глубоко понимать искусство, хотя учится еще только в средней школе.\n\n
    \n
    \n\n
    \n
    Иконы моды в Fashimals \\ Creative
    \n\nFashimals - tumblr-блог, посвященный иконам моды, превращенным в животных. Здесь есть Анна Винтур, Карл Лагерфельд, Терри Ричардсон, а также много других их коллег.\n\n
    \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c50f1f6dbff33a793e9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c51f1f6dbff33a793ef" }, "plunkId" : "eL5CM2kwUgN6GueEU2SX", "webPath" : "/task/emulate-placeholder/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c51f1f6dbff33a793f0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c51f1f6dbff33a793f1" }, "plunkId" : "18sEBH2y31pfQL4Xf1gr", "webPath" : "/task/emulate-placeholder/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c51f1f6dbff33a793f2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c52f1f6dbff33a793f4" }, "plunkId" : "i9B9XxFeXU6uA9GlVbO9", "webPath" : "/task/keyboard-mouse/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nКликните на мышонка и передвигайте его, нажимая клавиши со стрелками.\n\n
    \n
    \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c52f1f6dbff33a793f5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c52f1f6dbff33a793f6" }, "plunkId" : "nhbdXwipndOYPsVKm6qH", "webPath" : "/task/keyboard-mouse/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nКликните на мышонка и передвигайте его, нажимая клавиши со стрелками.\n\n
    \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c52f1f6dbff33a793f7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c52f1f6dbff33a793f9" }, "plunkId" : "b5CSgoAoB9K8zOH6mBvv", "webPath" : "/task/hotkeys/solution", "files" : [ { "filename" : "my.css", "content" : "#view, #area {\n height:150px;\n width:400px;\n font-family:arial;\n}\n\n#view {\n /* padding + border = 3px */\n padding: 2px;\n border:1px solid black;\n}\n\n#area {\n display:none;\n\n /* replace padding with border (still 3px not to shift the contents) */\n border: 3px groove blue;\n padding: 0px;\n}\n#area:focus {\n outline: none; /* remove focus border in Safari */\n}", "_id" : { "$oid" : "54c29c52f1f6dbff33a793fa" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
      \n
    • Ctrl-E для начала редактирования.
    • \n
    • Во время редактирования: Ctrl-S для сохранения, Esc для отмены.
    • \n
    \n\nHTML разрешён.\n\n\n
    Текст
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c52f1f6dbff33a793fb" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c53f1f6dbff33a793fc" }, "plunkId" : "J2xLSthNEBCXvRrXpcq2", "webPath" : "/task/hotkeys/source", "files" : [ { "filename" : "my.css", "content" : "#view, #area {\n height:150px;\n width:400px;\n font-family:arial;\n}\n\n#view {\n /* padding + border = 3px */\n padding: 2px;\n border:1px solid black;\n}\n\n#area {\n display:none;\n\n /* replace padding with border (still 3px not to shift the contents) */\n border: 3px groove blue;\n padding: 0px;\n}\n#area:focus {\n outline: none; /* remove focus border in Safari */\n}", "_id" : { "$oid" : "54c29c53f1f6dbff33a793fd" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
      \n
    • Ctrl-E to start editing.
    • \n
    • While editing: Ctrl-S to save, Esc to cancel.
    • \n
    \n\n\n\n
    Text
    \n\n\n\n", "_id" : { "$oid" : "54c29c53f1f6dbff33a793fe" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c53f1f6dbff33a79400" }, "plunkId" : "l1sjSmcdxPb9VBCT9qNq", "webPath" : "/task/edit-td-click-1/solution", "files" : [ { "filename" : "script.js", "content" : "var table = document.getElementById('bagua-table');\n\ntable.onclick = function(event) {\n var target = event.target;\n\n while(target != table) {\n if (target.nodeName == 'TD') {\n if (target.firstChild.tagName == 'TEXTAREA') { // already editing\n return;\n }\n makeTdEditable(target);\n return;\n }\n target = target.parentNode;\n }\n}\n\nfunction makeTdEditable(td) {\n var textArea = document.createElement('textarea');\n textArea.className = 'edit-area';\n textArea.value = td.innerHTML;\n textArea.onkeydown = function(e) {\n if (e.keyCode == 13 && e.shiftKey) {\n finishTdEditing(td);\n }\n }\n td.innerHTML = '';\n td.appendChild(textArea);\n textArea.focus();\n}\n\nfunction finishTdEditing(td) {\n td.innerHTML = td.firstChild.value;\n}", "_id" : { "$oid" : "54c29c53f1f6dbff33a79401" } }, { "filename" : "bagua.css", "content" : "#bagua-table th {\n text-align:center;\n font-weight:bold;\n}\n\n#bagua-table td {\n width: 150px;\n white-space: nowrap;\n text-align:center;\n vertical-align: bottom;\n padding: 0;\n}\n\n#bagua-table .nw {\n background-color: #999;\n}\n\n#bagua-table .n {\n background-color: #03f;\n color: #fff;\n}\n\n#bagua-table .ne {\n background-color: #ff6;\n}\n\n#bagua-table .w {\n background-color: #ff0;\n}\n#bagua-table .c {\n background-color: #60c;\n color: #fff;\n}\n#bagua-table .e {\n background-color: #09f;\n color: #fff;\n}\n\n#bagua-table .sw {\n background-color: #963;\n color: #fff;\n}\n\n#bagua-table .s {\n background-color: #f60;\n color: #fff;\n}\n#bagua-table .se {\n background-color: #0c3;\n color: #fff;\n}", "_id" : { "$oid" : "54c29c53f1f6dbff33a79402" } }, { "filename" : "my.css", "content" : ".edit-area {\n border: none;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n display: block;\n resize: none; /* remove resizing handle in Firefox */\n outline: none; /* remove outline on focus in Chrome */\n overflow: auto; /* remove scrollbar in IE */\n}", "_id" : { "$oid" : "54c29c53f1f6dbff33a79403" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\nКликните на ячейке для начала редактирования. Когда закончите -- нажмите, находясь в ней, Shift+Enter.\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c53f1f6dbff33a79404" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c53f1f6dbff33a79405" }, "plunkId" : "D9HQV59PzGDfGr1ejtUT", "webPath" : "/task/edit-td-click-1/source", "files" : [ { "filename" : "bagua.css", "content" : "#bagua-table th {\n text-align:center;\n font-weight:bold;\n}\n\n#bagua-table td {\n width: 150px;\n white-space: nowrap;\n text-align:center;\n vertical-align: bottom;\n padding: 0;\n}\n\n#bagua-table .nw {\n background-color: #999;\n}\n\n#bagua-table .n {\n background-color: #03f;\n color: #fff;\n}\n\n#bagua-table .ne {\n background-color: #ff6;\n}\n\n#bagua-table .w {\n background-color: #ff0;\n}\n#bagua-table .c {\n background-color: #60c;\n color: #fff;\n}\n#bagua-table .e {\n background-color: #09f;\n color: #fff;\n}\n\n#bagua-table .sw {\n background-color: #963;\n color: #fff;\n}\n\n#bagua-table .s {\n background-color: #f60;\n color: #fff;\n}\n#bagua-table .se {\n background-color: #0c3;\n color: #fff;\n}", "_id" : { "$oid" : "54c29c53f1f6dbff33a79406" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n\n\n", "_id" : { "$oid" : "54c29c53f1f6dbff33a79407" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c54f1f6dbff33a79409" }, "plunkId" : "DkRqGGBSVjrg7dOVoOx9", "webPath" : "/task/edit-td-click-2/solution", "files" : [ { "filename" : "script.js", "content" : "var table = document.getElementById('bagua-table');\n\nvar editingTd;\n\ntable.onclick = function(event) {\n\n var target = event.target;\n\n while(target != table) {\n if (target.className == 'edit-cancel') {\n finishTdEdit(editingTd.elem, false);\n return;\n }\n\n if (target.className == 'edit-ok') {\n finishTdEdit(editingTd.elem, true);\n return;\n }\n\n if (target.nodeName == 'TD') {\n if (editingTd) return; // already editing\n\n makeTdEditable(target);\n return;\n }\n\n target = target.parentNode;\n }\n}\n\nfunction makeTdEditable(td) {\n editingTd = { elem: td, data: td.innerHTML };\n\n td.className += ' edit-td'; // td, not textarea! the rest of rules will cascade\n\n var textArea = document.createElement('textarea');\n textArea.style.width = td.clientWidth + 'px';\n textArea.style.height = td.clientHeight + 'px';\n textArea.className = 'edit-area';\n\n textArea.value = td.innerHTML;\n td.innerHTML = '';\n td.appendChild(textArea);\n textArea.focus();\n\n var controls = document.createElement('div');\n controls.innerHTML = '';\n controls.className = 'edit-controls';\n td.appendChild(controls);\n}\n\nfunction finishTdEdit(td, isOk) {\n if (isOk) {\n td.innerHTML = td.firstChild.value;\n } else {\n td.innerHTML = editingTd.data;\n }\n td.className = td.className.replace(' edit-td', ''); // remove edit class\n editingTd = null;\n}", "_id" : { "$oid" : "54c29c54f1f6dbff33a7940a" } }, { "filename" : "bagua.css", "content" : "#bagua-table th {\n text-align:center;\n font-weight:bold;\n}\n\n#bagua-table td {\n width: 150px;\n white-space: nowrap;\n text-align:center;\n vertical-align: bottom;\n padding: 0;\n}\n\n#bagua-table .nw {\n background-color: #999;\n}\n\n#bagua-table .n {\n background-color: #03f;\n color: #fff;\n}\n\n#bagua-table .ne {\n background-color: #ff6;\n}\n\n#bagua-table .w {\n background-color: #ff0;\n}\n#bagua-table .c {\n background-color: #60c;\n color: #fff;\n}\n#bagua-table .e {\n background-color: #09f;\n color: #fff;\n}\n\n#bagua-table .sw {\n background-color: #963;\n color: #fff;\n}\n\n#bagua-table .s {\n background-color: #f60;\n color: #fff;\n}\n#bagua-table .se {\n background-color: #0c3;\n color: #fff;\n}", "_id" : { "$oid" : "54c29c54f1f6dbff33a7940b" } }, { "filename" : "my.css", "content" : ".edit-td .edit-area {\n border: none;\n margin: 0;\n padding: 0;\n display: block;\n resize: none; /* remove resizing handle in Firefox */\n outline: none; /* remove outline on focus in Chrome */\n overflow: auto; /* remove scrollbar in IE */\n}\n\n.edit-controls {\n position: absolute;\n}\n.edit-td {\n position: relative;\n}", "_id" : { "$oid" : "54c29c54f1f6dbff33a7940c" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\nКликните на ячейке для начала редактирования. Когда закончите -- нажмите, находясь в ней, Shift+Enter или кликните на OK/CANCEL.\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
    Bagua Chart: Direction, Element, Color, Meaning
    Northwest
    Metal
    Silver
    Elders\n
    North
    Water
    Blue
    Change\n
    Northeast
    Earth
    Yellow
    Direction\n
    West
    Metal
    Gold
    Youth\n
    Center
    All
    Purple
    Harmony\n
    East
    Wood
    Blue
    Future\n
    Southwest
    Earth
    Brown
    Tranquility\n
    South
    Fire
    Orange
    Fame\n
    Southeast
    Wood
    Green
    Romance\n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c54f1f6dbff33a7940d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c54f1f6dbff33a7940f" }, "plunkId" : "qFGyHrlETZBPYWNy1vkV", "webPath" : "/task/input-nice-placeholder/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
    Добро пожаловать
    \n\n\n
    Скажи пароль, друг
    \n\n
    .. и заходи
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c54f1f6dbff33a79410" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c54f1f6dbff33a79411" }, "plunkId" : "U5Xh19fafXJIUjevgL6Z", "webPath" : "/task/input-nice-placeholder/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n
    Добро пожаловать
    \n\n\n
    Скажи пароль, друг
    \n\n
    .. и заходи
    \n\n\n", "_id" : { "$oid" : "54c29c54f1f6dbff33a79412" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c55f1f6dbff33a79414" }, "plunkId" : "cMepjJNjtluWxd5dmLu3", "webPath" : "/task/capslock-warning-field/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\nВведите текст(например, пароль) с нажатым CapsLock:\n\n\n
    Внимание: нажат CapsLock!
    \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c55f1f6dbff33a79415" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c55f1f6dbff33a79416" }, "plunkId" : "qHArd6EoFhtGN0l0VRKy", "webPath" : "/task/capslock-warning-field/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\nВведите текст(например, пароль) с нажатым CapsLock:\n\n\n
    Внимание: нажат CapsLock!
    \n\n\n\n", "_id" : { "$oid" : "54c29c55f1f6dbff33a79417" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c56f1f6dbff33a7941a" }, "plunkId" : "MHBGJvUv21Z8CZ02vFHt", "webPath" : "/task/calculate-capitalization/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\nКалькулятор процентов, из расчёта 12% годовых.\n
    \n\n \n \n \n \n \n \n \n \n \n \n \n \n
    Сумма
    Срок в месяцах\n \n
    С капитализацией
    \n\n\n
    \n\n\n\n\n\n\n\n\n\n\n\n\n\n
    Было:Станет:
    \n
    \n
    \n
    \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c56f1f6dbff33a7941b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c56f1f6dbff33a7941c" }, "plunkId" : "8nfPLuMaHhoeAvD0p51h", "webPath" : "/task/calculate-capitalization/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\nКалькулятор процентов, из расчёта 12% годовых.\n
    \n\n \n \n \n \n \n \n \n \n \n \n \n \n
    Сумма
    Срок в месяцах\n \n
    С капитализацией
    \n\n\n
    \n\n\n\n\n\n\n\n\n\n\n\n\n\n
    Было:Станет:
    \n
    \n
    \n
    \n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c56f1f6dbff33a7941d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c56f1f6dbff33a79420" }, "plunkId" : "M1KBAcOS7JPJTbONQgio", "webPath" : "/task/modal-dialog/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n

    Нажмите на кнопку ниже

    \n\n\n\n\n
    \n
    \n
    \n \n \n \n
    \n
    \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c56f1f6dbff33a79421" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c57f1f6dbff33a79422" }, "plunkId" : "D49Xb1RdZqjq3aHhpqGi", "webPath" : "/task/modal-dialog/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n
    \n
    \n
    Введите, пожалуйста...
    Что-то..
    \n \n \n \n
    \n
    \n\n\n\n", "_id" : { "$oid" : "54c29c57f1f6dbff33a79423" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c57f1f6dbff33a79425" }, "plunkId" : "qg2RFduIb5oHGdzAQVGs", "webPath" : "/task/form-validation/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n
    \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    От кого
    Ваш пароль
    Повторите пароль
    Куда\n \n
    \n\nСообщение:\n\n\n\n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c57f1f6dbff33a79426" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c58f1f6dbff33a79427" }, "plunkId" : "3HOGUPOPZsE6cUFMiBR3", "webPath" : "/task/form-validation/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n
    \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    От кого
    Ваш пароль
    Повторите пароль
    Куда\n \n
    \n\nСообщение:\n\n\n\n
    \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c58f1f6dbff33a79428" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c59f1f6dbff33a7942d" }, "plunkId" : "adymmwYLNNODMw6vmmlp", "webPath" : "/task/clock/solution", "files" : [ { "filename" : "clock.js", "content" : "function Clock(options) {\n var elem = options.elem;\n\n var timer;\n\n function render() {\n var date = new Date();\n\n var hours = date.getHours();\n if (hours < 10) hours = '0' + hours;\n $('.hour', elem).html(hours);\n\n var min = date.getMinutes();\n if (min < 10) min = '0' + min;\n $('.min', elem).html(min);\n\n var sec = date.getSeconds();\n if (sec < 10) sec = '0' + sec;\n $('.sec', elem).html(sec);\n }\n\n this.stop = function() {\n clearInterval(timer);\n };\n\n this.start = function() {\n render();\n timer = setInterval(render, 1000);\n }\n\n}", "_id" : { "$oid" : "54c29c59f1f6dbff33a7942e" } }, { "filename" : "index.html", "content" : "\n\n\n Часики\n \n \n \n \n\n\n\n
    \n 00:00:00\n
    \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c59f1f6dbff33a7942f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c59f1f6dbff33a79430" }, "plunkId" : "YjZfR23OI37JJDknx9YK", "webPath" : "/task/clock/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n Часики\n \n \n \n\n\n\n
    \n 00:00:00\n
    \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c59f1f6dbff33a79431" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c59f1f6dbff33a79433" }, "plunkId" : "Ev3KeQP30G0TfoqIkPAH", "webPath" : "/task/slider-widget/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n \n\n \n \n\n \n
    \n
    \n
    \n \n \n\n", "_id" : { "$oid" : "54c29c59f1f6dbff33a79434" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5af1f6dbff33a79436" }, "plunkId" : "Mkw6v8zXmqZ7zE8FQcVh", "webPath" : "/task/selectable-list-component/solution", "files" : [ { "filename" : "listSelect.js", "content" : "function ListSelect(options) {\n var elem = options.elem;\n\n var lastClickedLi = null;\n\n elem.on('click', 'li', onLiClick);\n elem.on('selectstart mousedown', false);\n\n function onLiClick(e) {\n var li = $(this);\n\n if(e.metaKey || e.ctrlKey) { // для Mac проверяем Cmd, т.к. Ctrl + click там контекстное меню\n toggleSelect(li);\n } else if (e.shiftKey) {\n selectFromLast(li);\n } else {\n selectSingle(li);\n }\n\n lastClickedLi = li;\n }\n\n function deselectAll() {\n elem.children().removeClass('selected');\n }\n\n function toggleSelect(li) {\n li.toggleClass('selected');\n }\n\n function selectSingle(li) {\n deselectAll();\n li.addClass('selected');\n }\n\n function selectFromLast(target) {\n var startElem = lastClickedLi || elem.children().first();\n\n target.addClass('selected');\n if (startElem[0] == target[0]) {\n // клик на том же элементе, что и раньше\n // это особый случай\n return;\n }\n\n var isLastClickedBefore = startElem.index() < target.index();\n\n if (isLastClickedBefore) {\n startElem.nextUntil(target).add(startElem).addClass('selected');\n } else {\n startElem.prevUntil(target).add(startElem).addClass('selected');\n }\n }\n\n this.getSelected = function() {\n return elem.children('.selected').map(function() {\n return this.innerHTML;\n }).toArray();\n };\n}", "_id" : { "$oid" : "54c29c5af1f6dbff33a79437" } }, { "filename" : "style.css", "content" : ".selected {\n background: #0f0;\n}\nli {\n cursor: pointer;\n}", "_id" : { "$oid" : "54c29c5af1f6dbff33a79438" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\nКлик на элементе выделяет только его.
    \nCtrl(Cmd)+Клик добавляет/убирает элемент из выделенных.
    \nShift+Клик добавляет промежуток от последнего кликнутого к выделению.
    \n\n
      \n
    • Кристофер Робин
    • \n
    • Винни-Пух
    • \n
    • Ослик Иа
    • \n
    • Мудрая Сова
    • \n
    • Кролик. Просто кролик.
    • \n
    \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c5af1f6dbff33a79439" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5af1f6dbff33a7943b" }, "plunkId" : "chSIAfPX59hccHc8dTdr", "webPath" : "/task/voter/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n
    \n \n 0\n +\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c5af1f6dbff33a7943c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5bf1f6dbff33a7943d" }, "plunkId" : "I2O6k51A75LVndP3nSRY", "webPath" : "/task/voter/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n
    \n \n 0\n +\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c5bf1f6dbff33a7943e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5cf1f6dbff33a79440" }, "plunkId" : "3JFwWNh2crOPjSnmHdpw", "webPath" : "/task/voter-proto/solution", "files" : [ { "filename" : "voter.js", "content" : "function Voter(options) {\n var elem = this._elem = options.elem;\n this._voteElem = elem.find('.vote');\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.down', this._onDownClick.bind(this));\n elem.on('click', '.up', this._onUpClick.bind(this));\n}\n\nVoter.prototype._onDownClick = function() {\n this._voteElem.html( +this._voteElem.html() - 1 );\n};\n\nVoter.prototype._onUpClick = function() {\n this._voteElem.html( +this._voteElem.html() + 1 );\n};\n\nVoter.prototype.setVote = function(vote) {\n this._voteElem.html(vote);\n};", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79441" } }, { "filename" : "style.css", "content" : ".voter {\n font-family: Consolas, \"Lucida Console\", monospace;\n font-size: 18px;\n}\n.up, .down {\n cursor: pointer;\n color: blue;\n font-weight: bold;\n}", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79442" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n
    \n \n 0\n +\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79443" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5cf1f6dbff33a79445" }, "plunkId" : "iwb0dGuZTbc3Mt91vzVc", "webPath" : "/task/voter-colored/solution", "files" : [ { "filename" : "colored-voter.js", "content" : "function ColoredVoter(options) {\n Voter.apply(this, arguments);\n}\nColoredVoter.prototype = Object.create(Voter.prototype);\n\nColoredVoter.prototype._renderVote = function() {\n Voter.prototype._renderVote.apply(this, arguments);\n this._voteElem.removeClass('positive negative');\n if (this._vote > 0) {\n this._voteElem.addClass('positive');\n }\n if (this._vote < 0) {\n this._voteElem.addClass('negative');\n }\n};", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79446" } }, { "filename" : "voter.js", "content" : "function Voter(options) {\n var elem = this._elem = options.elem;\n this._voteElem = elem.find('.vote');\n this._vote = 0;\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.down', this._onDownClick.bind(this));\n elem.on('click', '.up', this._onUpClick.bind(this));\n}\n\nVoter.prototype._onDownClick = function() {\n this.setVote(this._vote - 1);\n};\n\nVoter.prototype._onUpClick = function() {\n this.setVote(this._vote + 1);\n};\n\nVoter.prototype._renderVote = function() {\n this._voteElem.html(this._vote);\n};\n\nVoter.prototype.setVote = function(vote) {\n this._vote = vote;\n this._renderVote();\n};", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79447" } }, { "filename" : "style.css", "content" : ".voter {\n font-family: Consolas, \"Lucida Console\", monospace;\n font-size: 18px;\n}\n.up, .down {\n cursor: pointer;\n color: blue;\n font-weight: bold;\n}\n\n.positive {\n color: green;\n}\n\n.negative {\n color: red;\n}", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79448" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n
    \n \n 0\n +\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79449" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5cf1f6dbff33a7944b" }, "plunkId" : "we5J2ISTElYaR0D8oHZX", "webPath" : "/task/voter-add-doublevote/solution", "files" : [ { "filename" : "step-voter.js", "content" : "function StepVoter(options) {\n Voter.apply(this, arguments);\n this._step = options.step || 1;\n}\nStepVoter.prototype = Object.create(Voter.prototype);\n\nStepVoter.prototype._increase = function() {\n this.setVote(this._vote + this._step);\n};\n\nStepVoter.prototype._decrease = function() {\n this.setVote(this._vote - this._step);\n};", "_id" : { "$oid" : "54c29c5cf1f6dbff33a7944c" } }, { "filename" : "voter.js", "content" : "function Voter(options) {\n var elem = this._elem = options.elem;\n this._voteElem = elem.find('.vote');\n this._vote = 0;\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.down', this._onDownClick.bind(this));\n elem.on('click', '.up', this._onUpClick.bind(this));\n}\n\nVoter.prototype._onDownClick = function() {\n this._decrease();\n};\n\nVoter.prototype._onUpClick = function() {\n this._increase();\n};\n\nVoter.prototype._renderVote = function() {\n this._voteElem.html(this._vote);\n};\n\nVoter.prototype.setVote = function(vote) {\n this._vote = vote;\n this._renderVote();\n};\n\nVoter.prototype._increase = function() {\n this.setVote(this._vote + 1);\n};\n\nVoter.prototype._decrease = function() {\n this.setVote(this._vote - 1);\n};", "_id" : { "$oid" : "54c29c5cf1f6dbff33a7944d" } }, { "filename" : "style.css", "content" : ".voter {\n font-family: Consolas, \"Lucida Console\", monospace;\n font-size: 18px;\n}\n.up, .down {\n cursor: pointer;\n color: blue;\n font-weight: bold;\n}", "_id" : { "$oid" : "54c29c5cf1f6dbff33a7944e" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n
    \n \n 0\n +\n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c5cf1f6dbff33a7944f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5cf1f6dbff33a79450" }, "plunkId" : "pWcPTSqCOlMVF0ePlcCs", "webPath" : "/article/widgets-structure/menu-1", "files" : [ { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem = options.elem;\n\n // отмена выделения при клике на меню\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.title', function() {\n elem.toggleClass('open');\n });\n\n}", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79451" } }, { "filename" : "style.css", "content" : ".menu ul {\n display: none;\n margin: 0;\n}\n\n.menu .title {\n font-weight: bold;\n cursor: pointer;\n background: url(//js.cx/clipart/arrow-right.png) left center no-repeat;\n padding-left: 18px;\n}\n\n.menu.open ul {\n display: block;\n}\n\n.menu.open .title {\n background-image: url(//js.cx/clipart/arrow-down.png);\n}", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79452" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n
    \n Сладости\n
      \n
    • Торт
    • \n
    • Пончик
    • \n
    • Пирожное
    • \n
    • Шоколадка
    • \n
    • Мороженое
    • \n
    \n
    \n\n\n\n\n", "_id" : { "$oid" : "54c29c5cf1f6dbff33a79453" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5ef1f6dbff33a79454" }, "plunkId" : "pk63raMoPz5R9ehldtrG", "webPath" : "/article/widgets-structure/menu-3-elem", "files" : [ { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem;\n\n function getElem() {\n if (!elem) render();\n return elem;\n }\n\n function render() {\n elem = $('
    ');\n elem.append( $('', { class: \"title\", text: options.title }))\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.title', onTitleClick);\n }\n\n function renderItems() {\n var items = options.items || [];\n var list = $('
      ');\n $.each(items, function(i, item) {\n list.append( $('
    • ').text(item) );\n })\n list.appendTo(elem);\n }\n\n function onTitleClick(e) {\n toggle();\n }\n\n function open() {\n if (!elem.find('ul').length) {\n renderItems();\n }\n elem.addClass('open');\n };\n\n function close() {\n elem.removeClass('open');\n };\n\n function toggle() {\n if (elem.hasClass('open')) close();\n else open();\n };\n\n this.getElem = getElem;\n this.toggle = toggle;\n this.close = close;\n this.open = open;\n}", "_id" : { "$oid" : "54c29c5ef1f6dbff33a79455" } }, { "filename" : "style.css", "content" : ".menu ul {\n display: none;\n margin: 0;\n}\n\n.menu .title {\n font-weight: bold;\n cursor: pointer;\n background: url(//js.cx/clipart/arrow-right.png) left center no-repeat;\n padding-left: 18px;\n}\n\n.menu.open ul {\n display: block;\n}\n\n.menu.open .title {\n background-image: url(//js.cx/clipart/arrow-down.png);\n}", "_id" : { "$oid" : "54c29c5ef1f6dbff33a79456" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n\n\n\n\n
      \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c5ef1f6dbff33a79457" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5ef1f6dbff33a7945a" }, "plunkId" : "W7gDIvMeGfHOWRyRrFDg", "webPath" : "/task/semantic-menu/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c5ef1f6dbff33a7945b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c5ef1f6dbff33a7945c" }, "plunkId" : "fYcT6DAZjgJnPkDJgmtS", "webPath" : "/task/semantic-menu/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
      \n
      Главная
      \n
      |
      \n
      Товары
      \n
      Фотографии
      \n
      Контакты
      \n
      \n\n\n", "_id" : { "$oid" : "54c29c5ef1f6dbff33a7945d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c60f1f6dbff33a79462" }, "plunkId" : "kG96IJIEF3rTUoUuJj3E", "webPath" : "/task/table-template/solution", "files" : [ { "filename" : "index.html", "content" : "\n \n \n \n \n \n \n \n \n\n
      \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c60f1f6dbff33a79463" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c60f1f6dbff33a79464" }, "plunkId" : "1Igds5QvX5AG6sTgEc4W", "webPath" : "/task/table-template/source", "files" : [ { "filename" : "index.html", "content" : "\n \n \n \n \n \n \n \n\n
      \n\n\n\n \n\n \n ", "_id" : { "$oid" : "54c29c60f1f6dbff33a79465" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c61f1f6dbff33a79468" }, "plunkId" : "ai6IJRopTid7udtXdKqz", "webPath" : "/task/menu-template/solution", "files" : [ { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem;\n\n function getElem() {\n if (!elem) render();\n return elem;\n }\n\n function render() {\n var elemHtml = options.template({title: options.title});\n\n elem = $(elemHtml);\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.title', onTitleClick);\n elem.on('click', 'a', onItemClick)\n }\n\n\n function renderItems() {\n if (elem.find('ul').length) return;\n\n var listHtml = options.listTemplate({items: options.items});\n elem.append(listHtml);\n }\n\n function onItemClick(e) {\n alert(e.currentTarget.getAttribute('href').slice(1));\n e.preventDefault();\n }\n\n function onTitleClick(e) {\n toggle();\n }\n\n function open() {\n renderItems();\n elem.addClass('open');\n };\n\n function close() {\n elem.removeClass('open');\n };\n\n function toggle() {\n if (elem.hasClass('open')) close();\n else open();\n };\n\n this.getElem = getElem;\n this.toggle = toggle;\n this.close = close;\n this.open = open;\n}", "_id" : { "$oid" : "54c29c61f1f6dbff33a79469" } }, { "filename" : "menu.css", "content" : ".menu ul {\n display: none;\n margin: 0;\n}\n\n.menu .title {\n font-weight: bold;\n cursor: pointer;\n background: url(//js.cx/clipart/arrow-right.png) left center no-repeat;\n padding-left: 18px;\n}\n\n.menu.open ul {\n display: block;\n}\n\n.menu.open .title {\n background-image: url(//js.cx/clipart/arrow-down.png);\n}", "_id" : { "$oid" : "54c29c61f1f6dbff33a7946a" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c61f1f6dbff33a7946b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c61f1f6dbff33a7946c" }, "plunkId" : "s3eVMQ8NYgBauI8IE5Da", "webPath" : "/task/menu-template/source", "files" : [ { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem;\n\n function getElem() {\n if (!elem) render();\n return elem;\n }\n\n function render() {\n var elemHtml = options.template({title: options.title});\n\n elem = $(elemHtml);\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.title', onTitleClick);\n }\n\n function renderItems() {\n if (elem.find('ul').length) return;\n\n var listHtml = options.listTemplate({items: options.items});\n elem.append(listHtml);\n }\n\n function onTitleClick(e) {\n toggle();\n }\n\n function open() {\n renderItems();\n elem.addClass('open');\n };\n\n function close() {\n elem.removeClass('open');\n };\n\n function toggle() {\n if (elem.hasClass('open')) close();\n else open();\n };\n\n this.getElem = getElem;\n this.toggle = toggle;\n this.close = close;\n this.open = open;\n}", "_id" : { "$oid" : "54c29c61f1f6dbff33a7946d" } }, { "filename" : "menu.css", "content" : ".menu ul {\n display: none;\n margin: 0;\n}\n\n.menu .title {\n font-weight: bold;\n cursor: pointer;\n background: url(//js.cx/clipart/arrow-right.png) left center no-repeat;\n padding-left: 18px;\n}\n\n.menu.open ul {\n display: block;\n}\n\n.menu.open .title {\n background-image: url(//js.cx/clipart/arrow-down.png);\n}", "_id" : { "$oid" : "54c29c61f1f6dbff33a7946e" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c61f1f6dbff33a7946f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c61f1f6dbff33a79470" }, "plunkId" : "3uJ46D4LqdaYdWI84kdA", "webPath" : "/article/template-lodash/menu-3-template", "files" : [ { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem;\n\n function getElem() {\n if (!elem) render();\n return elem;\n }\n\n function render() {\n var elemHtml = options.template({title: options.title});\n\n elem = $(elemHtml);\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.title', onTitleClick);\n }\n\n function renderItems() {\n if (elem.find('ul').length) return;\n\n var listHtml = options.listTemplate({items: options.items});\n elem.append(listHtml);\n }\n\n function onTitleClick(e) {\n toggle();\n }\n\n function open() {\n renderItems();\n elem.addClass('open');\n };\n\n function close() {\n elem.removeClass('open');\n };\n\n function toggle() {\n if (elem.hasClass('open')) close();\n else open();\n };\n\n this.getElem = getElem;\n this.toggle = toggle;\n this.close = close;\n this.open = open;\n}", "_id" : { "$oid" : "54c29c61f1f6dbff33a79471" } }, { "filename" : "menu.css", "content" : ".menu ul {\n display: none;\n margin: 0;\n}\n\n.menu .title {\n font-weight: bold;\n cursor: pointer;\n background: url(//js.cx/clipart/arrow-right.png) left center no-repeat;\n padding-left: 18px;\n}\n\n.menu.open ul {\n display: block;\n}\n\n.menu.open .title {\n background-image: url(//js.cx/clipart/arrow-down.png);\n}", "_id" : { "$oid" : "54c29c61f1f6dbff33a79472" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c61f1f6dbff33a79473" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c62f1f6dbff33a79476" }, "plunkId" : "Dl1r727EGbPU2jy1U8fS", "webPath" : "/task/voter-events/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n
      \n \n 0\n +\n
      \n\n\n\n\n", "_id" : { "$oid" : "54c29c62f1f6dbff33a79477" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c64f1f6dbff33a79479" }, "plunkId" : "BKkXOOheffKzdxxbmG8e", "webPath" : "/task/selectable-list-evented/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\nКлик на элементе выделяет только его.
      \nShift+Клик добавляет/убирает элемент из выделенных.
      \n\n
        \n
      • Винни-Пух
      • \n
      • Ослик Иа
      • \n
      • Мудрая Сова
      • \n
      • Кролик. Просто кролик.
      • \n
      \n\n\n\n", "_id" : { "$oid" : "54c29c64f1f6dbff33a7947a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c65f1f6dbff33a7947c" }, "plunkId" : "RGzI9yhozPcDgjyhhx0Z", "webPath" : "/task/custom-select/solution", "files" : [ { "filename" : "customselect.js", "content" : "function CustomSelect(options) {\n var self = this;\n\n var elem = options.elem;\n\n elem.on('click', '.customselect-title', onTitleClick);\n elem.on('click', 'li', onOptionClick);\n\n var isOpen = false;\n\n // ------ обработчики ------\n\n function onTitleClick(event) {\n toggle();\n }\n\n // закрыть селект, если клик вне его\n function onDocumentClick(event) {\n var isInside = $(event.target).closest(elem).length;\n if (!isInside) close();\n }\n\n function onOptionClick(event) {\n close();\n\n var name = $(event.target).html();\n var value = $(event.target).data('value');\n\n setValue(name, value);\n }\n\n // ------------------------\n\n function setValue(name, value) {\n elem.find('.customselect-title').html(name);\n\n $(self).triggerHandler({\n type: 'select',\n name: name,\n value: value\n });\n }\n\n function toggle() {\n if (isOpen) close()\n else open();\n }\n\n function open() {\n elem.addClass('customselect-open');\n $(document).on('click', onDocumentClick);\n isOpen = true;\n }\n\n function close() {\n elem.removeClass('customselect-open');\n $(document).off('click', onDocumentClick);\n isOpen = false;\n }\n\n}", "_id" : { "$oid" : "54c29c65f1f6dbff33a7947d" } }, { "filename" : "customselect.css", "content" : ".customselect {\n width: 200px;\n font-size: 14px;\n display: inline-block;\n}\n\n.customselect-title {\n height: 17px;\n border: 1px solid #ADD8E6;\n background-position: right;\n background-image: url(//js.cx/clipart/select-button.gif);\n background-repeat: no-repeat;\n padding: 2px;\n cursor: pointer;\n}\n\n.customselect-options li {\n padding: 2px;\n cursor: pointer;\n}\n\n.customselect-options li:nth-child(even) {\n background-color: #f0f8ff;\n}\n\n.customselect-options li:hover {\n background-color: #7fffd4;\n}\n\n.customselect-options {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n display: none;\n\n position: absolute;\n z-index: 1000;\n background: white;\n width: 200px;\n border-bottom: 1px solid #add8e6;\n border-left: 1px solid #add8e6;\n border-right: 1px solid #add8e6;\n box-sizing: border-box;\n}\n.customselect-open .customselect-options {\n display: block;\n}", "_id" : { "$oid" : "54c29c65f1f6dbff33a7947e" } }, { "filename" : "index.html", "content" : "\n\n\n Селект\n \n \n \n\n\n\n
      Последний результат: ...
      \n\n
      \n
      Выберите
      \n
        \n \n
      1. Птицы
      2. \n
      3. Рыбы
      4. \n
      5. Звери
      6. \n
      7. Динозавры
      8. \n
      9. Одноклеточные
      10. \n
      \n
      \n\n
      \n
      Выберите
      \n
        \n
      1. Плотоядные
      2. \n
      3. Травоядные
      4. \n
      5. Всеядные
      6. \n
      \n
      \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c65f1f6dbff33a7947f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c65f1f6dbff33a79480" }, "plunkId" : "spxTj0BIJmTP5hz37INd", "webPath" : "/task/custom-select/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n Селект\n \n \n \n\n\n\n
      Последний результат: ...
      \n\n\n\n
      \n
      Выберите
      \n
        \n \n
      1. Птицы
      2. \n
      3. Рыбы
      4. \n
      5. Звери
      6. \n
      7. Динозавры
      8. \n
      9. Одноклеточные
      10. \n
      \n
      \n\n
      \n
      Выберите
      \n
        \n
      1. Плотоядные
      2. \n
      3. Травоядные
      4. \n
      5. Всеядные
      6. \n
      \n
      \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c65f1f6dbff33a79481" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c65f1f6dbff33a79482" }, "plunkId" : "xeDuY2UvfCXACE7nR9xX", "webPath" : "/article/custom-events/menu-callback", "files" : [ { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem;\n\n function getElem() {\n if (!elem) render();\n return elem;\n }\n\n function render() {\n var elemHtml = options.template({title: options.title});\n\n elem = $(elemHtml);\n\n elem.on('mousedown selectstart', false);\n\n elem.on('click', '.title', onTitleClick);\n elem.on('click', 'a', onItemClick)\n }\n\n\n function renderItems() {\n if (elem.find('ul').length) return;\n\n var listHtml = options.listTemplate({items: options.items});\n elem.append(listHtml);\n }\n\n function onItemClick(e) {\n e.preventDefault();\n\n var onselect = options.onselect;\n if (onselect) {\n onselect(e.currentTarget.getAttribute('href').slice(1));\n }\n }\n\n function onTitleClick(e) {\n toggle();\n }\n\n function open() {\n renderItems();\n elem.addClass('open');\n };\n\n function close() {\n elem.removeClass('open');\n };\n\n function toggle() {\n if (elem.hasClass('open')) close();\n else open();\n };\n\n this.getElem = getElem;\n this.toggle = toggle;\n this.close = close;\n this.open = open;\n}", "_id" : { "$oid" : "54c29c65f1f6dbff33a79483" } }, { "filename" : "style.css", "content" : ".menu ul {\n display: none;\n margin: 0;\n}\n\n.menu .title {\n font-weight: bold;\n cursor: pointer;\n background: url(//js.cx/clipart/arrow-right.png) left center no-repeat;\n padding-left: 18px;\n}\n\n.menu.open ul {\n display: block;\n}\n\n.menu.open .title {\n background-image: url(//js.cx/clipart/arrow-down.png);\n}", "_id" : { "$oid" : "54c29c65f1f6dbff33a79484" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c65f1f6dbff33a79485" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c66f1f6dbff33a79486" }, "plunkId" : "czyTlStx1JcdWPQ89Ah0", "webPath" : "/article/custom-events/menu-event", "files" : [ { "filename" : "eventMixin.js", "content" : "var EventMixin = {\n\n /**\n * Подписка на событие\n * Использование:\n * menu.on('select', function(item) { ... }\n */\n on: function(eventName, handler) {\n if (!this._eventHandlers) this._eventHandlers = {};\n if (!this._eventHandlers[eventName]) {\n this._eventHandlers[eventName] = [];\n }\n this._eventHandlers[eventName].push(handler);\n },\n\n /**\n * Прекращение подписки\n * menu.off('select', handler)\n */\n off: function(eventName, handler) {\n var handlers = this._eventHandlers && this._eventHandlers[eventName];\n if (!handlers) return;\n for(var i=0; i\n\n\n \n \n \n \n \n \n\n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c66f1f6dbff33a7948a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c66f1f6dbff33a7948d" }, "plunkId" : "ipWFoMEQRh45q7fKo0fs", "webPath" : "/task/tooltip-over-element/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n

      ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

      \n

      ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

      \n

      ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

      \n\nСсылка с подсказкой\nЕще ссылка\n\n\n\n\n", "_id" : { "$oid" : "54c29c66f1f6dbff33a7948e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c67f1f6dbff33a7948f" }, "plunkId" : "fQatLX4keChREDQjXDfG", "webPath" : "/task/tooltip-over-element/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n

      ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

      \n

      ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

      \n

      ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя ЛяЛяЛя

      \n\nСсылка с подсказкой\nЕще ссылка\n\n\n\n\n", "_id" : { "$oid" : "54c29c67f1f6dbff33a79490" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c67f1f6dbff33a79492" }, "plunkId" : "PqM7RIyWwA60oJHAENKU", "webPath" : "/task/moving-tooltip/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\nСсылка с подсказкой\nЕще ссылка\n\n
      \n Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n
      \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c67f1f6dbff33a79493" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c68f1f6dbff33a79494" }, "plunkId" : "pjGpVT8O5FEW4IpvcGHW", "webPath" : "/task/moving-tooltip/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\nСсылка с подсказкой\nЕще ссылка\n\n
      \n Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n
      \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c68f1f6dbff33a79495" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c68f1f6dbff33a79497" }, "plunkId" : "ag0GudZGXCkLQTNRMfpr", "webPath" : "/task/resize-img/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n
      \n\n\n\n\n", "_id" : { "$oid" : "54c29c68f1f6dbff33a79498" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c68f1f6dbff33a79499" }, "plunkId" : "Q117PCOoHuBqE1BmE3SC", "webPath" : "/task/resize-img/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\nКартинка для декорации правого-нижнего угла: \n\n
      \n\n\n\n\n", "_id" : { "$oid" : "54c29c68f1f6dbff33a7949a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c69f1f6dbff33a7949c" }, "plunkId" : "Q107ZUNWEXVniReXIRdN", "webPath" : "/task/img-select-mouse/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n
      \n\n\n\n", "_id" : { "$oid" : "54c29c69f1f6dbff33a7949d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c69f1f6dbff33a7949e" }, "plunkId" : "QYaS5h5wZqh1ffkxTNd7", "webPath" : "/task/img-select-mouse/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n
      \n\n\n\n", "_id" : { "$oid" : "54c29c69f1f6dbff33a7949f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c69f1f6dbff33a794a1" }, "plunkId" : "bF8p7ohc0EEFFxW7At3F", "webPath" : "/task/menu-animated/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
      \n\n
      \n Сладости (наведи курсор)!\n \n\n
      \n\n\n\n\n", "_id" : { "$oid" : "54c29c69f1f6dbff33a794a2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6af1f6dbff33a794a3" }, "plunkId" : "Wy9lhppMbqx7hdfx2Ezd", "webPath" : "/task/menu-animated/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
      \n\n
      \n Сладости (наведи курсор)!\n \n\n
      \n\n\n\n\n", "_id" : { "$oid" : "54c29c6af1f6dbff33a794a4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6af1f6dbff33a794a6" }, "plunkId" : "TAv6zjXIwwnCsl6uedUN", "webPath" : "/task/slider-events/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n
      \n
      \n
      \n\nSlide: \nChange: \n\n\n\n\n", "_id" : { "$oid" : "54c29c6af1f6dbff33a794a7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6bf1f6dbff33a794a9" }, "plunkId" : "kWmy8Z7Ixx0PQi8e9utE", "webPath" : "/task/calendar/solution", "files" : [ { "filename" : "calendar.js", "content" : "/**\n * options:\n * value Date или объект {year,month,day}} -- дата, для которой показывать календарь\n * если в объекте указаны только {year,month}, то день не выбран\n*/\nfunction Calendar(options) {\n var self = this;\n\n var monthNames = 'Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь'.split(' ');\n\n var elem;\n var year, month, day;\n\n var showYear, showMonth;\n\n parseValue(options.value);\n\n // -----------------------\n\n this.getElement = function() {\n if (!elem) {\n render();\n }\n return elem;\n };\n\n this.getValue = function() {\n return day ? new Date(year, month, day) : null;\n };\n\n function parseValue(value) {\n if (value instanceof Date) {\n year = value.getFullYear();\n month = value.getMonth();\n day = value.getDate();\n } else {\n year = value.year;\n month = value.month;\n day = value.day;\n }\n }\n\n /**\n * Установить значение календаря\n * @param newValue {Date или объект {year,month[,day]} Новое значение\n * @param quiet Если true, то событие не генерируется\n */\n this.setValue = function(newValue, quiet) {\n parseValue(newValue);\n\n if (elem) {\n clearSelected();\n render();\n }\n\n if (!quiet) {\n $(self).triggerHandler({\n type: \"select\",\n value: new Date(year, month, day)\n });\n }\n };\n\n function render() {\n if (!elem) {\n elem = $('
      ')\n .on('click', '.date-cell', onDateCellClick);\n }\n\n if (showYear != year || showMonth != month) {\n elem.html(renderCalendarTable(year, month));\n elem.find('caption').html(monthNames[month]+' '+year);\n showYear = year;\n showMonth = month;\n }\n\n if (day) {\n var num = getCellByDate(new Date(year, month, day));\n elem.find('td').eq(num).addClass(\"selected\");\n }\n\n }\n\n function clearSelected() {\n elem.find('.selected').removeClass('selected');\n }\n\n\n function onDateCellClick(e) {\n day = $(e.target).html();\n self.setValue({year: year, month: month, day: day});\n }\n\n\n /**\n * Возвращает по дате номер TD в таблице\n * Использование:\n * var td = table.getElementsByTagName('td')[getCellByDate(date)]\n */\n function getCellByDate(date) {\n var dateDayOne = new Date(date.getFullYear(), date.getMonth(), 1);\n\n return getDay(dateDayOne) + date.getDate() - 1;\n }\n\n /**\n * получить номер дня недели для date, от 0(пн) до 6(вс)\n * @param date\n */\n function getDay(date) { //\n var day = date.getDay();\n if (day == 0) day = 7;\n return day - 1;\n }\n\n /**\n * Генерирует таблицу для календаря заданного месяца/года\n */\n function renderCalendarTable(year, month) {\n\n var d = new Date(year, month);\n\n var table = [''];\n\n for (var i=0; i');\n }\n\n // ячейки календаря с датами\n while(d.getMonth() == month) {\n table.push('');\n\n if (getDay(d) % 7 == 6) { // вс, последний день - перевод строки\n table.push('');\n }\n\n d.setDate(d.getDate()+1);\n }\n\n // добить таблицу пустыми ячейками, если нужно\n if (getDay(d) != 0) {\n for (var i=getDay(d); i<7; i++) {\n table.push('');\n }\n }\n\n table.push('
      пнвтсрчтптсбвс
      '+d.getDate()+'
      ');\n\n return table.join('\\n')\n }\n\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794aa" } }, { "filename" : "calendar.css", "content" : ".calendar-table {\n border-collapse: collapse;\n}\n\n.calendar-table td, .calendar-table th {\n border: 1px solid black;\n padding: 3px;\n text-align: center;\n}\n\n.calendar-table th {\n font-weight: bold;\n background-color: #E6E6E6;\n}\n\n.date-cell:hover {\n background: #eee;\n cursor: pointer;\n}\n\n.date-cell.selected {\n background: #0F0;\n}\n\n.calendar-table caption {\n text-align: center;\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794ab" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n\n\n\n
      \n
      тут будет выбранное значение (дата)
      \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794ac" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6bf1f6dbff33a794ad" }, "plunkId" : "ldairy0YKnocvOPIT4C1", "webPath" : "/task/calendar/source", "files" : [ { "filename" : "calendar-table.js", "content" : "/**\n * Возвращает по дате номер TD в таблице\n * Использование:\n * var td = table.find('td').eq(getCellByDate(date))\n*/\nfunction getCellByDate(date) {\n var date1 = new Date(date.getFullYear(), date.getMonth(), 1);\n\n return getDay(date1) + date.getDate() - 1;\n}\n\n/**\n * получить номер дня недели для date, от 0(пн) до 6(вс)\n * @param date\n */\nfunction getDay(date) { //\n var day = date.getDay();\n if (day == 0) day = 7;\n return day - 1;\n}\n\n/**\n * Генерирует таблицу для календаря заданного месяца/года\n * @param year\n * @param month\n */\nfunction renderCalendarTable(year, month) {\n\n var d = new Date(year, month);\n\n var table = [''];\n\n for (var i=0; i');\n }\n\n // ячейки календаря с датами\n while(d.getMonth() == month) {\n table.push('');\n\n if (getDay(d) % 7 == 6) { // вс, последний день - перевод строки\n table.push('');\n }\n\n d.setDate(d.getDate()+1);\n }\n\n // добить таблицу пустыми ячейками, если нужно\n if (getDay(d) != 0) {\n for (var i=getDay(d); i<7; i++) {\n table.push('');\n }\n }\n\n table.push('
      пнвтсрчтптсбвс
      '+d.getDate()+'
      ');\n\n return table.join('\\n')\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794ae" } }, { "filename" : "calendar.js", "content" : "/**\n * options:\n * year/month {number} год/месяц для календаря\n * value {Date} текущая выбранная дата\n*/\nfunction Calendar(options) {\n var monthNames = 'Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь'.split(' ');\n\n /* ваш код */\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794af" } }, { "filename" : "calendar.css", "content" : ".calendar-table {\n border-collapse: collapse;\n}\n\n.calendar-table td, .calendar-table th {\n border: 1px solid black;\n padding: 3px;\n text-align: center;\n}\n\n.calendar-table th {\n font-weight: bold;\n background-color: #E6E6E6;\n}\n\n.date-cell:hover {\n background: #eee;\n cursor: pointer;\n}\n\n.date-cell.selected {\n background: #0F0;\n}\n\n.calendar-table caption {\n text-align: center;\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b0" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n\n\n\n
      \n
      тут будет выбранное значение (дата)
      \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b3" }, "plunkId" : "nqwetLSbrnGRw8raJk4L", "webPath" : "/task/autocomplete/solution", "files" : [ { "filename" : "autocomplete-list.js", "content" : "function AutocompleteList(provider) {\n var elem;\n\n var filteredResults;\n var currentIndex = 0;\n\n this.render = function() {\n elem = $('
        ');\n return elem;\n };\n\n this.update = function(value) {\n filteredResults = provider.filterByStart(value);\n\n if (filteredResults.length) {\n elem.html( '
      1. ' + filteredResults.join('
      2. ') + '
      3. ' );\n } else {\n elem.empty();\n }\n\n currentIndex = 0;\n renderCurrent();\n\n // это событие, как и всё обновление,\n // может быть асинхронным (при получении списка с сервера)\n $(this).triggerHandler({\n type: 'update',\n values: filteredResults\n });\n\n };\n\n function renderCurrent() {\n elem.children().eq(currentIndex).addClass('selected');\n }\n\n function clearCurrent() {\n elem.children().eq(currentIndex).removeClass('selected');\n }\n\n this.get = function() {\n return filteredResults[currentIndex];\n };\n\n this.down = function() {\n if (currentIndex == filteredResults.length - 1) return;\n clearCurrent();\n currentIndex++;\n renderCurrent();\n };\n\n this.up = function() {\n if (currentIndex == 0) return;\n clearCurrent();\n currentIndex--;\n renderCurrent();\n };\n\n this.clear = function() {\n this.update('');\n };\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b4" } }, { "filename" : "autocomplete.js", "content" : "function Autocomplete(options) {\n var self = this;\n\n var elem = options.elem;\n\n var input = $('input', elem);\n var list;\n\n input.on({\n focus: onInputFocus,\n blur: onInputBlur,\n keydown: onInputKeyDown\n });\n\n var inputCheckTimer;\n\n // ------------------\n\n function onInputKeyDown(e) {\n var KEY_ARROW_UP = 38;\n var KEY_ARROW_RIGHT = 39;\n var KEY_ARROW_DOWN = 40;\n var KEY_ENTER = 13;\n var KEY_ESC = 27;\n\n switch(e.keyCode) {\n case KEY_ARROW_UP:\n list.up();\n return false;\n break;\n\n case KEY_ARROW_RIGHT:\n if (list.get()) {\n self.setValue( list.get(), true );\n }\n break;\n\n case KEY_ENTER:\n self.setValue( list.get() || input.val() );\n input.blur();\n break;\n\n case KEY_ESC:\n list.clear();\n break;\n\n case KEY_ARROW_DOWN:\n list.down();\n return false;\n break;\n }\n\n }\n\n function initList() {\n list = new AutocompleteList(options.provider);\n list.render().appendTo(elem);\n $(list).on('update', onListUpdate);\n }\n\n function onListUpdate(e) {\n if (e.values.length) {\n elem.addClass('open');\n } else {\n elem.removeClass('open');\n }\n }\n\n function onInputFocus() {\n var inputValue = input.val();\n function checkInput() {\n if (inputValue != input.val()) {\n\n if (!list) {\n initList();\n }\n\n list.update(input.val());\n inputValue = input.val();\n }\n }\n\n inputCheckTimer = setInterval(checkInput, 30);\n }\n\n function onInputBlur() {\n clearInterval(inputCheckTimer);\n if (list) {\n list.clear();\n }\n }\n\n this.setValue = function(value, quiet) {\n input.val(value);\n if (!quiet) {\n $(self).triggerHandler({\n type: 'change',\n value: value\n });\n }\n }\n\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b5" } }, { "filename" : "filtering-list-provider.js", "content" : "function FilteringListProvider(strings) {\n\n this.get = function(index) {\n return strings[index];\n };\n\n this.filterByStart = function(stringStart) {\n if (stringStart.length < 2) return [];\n\n var stringStartLC = stringStart.toLowerCase();\n\n return strings.filter(function(str) {\n var strLC = str.toLowerCase();\n\n return strLC.slice(0, stringStartLC.length) == stringStartLC && strLC != stringStartLC;\n });\n }\n\n\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b6" } }, { "filename" : "autocomplete.css", "content" : ".autocomplete ol {\n display: none;\n margin: 0;\n padding: 3px;\n border: 1px solid gray;\n list-style: none;\n}\n\n.autocomplete input {\n -moz-box-sizing: border-box;\n\n box-sizing: border-box;\n margin: 0;\n padding: 1px 0 1px 3px;\n\n width: 100%;\n\n border: 1px solid blue;\n border-radius: 3px;\n -webkit-appearance: none;\n\n font-size: 16px;\n}\n\n.autocomplete input:focus {\n outline: none;\n}\n\n.autocomplete.open input {\n border-bottom: none;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.autocomplete.open ol {\n display: block;\n\n background: white;\n z-index: 10000;\n position: relative;\n}\n\n.autocomplete {\n width: 400px;\n height: 20px;\n}\n\n.autocomplete ol .selected {\n background: blue;\n}", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b7" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n \n\n\n\n
        \n\n \n\n
        \n\n
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam explicabo nostrum eum placeat aliquid voluptatem nihil modi libero nulla tempore dolore itaque accusamus distinctio veniam quae voluptatibus suscipit provident quas quaerat tempora sequi magnam.
        \n\n\n \n\n", "_id" : { "$oid" : "54c29c6bf1f6dbff33a794b8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6cf1f6dbff33a794ba" }, "plunkId" : "DEhoSLPTLDeHe52EiOX5", "webPath" : "/task/hover-menu-onclick/solution", "files" : [ { "filename" : "hoverintent.js", "content" : "/**\n * Taken from jQuery UI accordion and fixed, special hoverintent event\n * http://benalman.com/news/2010/03/jquery-special-events/\n */\n!function($) {\n\n\n var cfg = {\n sensitivity: 9,\n interval: 50\n };\n\n\n $.event.special.hoverintent = {\n setup: function() {\n $(this).on(\"mouseover\", handler);\n },\n\n teardown: function() {\n $(this).on(\"mouseover\", handler);\n },\n\n cfg: cfg\n };\n\n function handler(event) {\n\n var self = this,\n args = arguments,\n target = $(event.target),\n cX, cY, pX, pY;\n\n function track(event) {\n cX = event.pageX;\n cY = event.pageY;\n };\n pX = event.pageX;\n pY = event.pageY;\n\n function clear() {\n target.off(\"mousemove\", track).off(\"mouseout\", clear);\n clearTimeout(timeout);\n }\n\n function handler() {\n if((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {\n clear();\n event.type = \"hoverintent\";\n jQuery.event.simulate(\"hoverintent\", event.target, $.event.fix(event), true);\n } else {\n pX = cX;\n pY = cY;\n timeout = setTimeout(handler, cfg.interval);\n }\n }\n var timeout = setTimeout(handler, cfg.interval);\n target.mousemove(track).mouseout(clear);\n return true;\n }\n\n\n}(jQuery);", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794bb" } }, { "filename" : "menu.js", "content" : "function Menu(options) {\n var elem = options.elem;\n var self = this;\n\n var activeLi;\n\n elem.on('click', 'a.title', onTitleClick);\n\n // item clicks are all inside ol\n elem.on('click', 'ol a', onLiClick);\n\n // I use \"a\" here instead of LI, because hover on LI also works if going over it's child container OL\n // child container may have paddings etc, so the click may happen on that OL, outside of this item\n elem.on('hoverintent', 'ol a', onLiHoverIntent);\n\n // ----------------------\n\n function onLiClick(e) {\n\n close();\n\n var li = $(e.currentTarget).closest('li');\n\n $(self).triggerHandler({\n type: 'select',\n value: getLiValue(li)\n });\n\n return false;\n }\n\n function onTitleClick() {\n if (elem.hasClass('open')) {\n close();\n } else {\n open();\n }\n }\n\n function onLiHoverIntent(e) {\n var li = $(this).closest('li');\n\n if (isActiveLi(li)) return;\n\n activateLi(li);\n openChildren();\n }\n\n // ----------------------\n\n function isActiveLi(li) {\n if (activeLi && activeLi[0] == li[0]) return true;\n return false;\n }\n\n\n function close(argument) {\n\n elem.removeClass('open');\n\n if (activeLi) {\n activeLi.parentsUntil(elem).andSelf().removeClass('active');\n activeLi = null;\n }\n\n $(document).off('.menu-nested');\n }\n\n function getLiValue(li) {\n if (!li.length) return null;\n return li.children('a').attr('href').slice(2);\n }\n\n function open() {\n\n elem.addClass('open');\n\n // TODO: close menu on document click outside of it\n $(document).on('click.menu-nested', function(e) {\n if ( $(e.target).closest(elem).length ) return;\n close();\n });\n }\n\n function getParentLi(li) {\n return li.parent().parent();\n }\n\n function activateLi(li) {\n\n if (activeLi && getParentLi(li)[0] != activeLi[0]) { // if (new li is not child of activeLi)\n // not a child item, then need to close currently active ones\n // collapse parents of last active until container of new element\n collapseActiveUntil(li);\n }\n\n activeLi = li;\n activeLi.addClass(\"active\");\n }\n\n function collapseActiveUntil(li) {\n\n var el = activeLi;\n for(;;) {\n el.removeClass('active');\n if (el[0].parentNode == li[0].parentNode) break;\n el = getParentLi(el);\n }\n\n }\n\n function openChildren() {\n var subcontainer = activeLi.children('ol');\n if (!subcontainer.length) return;\n\n // show children\n\n var left = activeLi.width(); // to the right of the parent\n var top = activeLi.position().top; // at same height as current parent\n\n // lift it up, so that first subchild will be aligned with the parent\n top -= subcontainer.children('li').position().top;\n top -= subcontainer.prop('clientTop')\n\n subcontainer.css({\n left: left,\n top: top\n })\n }\n\n}", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794bc" } }, { "filename" : "menu.css", "content" : ".menu::before {\n content: '☞';\n font-size: 16px;\n float: left;\n}\n\n\n.menu.open::before {\n content: '☟';\n}\n\n.menu a {\n text-decoration: none;\n color: black;\n display: block;\n}\n\n.menu > a {\n display: inline;\n}\n\n.menu a {\n padding: 3px 5px;\n white-space: nowrap;\n}\n\nli.active > a {\n background: blue;\n color: white;\n}\n\n.menu ol {\n margin: 0;\n padding: 3px 0;\n list-style: none;\n display: none;\n background: #eee;\n border: 1px solid black;\n position: absolute;\n}\n\n.menu.open > ol {\n display: block;\n margin-left: 16px;\n}\n\n.menu li.has-children > a::after {\n content: ' >';\n}\n\n.menu li.active > ol {\n display: block;\n}", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794bd" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n\n\n\n \n \n Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor eos.\n\n \n\n\n", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794be" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6cf1f6dbff33a794c2" }, "plunkId" : "jHQVNDqu5x9iuKymSD8G", "webPath" : "/task/date-selector/solution", "files" : [ { "filename" : "dateselector.js", "content" : "/**\n * options:\n * yearFrom {number} начальный год в селекторе\n * yearTo {number} конечный год в селекторе\n * value {Date} текущая выбранная дата\n*/\nfunction DateSelector(options) {\n var self = this;\n\n var monthNames = 'января февраля марта апреля мая июня июля августа сентября октября ноября декабря'.split(' ');\n\n var value = options.value;\n\n var elem;\n var yearSelect, monthSelect, daySelect;\n\n function render() {\n var tmpl = _.template( options.template );\n elem = $('
        ').html(tmpl({\n yearFrom: options.yearFrom,\n yearTo: options.yearTo,\n dayTo: getLastDayOfMonth(value.getFullYear(), value.getMonth()),\n monthNames: monthNames\n }));\n\n yearSelect = elem.find('.year');\n monthSelect = elem.find('.month');\n daySelect = elem.find('.day');\n\n elem.on('change', onChange); // обычно оно не всплывает, но jQuery эмулирует всплытие\n self.setValue(value, true);\n }\n\n this.getValue = function() {\n return value;\n };\n\n this.setValue = function(newValue, quiet) {\n value = newValue;\n\n yearSelect.val(value.getFullYear());\n monthSelect.val(value.getMonth());\n daySelect.val(value.getDate());\n\n if (!quiet) {\n $(self).triggerHandler({\n type: \"select\",\n value: value\n });\n }\n };\n\n this.getElement = function() {\n if (!elem) render();\n return elem;\n };\n\n function onChange(e) {\n\n var selectType = e.target.className;\n\n if (selectType == \"month\" || selectType == \"year\") {\n // поправить день с учетом месяца и, возможно, високосного года\n adjustDayOptions(+yearSelect.val(), +monthSelect.val());\n }\n\n readValue(); // для простоты -- получим значения из всех селектов\n\n $(self).triggerHandler({\n type: \"select\",\n value: value\n });\n }\n\n function readValue() {\n // если я сделаю сначала value.setMonth(),\n // то может получится некорректная дата типа 31 марта -> 31 февраля,\n // которая автоскорректируется в 2 марта, т.е месяц не поставится.\n // поэтому сначала именно setDate, и так далее.\n value.setDate(daySelect.val());\n value.setMonth(monthSelect.val());\n value.setFullYear(yearSelect.val());\n }\n\n function getLastDayOfMonth(year, month) {\n var date = new Date(year, month+1, 0);\n return date.getDate();\n }\n\n function adjustDayOptions(year, month) {\n var maxDay = getLastDayOfMonth(year, month);\n\n // укоротить селект, если дней стало меньше\n daySelect.children().filter(function() {\n return this.value > maxDay;\n }).remove();\n\n // добавить дни, если новый месяц дольше\n for(var i = +daySelect.last().val(); i <= maxDay; i++) {\n daySelect.append(new Option(i, i));\n }\n }\n\n}", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794c3" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n\n\n
        \n
        тут будет значение даты при выборе
        \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794c4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6cf1f6dbff33a794c5" }, "plunkId" : "ZmYNBu36cagnqp4Qjggj", "webPath" : "/task/date-selector/source", "files" : [ { "filename" : "dateselector.js", "content" : "/**\n * options:\n * yearFrom {number} начальный год в селекторе\n * yearTo {number} конечный год в селекторе\n * value {Date} текущая выбранная дата\n*/\nfunction DateSelector(options) {\n var self = this;\n\n\n /* ваш код */\n}", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794c6" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\n\n\n
        \n
        тут будет значение даты при выборе
        \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6cf1f6dbff33a794c7" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6df1f6dbff33a794c9" }, "plunkId" : "851L7nOQc33UBaxmng8g", "webPath" : "/task/draggable-windows/solution", "files" : [ { "filename" : "draggableWindow.js", "content" : "// если начать перенос и передвинуть мышь максимально вверх -- верхний край окна не должен вылетать за край страницы.\n// в другие стороны\n\n// чтобы даже при резких движениях мыши -- окно прилипало к краю но не вылезало за край\n// исключение -- максимальная нижняя позиция окна -- это когда только заголовок виден\n\n// позиция мыши смещается\nfunction DraggableWindow(options) {\n var self = this;\n\n var title = options.title;\n var template = typeof options.template == 'function' ? // компиляция, если строка\n options.template : _.template(options.template);\n\n var elem, contentElem;\n\n var mouseDownShift;\n\n function render() {\n elem = $('
        ', {\n \"class\": \"window\",\n html: template({\n title: title\n })\n });\n\n $('form', elem).on('submit', onSubmit);\n\n titleElem = elem.find('.window-title');\n\n titleElem.on('selectstart dragstart', false);\n titleElem.on('mousedown', onTitleMouseDown);\n\n contentElem = elem.find('.window-content'); // = children[1]\n }\n\n this.getElement = function() {\n if (!elem) render();\n return elem;\n }\n\n function onTitleMouseDown(e) {\n startDrag(e.pageX, e.pageY);\n return false;\n };\n\n function startDrag(mouseDownX, mouseDownY) {\n // запомнить координаты нажатия\n var coords = elem.offset();\n mouseDownShift = {\n x: mouseDownX - coords.left,\n y: mouseDownY - coords.top\n };\n\n // двигать\n $(document).on({\n 'mousemove.draggablewindow': onDocumentMouseMove,\n 'mouseup.draggablewindow': onDocumentMouseUp\n });\n\n elem.addClass('window-moving');\n }\n\n function onDocumentMouseUp() {\n $(document).off('.draggablewindow');\n elem.removeClass('window-moving');\n }\n\n function onDocumentMouseMove(e) {\n moveWindowAtCursor(e.pageX, e.pageY);\n }\n\n function moveWindowAtCursor(pageX, pageY) {\n var newLeft = pageX - mouseDownShift.x;\n var newTop = pageY - mouseDownShift.y;\n\n // проверим, не вылезем ли мы за границы экрана\n var windowLeft = window.pageXOffset || document.documentElement.scrollLeft;\n var windowTop = window.pageYOffset || document.documentElement.scrollTop;\n var windowRight = windowLeft + document.documentElement.clientWidth;\n var windowBottom = windowTop + document.documentElement.clientHeight;\n\n // тут не if..else, а if т.к., возможно, обе координаты надо поправить\n if (newLeft < windowLeft) {\n newLeft = windowLeft;\n }\n if (newLeft > windowRight - elem.outerWidth()) {\n newLeft = windowRight - elem.outerWidth(); // внешняя ширина с учетом рамки внешней\n }\n if (newTop < windowTop) {\n newTop = windowTop;\n }\n if (newTop > windowBottom - titleElem.outerHeight()) {\n newTop = windowBottom - titleElem.outerHeight();\n // внизу заголовок будет немного залезать за край, т.к. нужно мерять вместе с рамкой верхней на самом деле\n // но здесь это не страшно\n }\n\n elem.css({\n left: newLeft,\n top: newTop\n });\n };\n\n function onSubmit(e) {\n // принять события, совершить обработку события, связанную с формой\n var form = e.currentTarget;\n var value = form.elements.message.value;\n form.elements.message.value = '';\n if (value) {\n submit(value); // логика по отправке сообщения\n }\n return false;\n }\n\n function submit(message) {\n // добавить\n var newMessageElem = $('
        ', {text: message }).appendTo(contentElem);\n\n // прокрутить к новому сообщению\n contentElem.prop('scrollTop', 999999999);\n }\n\n\n}", "_id" : { "$oid" : "54c29c6df1f6dbff33a794ca" } }, { "filename" : "window.css", "content" : ".window {\n position: absolute;\n left: 0;\n top: 0;\n z-index: 10;\n\n width: 200px;\n height: 300px;\n border: 2px #ADD8E6 groove;\n /* раскомментировать для проверки, вылезает ли внешняя рамка за экран\n border: 2px red solid;\n */\n background: white;\n}\n\n.window-title {\n width: 100%;\n height: 30px;\n line-height: 30px;\n\n background-color: #4169E1;\n color: white;\n text-align:center;\n cursor: pointer;\n}\n\n.window-moving .window-title {\n cursor: move;\n}\n\n.window-message-form {\n position: absolute;\n bottom: 0;\n height: 30px;\n line-height: 30px;\n width: 100%;\n\n background: #ADD8E6;\n}\n\n.window-content {\n height: 240px;\n padding: 3px;\n overflow-y: auto;\n}\n\n.window-message-text {\n width: 120px;\n}\n\n.window-message-submit {\n width: 70px;\n margin-left: 2px;\n}", "_id" : { "$oid" : "54c29c6df1f6dbff33a794cb" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n \n\n\n\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6df1f6dbff33a794cc" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6df1f6dbff33a794cd" }, "plunkId" : "dSzGa6Q4DxwJnJ7gej1P", "webPath" : "/task/draggable-windows/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n\n\n\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6df1f6dbff33a794ce" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6ef1f6dbff33a794d0" }, "plunkId" : "9kLjscDoI4EyKAULwL5y", "webPath" : "/task/window-manager/solution", "files" : [ { "filename" : "draggableWindow.js", "content" : "// если начать перенос и передвинуть мышь максимально вверх -- верхний край окна не должен вылетать за край страницы.\n// в другие стороны\n\n// чтобы даже при резких движениях мыши -- окно прилипало к краю но не вылезало за край\n// исключение -- максимальная нижняя позиция окна -- это когда только заголовок виден\n\n// позиция мыши смещается\nfunction DraggableWindow(options) {\n var self = this;\n\n var title = options.title;\n var template = typeof options.template == 'function' ? // компиляция, если строка\n options.template : _.template(options.template);\n\n var elem, contentElem;\n\n var mouseDownShift;\n\n function render() {\n elem = $('
        ').html(template({\n title: title\n }));\n\n $('form', elem).on('submit', onSubmit);\n\n titleElem = elem.find('.window-title');\n\n titleElem.on('selectstart dragstart', false);\n titleElem.on('mousedown', onTitleMouseDown);\n\n contentElem = elem.find('.window-content'); // = children[1]\n elem.on('focusin', onFocus);\n }\n\n this.getElement = function() {\n if (!elem) render();\n return elem;\n }\n\n function onFocus() {\n $(self).triggerHandler({ type: 'focus' });\n }\n\n function onTitleMouseDown(e) {\n startDrag(e.pageX, e.pageY);\n\n setTimeout(onFocus, 0);\n return false; // returning false prevents onfocus\n };\n\n function startDrag(mouseDownX, mouseDownY) {\n // запомнить координаты нажатия\n var coords = elem.offset();\n mouseDownShift = {\n x: mouseDownX - coords.left,\n y: mouseDownY - coords.top\n };\n\n // двигать\n $(document).on({\n 'mousemove.draggablewindow': onDocumentMouseMove,\n 'mouseup.draggablewindow': onDocumentMouseUp\n });\n\n elem.addClass('window-moving');\n }\n\n function onDocumentMouseUp() {\n $(document).off('.draggablewindow');\n elem.removeClass('window-moving');\n }\n\n function onDocumentMouseMove(e) {\n moveWindowAtCursor(e.pageX, e.pageY);\n }\n\n function moveWindowAtCursor(pageX, pageY) {\n var newLeft = pageX - mouseDownShift.x;\n var newTop = pageY - mouseDownShift.y;\n\n // проверим, не вылезем ли мы за границы экрана\n var windowLeft = window.pageXOffset || document.documentElement.scrollLeft;\n var windowTop = window.pageYOffset || document.documentElement.scrollTop;\n var windowRight = windowLeft + document.documentElement.clientWidth;\n var windowBottom = windowTop + document.documentElement.clientHeight;\n\n // тут не if..else, а if т.к., возможно, обе координаты надо поправить\n if (newLeft < windowLeft) {\n newLeft = windowLeft;\n }\n if (newLeft > windowRight - elem.outerWidth()) {\n newLeft = windowRight - elem.outerWidth(); // внешняя ширина с учетом рамки внешней\n }\n if (newTop < windowTop) {\n newTop = windowTop;\n }\n if (newTop > windowBottom - titleElem.outerHeight()) {\n newTop = windowBottom - titleElem.outerHeight();\n // внизу заголовок будет немного залезать за край, т.к. нужно мерять вместе с рамкой верхней на самом деле\n // но здесь это не страшно\n }\n\n elem.css({\n left: newLeft,\n top: newTop\n });\n };\n\n function onSubmit(e) {\n // принять события, совершить обработку события, связанную с формой\n var form = e.currentTarget;\n var value = form.elements.message.value;\n form.elements.message.value = '';\n if (value) {\n submit(value); // логика по отправке сообщения\n }\n return false;\n }\n\n function submit(message) {\n // добавить\n var newMessageElem = $('
        ', {text: message }).appendTo(contentElem);\n\n // прокрутить к новому сообщению\n contentElem.prop('scrollTop', 999999999);\n }\n\n\n this.setZIndex = function(zIndex) {\n elem.css('z-index', zIndex);\n };\n\n this.getZIndex = function() {\n return +elem.css('z-index') || 0;\n };\n\n this.toString = function() {\n return \"[Window \" + options.title + \" \" + elem.css('z-index') + \"]\";\n }\n\n}", "_id" : { "$oid" : "54c29c6ef1f6dbff33a794d1" } }, { "filename" : "windowManager.js", "content" : "var WindowManager = new function() {\n\n var windows = [];\n var activeWindow;\n\n var template;\n\n this.setTemplate = function(newTemplate) {\n template = _.template(newTemplate);\n };\n\n this.addWindow = function(options) {\n\n var win = new DraggableWindow({\n title: options.title,\n template: template\n });\n\n $(win).on(\"focus\", function() {\n activateWindow(this);\n });\n\n win.getElement().appendTo('body');\n\n windows.push(win);\n activateWindow(win);\n\n return win;\n }\n\n function activateWindow(win) {\n if (activeWindow == win) return;\n activeWindow = win;\n sortWindows();\n }\n\n /**\n * пересортировать окна\n */\n function sortWindows() {\n windows.sort(function(a, b) {\n if (activeWindow == a) return 1; // активное окно больше всех\n if (activeWindow == b) return -1; // активное окно больше всех\n return a.getZIndex() - b.getZIndex(); // порядок среди остальных - оставляем \"как есть\"\n });\n for(var i=0; i\n\n\n \n \n \n \n \n \n \n\n\n\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\nТекст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6ef1f6dbff33a794d4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6ff1f6dbff33a794d6" }, "plunkId" : "uhmofXLtR7neIAiyllJj", "webPath" : "/task/double-calendar-with-arrows/solution", "files" : [ { "filename" : "calendar.js", "content" : "/**\n * options:\n * value Date или объект {year,month,day}} -- дата, для которой показывать календарь\n * если в объекте указаны только {year,month}, то день не выбран\n*/\nfunction Calendar(options) {\n var self = this;\n\n var monthNames = 'Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь'.split(' ');\n\n var elem;\n var year, month, day;\n\n var showYear, showMonth;\n\n parseValue(options.value);\n\n // -----------------------\n\n this.getElement = function() {\n if (!elem) {\n render();\n }\n return elem;\n };\n\n this.getValue = function() {\n return day ? new Date(year, month, day) : null;\n };\n\n function parseValue(value) {\n if (value instanceof Date) {\n year = value.getFullYear();\n month = value.getMonth();\n day = value.getDate();\n } else {\n year = value.year;\n month = value.month;\n day = value.day;\n }\n }\n\n /**\n * Установить значение календаря\n * @param newValue {Date или объект {year,month[,day]} Новое значение\n * @param quiet Если true, то событие не генерируется\n */\n this.setValue = function(newValue, quiet) {\n parseValue(newValue);\n\n if (elem) {\n clearSelected();\n render();\n }\n\n if (!quiet) {\n $(self).triggerHandler({\n type: \"select\",\n value: new Date(year, month, day)\n });\n }\n };\n\n this.clearValue = function() {\n day = null;\n clearSelected();\n };\n\n function render() {\n if (!elem) {\n elem = $('
        ')\n .on('click', '.date-cell', onDateCellClick);\n }\n\n if (showYear != year || showMonth != month) {\n elem.html(renderCalendarTable(year, month));\n elem.find('caption').html(monthNames[month]+' '+year);\n showYear = year;\n showMonth = month;\n }\n\n if (day) {\n var num = getCellByDate(new Date(year, month, day));\n elem.find('td').eq(num).addClass(\"selected\");\n }\n\n }\n\n function clearSelected() {\n elem.find('.selected').removeClass('selected');\n }\n\n\n function onDateCellClick(e) {\n day = $(e.target).html();\n self.setValue({year: year, month: month, day: day});\n }\n\n\n /**\n * Возвращает по дате номер TD в таблице\n * Использование:\n * var td = table.getElementsByTagName('td')[getCellByDate(date)]\n */\n function getCellByDate(date) {\n var dateDayOne = new Date(date.getFullYear(), date.getMonth(), 1);\n\n return getDay(dateDayOne) + date.getDate() - 1;\n }\n\n /**\n * получить номер дня недели для date, от 0(пн) до 6(вс)\n * @param date\n */\n function getDay(date) { //\n var day = date.getDay();\n if (day == 0) day = 7;\n return day - 1;\n }\n\n /**\n * Генерирует таблицу для календаря заданного месяца/года\n */\n function renderCalendarTable(year, month) {\n\n var d = new Date(year, month);\n\n var table = [''];\n\n for (var i=0; i');\n }\n\n // ячейки календаря с датами\n while(d.getMonth() == month) {\n table.push('');\n\n if (getDay(d) % 7 == 6) { // вс, последний день - перевод строки\n table.push('');\n }\n\n d.setDate(d.getDate()+1);\n }\n\n // добить таблицу пустыми ячейками, если нужно\n if (getDay(d) != 0) {\n for (var i=getDay(d); i<7; i++) {\n table.push('');\n }\n }\n\n table.push('
        пнвтсрчтптсбвс
        '+d.getDate()+'
        ');\n\n return table.join('\\n')\n }\n\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794d7" } }, { "filename" : "datepicker.js", "content" : "/**\n * options:\n * value Date или объект {year,month,day}} -- дата, для которой показывать календарь\n * если в объекте указаны только {year,month}, то день не выбран\n*/\nfunction DatePicker(options) {\n var elem;\n var calendarLeft;\n var calendarRight;\n var calendarCache = {};\n\n var showYear, showMonth;\n var selectedYear, selectedMonth, selectedDay;\n\n var self = this;\n\n parseValue(options.value);\n showYear = selectedYear;\n showMonth = selectedMonth;\n\n // -------------\n\n this.getElement = function() {\n if (!elem) render();\n return elem;\n };\n\n this.getValue = function() {\n if (!selectedDay) return null;\n\n return new Date(selectedYear, selectedMonth, selectedDay);\n };\n\n function parseValue(value) {\n if (value instanceof Date) {\n selectedYear = value.getFullYear();\n selectedMonth = value.getMonth();\n selectedDay = value.getDate();\n } else {\n selectedYear = value.year;\n selectedMonth = value.month;\n selectedDay = value.day;\n }\n }\n\n function getCalendar(year, month) {\n\n var key = '' + year + month;\n var calendar;\n\n if (!calendarCache[key]) {\n calendar = calendarCache[key] = new Calendar({\n value: {year: year, month: month}\n });\n $(calendar).on(\"select\", onCalendarSelect);\n } else {\n calendar = calendarCache[key];\n }\n\n var value = {\n year: year,\n month: month,\n // если календарь отображает текущий выбранный месяц, то передать и день для выбора\n day: (year == selectedYear && month == selectedMonth) ? selectedDay : null\n };\n\n calendar.setValue(value, true);\n\n return calendar;\n }\n\n function onCalendarSelect(e) {\n parseValue(e.value);\n if (e.target == calendarLeft) {\n calendarRight.clearValue();\n } else {\n calendarLeft.clearValue();\n }\n\n $(self).triggerHandler({\n type: \"select\",\n value: e.target.getValue()\n });\n }\n\n\n function render() {\n elem = $('
        ').html(\n _.template(options.template)()\n );\n\n elem.on('mousedown', '.next-link', onNextLinkMouseDown);\n elem.on('mousedown', '.prev-link', onPrevLinkMouseDown);\n renderCalendars();\n }\n\n function renderCalendars() {\n calendarLeft = getCalendar(showYear, showMonth);\n // использую children().detach() вместо empty(),\n // т.к. empty() убивает обработчики на календаре\n elem.find('.calendar-left-holder').children().detach().end()\n .append(calendarLeft.getElement());\n\n var dateNextMonth = new Date(showYear, showMonth + 1);\n calendarRight = getCalendar(dateNextMonth.getFullYear(), dateNextMonth.getMonth());\n elem.find('.calendar-right-holder').children().detach().end()\n .append(calendarRight.getElement());\n }\n\n function onNextLinkMouseDown() {\n showMonth++;\n if (showMonth > 11) {\n showMonth = 0;\n showYear++;\n }\n renderCalendars();\n return false;\n }\n\n function onPrevLinkMouseDown() {\n showMonth--;\n if (showMonth < 0) {\n showMonth = 11;\n showYear--;\n }\n renderCalendars();\n return false;\n }\n\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794d8" } }, { "filename" : "calendar.css", "content" : ".calendar-table {\n border-collapse: collapse;\n}\n\n.calendar-table td, .calendar-table th {\n border: 1px solid black;\n padding: 3px;\n text-align: center;\n}\n\n.calendar-table th {\n font-weight: bold;\n background-color: #E6E6E6;\n}\n\n.date-cell:hover {\n background: #eee;\n cursor: pointer;\n}\n\n.date-cell.selected {\n background: #0F0;\n}\n\n.calendar-table caption {\n text-align: center;\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794d9" } }, { "filename" : "datepicker.css", "content" : ".datepicker {\n border: 1px solid black;\n width: 350px;\n}\n\n.datepicker .body {\n clear: both;\n background: red;\n}\n\n.datepicker .prev-link {\n float: left;\n cursor: pointer;\n}\n\n.datepicker .next-link {\n float: right;\n cursor: pointer;\n}\n\n.datepicker .prev-link:hover, .datepicker .next-link:hover {\n\tcolor: red;\n}\n\n\n.datepicker .header {\n\tpadding: 5px;\n font-size: 120%;\n}\n\n.datepicker .calendar-left-holder {\n\tfloat: left;\n}\n\n.datepicker .calendar-right-holder {\n\tfloat: right;\n}\n\n.datepicker .title {\n\ttext-align: center;\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794da" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n\n \n \n\n \n \n\n\n\n
        тут будет выбранное значение (дата)
        \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794db" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c6ff1f6dbff33a794dc" }, "plunkId" : "fm8dmsHyuUIoML9uF39d", "webPath" : "/task/double-calendar-with-arrows/source", "files" : [ { "filename" : "calendar.js", "content" : "/**\n * options:\n * value Date или объект {year,month,day}} -- дата, для которой показывать календарь\n * если в объекте указаны только {year,month}, то день не выбран\n*/\nfunction Calendar(options) {\n var self = this;\n\n var monthNames = 'Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь'.split(' ');\n\n var elem;\n var year, month, day;\n\n var showYear, showMonth;\n\n parseValue(options.value);\n\n // -----------------------\n\n this.getElement = function() {\n if (!elem) {\n render();\n }\n return elem;\n };\n\n this.getValue = function() {\n return day ? new Date(year, month, day) : null;\n };\n\n function parseValue(value) {\n if (value instanceof Date) {\n year = value.getFullYear();\n month = value.getMonth();\n day = value.getDate();\n } else {\n year = value.year;\n month = value.month;\n day = value.day;\n }\n }\n\n /**\n * Установить значение календаря\n * @param newValue {Date или объект {year,month[,day]} Новое значение\n * @param quiet Если true, то событие не генерируется\n */\n this.setValue = function(newValue, quiet) {\n parseValue(newValue);\n\n if (elem) {\n clearSelected();\n render();\n }\n\n if (!quiet) {\n $(self).triggerHandler({\n type: \"select\",\n value: new Date(year, month, day)\n });\n }\n };\n\n this.clearValue = function() {\n day = null;\n clearSelected();\n };\n\n function render() {\n if (!elem) {\n elem = $('
        ')\n .on('click', '.date-cell', onDateCellClick);\n }\n\n if (showYear != year || showMonth != month) {\n elem.html(renderCalendarTable(year, month));\n elem.find('caption').html(monthNames[month]+' '+year);\n showYear = year;\n showMonth = month;\n }\n\n if (day) {\n var num = getCellByDate(new Date(year, month, day));\n elem.find('td').eq(num).addClass(\"selected\");\n }\n\n }\n\n function clearSelected() {\n elem.find('.selected').removeClass('selected');\n }\n\n\n function onDateCellClick(e) {\n day = $(e.target).html();\n self.setValue({year: year, month: month, day: day});\n }\n\n\n /**\n * Возвращает по дате номер TD в таблице\n * Использование:\n * var td = table.getElementsByTagName('td')[getCellByDate(date)]\n */\n function getCellByDate(date) {\n var dateDayOne = new Date(date.getFullYear(), date.getMonth(), 1);\n\n return getDay(dateDayOne) + date.getDate() - 1;\n }\n\n /**\n * получить номер дня недели для date, от 0(пн) до 6(вс)\n * @param date\n */\n function getDay(date) { //\n var day = date.getDay();\n if (day == 0) day = 7;\n return day - 1;\n }\n\n /**\n * Генерирует таблицу для календаря заданного месяца/года\n */\n function renderCalendarTable(year, month) {\n\n var d = new Date(year, month);\n\n var table = [''];\n\n for (var i=0; i');\n }\n\n // ячейки календаря с датами\n while(d.getMonth() == month) {\n table.push('');\n\n if (getDay(d) % 7 == 6) { // вс, последний день - перевод строки\n table.push('');\n }\n\n d.setDate(d.getDate()+1);\n }\n\n // добить таблицу пустыми ячейками, если нужно\n if (getDay(d) != 0) {\n for (var i=getDay(d); i<7; i++) {\n table.push('');\n }\n }\n\n table.push('
        пнвтсрчтптсбвс
        '+d.getDate()+'
        ');\n\n return table.join('\\n')\n }\n\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794dd" } }, { "filename" : "datepicker.js", "content" : "/**\n * options:\n * value Date или объект {year,month,day}} -- дата, для которой показывать календарь\n * если в объекте указаны только {year,month}, то день не выбран\n*/\nfunction DatePicker(options) {\n /* ваш код */\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794de" } }, { "filename" : "calendar.css", "content" : ".calendar-table {\n border-collapse: collapse;\n}\n\n.calendar-table td, .calendar-table th {\n border: 1px solid black;\n padding: 3px;\n text-align: center;\n}\n\n.calendar-table th {\n font-weight: bold;\n background-color: #E6E6E6;\n}\n\n.date-cell:hover {\n background: #eee;\n cursor: pointer;\n}\n\n.date-cell.selected {\n background: #0F0;\n}\n\n.calendar-table caption {\n text-align: center;\n}", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794df" } }, { "filename" : "datepicker.css", "content" : "/* ваши стили */", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794e0" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n \n \n\n \n \n\n \n \n\n\n\n
        тут будет выбранное значение (дата)
        \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c6ff1f6dbff33a794e1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c70f1f6dbff33a794e3" }, "plunkId" : "UMf8beqA6d0d0nQCUpCb", "webPath" : "/task/tree-checkboxes/solution", "files" : [ { "filename" : "fetch.js", "content" : "var result = {\n\t0: { children: [] }\n};\n\n$('div[id^=\"region\"]').each(function() {\n el = $(this);\n var id = el.attr('id').slice(6);\n result[id] = {\n title: el.children('label').html(),\n children: [],\n id: id\n };\n\n var parent = el.parent().closest('div[id^=\"region\"]');\n if (parent.length) {\n var pid = parent.attr('id').slice(6);\n } else {\n pid = 0;\n }\n\n result[pid].children.push(+id);\n\n});", "_id" : { "$oid" : "54c29c70f1f6dbff33a794e4" } }, { "filename" : "regions.js", "content" : "var regions = {\"0\":{\"children\":[225,166,111,183,241,10002,10003,138]},\"1\":{\"title\":\"Москва и область\",\"children\":[213,10716,10722,10723,214,215,21622,20571,21623,37147,10734,20728,10735,10739,10745,10747,217,10750,10752,10754,21619,219,10765,21620],\"id\":\"1\"},\"2\":{\"title\":\"Санкт-Петербург\",\"children\":[],\"id\":\"2\"},\"3\":{\"title\":\"Центр\",\"children\":[1,10645,10650,10658,10672,10687,10693,10699,10705,10712,10772,10776,10795,10802,10819,10832,10841],\"id\":\"3\"},\"4\":{\"title\":\"Белгород\",\"children\":[],\"id\":\"4\"},\"6\":{\"title\":\"Калуга\",\"children\":[],\"id\":\"6\"},\"8\":{\"title\":\"Курск\",\"children\":[],\"id\":\"8\"},\"15\":{\"title\":\"Тула\",\"children\":[],\"id\":\"15\"},\"16\":{\"title\":\"Ярославль\",\"children\":[],\"id\":\"16\"},\"17\":{\"title\":\"Северо-Запад\",\"children\":[10174,10842,10904,10853,10857,10897,10176,10926,10933,10939],\"id\":\"17\"},\"18\":{\"title\":\"Петрозаводск\",\"children\":[],\"id\":\"18\"},\"19\":{\"title\":\"Сыктывкар\",\"children\":[],\"id\":\"19\"},\"20\":{\"title\":\"Архангельск\",\"children\":[],\"id\":\"20\"},\"21\":{\"title\":\"Вологда\",\"children\":[],\"id\":\"21\"},\"23\":{\"title\":\"Мурманск\",\"children\":[],\"id\":\"23\"},\"25\":{\"title\":\"Псков\",\"children\":[],\"id\":\"25\"},\"26\":{\"title\":\"Юг\",\"children\":[10946,10950,10995,11004,11015,11029],\"id\":\"26\"},\"35\":{\"title\":\"Краснодар\",\"children\":[],\"id\":\"35\"},\"36\":{\"title\":\"Ставрополь\",\"children\":[],\"id\":\"36\"},\"38\":{\"title\":\"Волгоград\",\"children\":[],\"id\":\"38\"},\"39\":{\"title\":\"Ростов-на-Дону\",\"children\":[],\"id\":\"39\"},\"40\":{\"title\":\"Поволжье\",\"children\":[11070,11079,11084,11095,11108,11111,11077,11117,11119,11131,11146,11148,11153,11156],\"id\":\"40\"},\"43\":{\"title\":\"Казань\",\"children\":[],\"id\":\"43\"},\"44\":{\"title\":\"Ижевск\",\"children\":[],\"id\":\"44\"},\"45\":{\"title\":\"Чебоксары\",\"children\":[],\"id\":\"45\"},\"47\":{\"title\":\"Нижний Новгород\",\"children\":[],\"id\":\"47\"},\"48\":{\"title\":\"Оренбург\",\"children\":[],\"id\":\"48\"},\"50\":{\"title\":\"Пермь\",\"children\":[],\"id\":\"50\"},\"51\":{\"title\":\"Самара\",\"children\":[],\"id\":\"51\"},\"52\":{\"title\":\"Урал\",\"children\":[11162,11158,11176,11193,11225,11232],\"id\":\"52\"},\"54\":{\"title\":\"Екатеринбург\",\"children\":[],\"id\":\"54\"},\"55\":{\"title\":\"Тюмень\",\"children\":[],\"id\":\"55\"},\"56\":{\"title\":\"Челябинск\",\"children\":[],\"id\":\"56\"},\"57\":{\"title\":\"Ханты-Мансийск\",\"children\":[],\"id\":\"57\"},\"58\":{\"title\":\"Салехард\",\"children\":[],\"id\":\"58\"},\"59\":{\"title\":\"Сибирь\",\"children\":[11235,21949,11266,11282,11309,11316,11318,10231,11330,10233,11340,11353],\"id\":\"59\"},\"62\":{\"title\":\"Красноярск\",\"children\":[],\"id\":\"62\"},\"63\":{\"title\":\"Иркутск\",\"children\":[],\"id\":\"63\"},\"64\":{\"title\":\"Кемерово\",\"children\":[],\"id\":\"64\"},\"67\":{\"title\":\"Томск\",\"children\":[],\"id\":\"67\"},\"73\":{\"title\":\"Дальний Восток\",\"children\":[11375,10243,11398,11403,11409,11443,11457,10251,11450],\"id\":\"73\"},\"75\":{\"title\":\"Владивосток\",\"children\":[],\"id\":\"75\"},\"76\":{\"title\":\"Хабаровск\",\"children\":[],\"id\":\"76\"},\"77\":{\"title\":\"Благовещенск\",\"children\":[],\"id\":\"77\"},\"84\":{\"title\":\"США\",\"children\":[],\"id\":\"84\"},\"93\":{\"title\":\"Аргентина\",\"children\":[],\"id\":\"93\"},\"94\":{\"title\":\"Бразилия\",\"children\":[],\"id\":\"94\"},\"95\":{\"title\":\"Канада\",\"children\":[],\"id\":\"95\"},\"96\":{\"title\":\"Германия\",\"children\":[],\"id\":\"96\"},\"102\":{\"title\":\"Великобритания\",\"children\":[],\"id\":\"102\"},\"111\":{\"title\":\"Европа\",\"children\":[113,114,115,102,116,96,246,203,204,205,20574,118,119,120,180,121,122,980,983,123,124,10083,125,126,127],\"id\":\"111\"},\"113\":{\"title\":\"Австрия\",\"children\":[],\"id\":\"113\"},\"114\":{\"title\":\"Бельгия\",\"children\":[],\"id\":\"114\"},\"115\":{\"title\":\"Болгария\",\"children\":[],\"id\":\"115\"},\"116\":{\"title\":\"Венгрия\",\"children\":[],\"id\":\"116\"},\"117\":{\"title\":\"Литва\",\"children\":[],\"id\":\"117\"},\"118\":{\"title\":\"Нидерланды\",\"children\":[],\"id\":\"118\"},\"119\":{\"title\":\"Норвегия\",\"children\":[],\"id\":\"119\"},\"120\":{\"title\":\"Польша\",\"children\":[],\"id\":\"120\"},\"121\":{\"title\":\"Словакия\",\"children\":[],\"id\":\"121\"},\"122\":{\"title\":\"Словения\",\"children\":[],\"id\":\"122\"},\"123\":{\"title\":\"Финляндия\",\"children\":[],\"id\":\"123\"},\"124\":{\"title\":\"Франция\",\"children\":[],\"id\":\"124\"},\"125\":{\"title\":\"Чехия\",\"children\":[],\"id\":\"125\"},\"126\":{\"title\":\"Швейцария\",\"children\":[],\"id\":\"126\"},\"127\":{\"title\":\"Швеция\",\"children\":[],\"id\":\"127\"},\"134\":{\"title\":\"Китай\",\"children\":[],\"id\":\"134\"},\"135\":{\"title\":\"Южная Корея\",\"children\":[],\"id\":\"135\"},\"137\":{\"title\":\"Япония\",\"children\":[],\"id\":\"137\"},\"138\":{\"title\":\"Австралия и Океания\",\"children\":[211,139],\"id\":\"138\"},\"139\":{\"title\":\"Новая Зеландия\",\"children\":[],\"id\":\"139\"},\"141\":{\"title\":\"Днепропетровск\",\"children\":[],\"id\":\"141\"},\"142\":{\"title\":\"Донецк\",\"children\":[],\"id\":\"142\"},\"143\":{\"title\":\"Киев\",\"children\":[],\"id\":\"143\"},\"146\":{\"title\":\"Симферополь\",\"children\":[],\"id\":\"146\"},\"149\":{\"title\":\"Беларусь\",\"children\":[29632,29633,29631,29634,29630,29629],\"id\":\"149\"},\"159\":{\"title\":\"Казахстан\",\"children\":[29414,29404,29406,29403,29407,29408,29410,29411,29412,29413,29415,29416,29409,29417],\"id\":\"159\"},\"162\":{\"title\":\"Алматы\",\"children\":[],\"id\":\"162\"},\"163\":{\"title\":\"Астана\",\"children\":[],\"id\":\"163\"},\"165\":{\"title\":\"Семей\",\"children\":[],\"id\":\"165\"},\"166\":{\"title\":\"СНГ (исключая Россию)\",\"children\":[29386,167,168,149,159,207,208,209,170,171,187],\"id\":\"166\"},\"167\":{\"title\":\"Азербайджан\",\"children\":[],\"id\":\"167\"},\"168\":{\"title\":\"Армения\",\"children\":[],\"id\":\"168\"},\"169\":{\"title\":\"Грузия\",\"children\":[],\"id\":\"169\"},\"170\":{\"title\":\"Туркмения\",\"children\":[],\"id\":\"170\"},\"171\":{\"title\":\"Узбекистан\",\"children\":[],\"id\":\"171\"},\"172\":{\"title\":\"Уфа\",\"children\":[],\"id\":\"172\"},\"179\":{\"title\":\"Эстония\",\"children\":[],\"id\":\"179\"},\"180\":{\"title\":\"Сербия\",\"children\":[],\"id\":\"180\"},\"181\":{\"title\":\"Израиль\",\"children\":[],\"id\":\"181\"},\"183\":{\"title\":\"Азия\",\"children\":[1004,169,994,20975,134,995,135,137],\"id\":\"183\"},\"187\":{\"title\":\"Украина\",\"children\":[20525,20524,977,20528,20527,20526],\"id\":\"187\"},\"192\":{\"title\":\"Владимир\",\"children\":[],\"id\":\"192\"},\"194\":{\"title\":\"Саратов\",\"children\":[],\"id\":\"194\"},\"195\":{\"title\":\"Ульяновск\",\"children\":[],\"id\":\"195\"},\"197\":{\"title\":\"Барнаул\",\"children\":[],\"id\":\"197\"},\"203\":{\"title\":\"Дания\",\"children\":[],\"id\":\"203\"},\"204\":{\"title\":\"Испания\",\"children\":[],\"id\":\"204\"},\"205\":{\"title\":\"Италия\",\"children\":[],\"id\":\"205\"},\"206\":{\"title\":\"Латвия\",\"children\":[],\"id\":\"206\"},\"207\":{\"title\":\"Киргизия\",\"children\":[],\"id\":\"207\"},\"208\":{\"title\":\"Молдова\",\"children\":[],\"id\":\"208\"},\"209\":{\"title\":\"Таджикистан\",\"children\":[],\"id\":\"209\"},\"210\":{\"title\":\"Объединенные Арабские Эмираты\",\"children\":[],\"id\":\"210\"},\"211\":{\"title\":\"Австралия\",\"children\":[],\"id\":\"211\"},\"213\":{\"title\":\"Москва\",\"children\":[],\"id\":\"213\"},\"214\":{\"title\":\"Долгопрудный\",\"children\":[],\"id\":\"214\"},\"215\":{\"title\":\"Дубна\",\"children\":[],\"id\":\"215\"},\"217\":{\"title\":\"Пущино\",\"children\":[],\"id\":\"217\"},\"219\":{\"title\":\"Черноголовка\",\"children\":[],\"id\":\"219\"},\"222\":{\"title\":\"Луганск\",\"children\":[],\"id\":\"222\"},\"225\":{\"title\":\"Россия\",\"children\":[3,17,40,26,59,73,102444,52],\"id\":\"225\"},\"235\":{\"title\":\"Магнитогорск\",\"children\":[],\"id\":\"235\"},\"236\":{\"title\":\"Набережные Челны\",\"children\":[],\"id\":\"236\"},\"237\":{\"title\":\"Новокузнецк\",\"children\":[],\"id\":\"237\"},\"238\":{\"title\":\"Новочеркасск\",\"children\":[],\"id\":\"238\"},\"239\":{\"title\":\"Сочи\",\"children\":[],\"id\":\"239\"},\"240\":{\"title\":\"Тольятти\",\"children\":[],\"id\":\"240\"},\"241\":{\"title\":\"Африка\",\"children\":[],\"id\":\"241\"},\"246\":{\"title\":\"Греция\",\"children\":[],\"id\":\"246\"},\"959\":{\"title\":\"Севастополь\",\"children\":[],\"id\":\"959\"},\"964\":{\"title\":\"Полтава\",\"children\":[],\"id\":\"964\"},\"967\":{\"title\":\"Обнинск\",\"children\":[],\"id\":\"967\"},\"968\":{\"title\":\"Череповец\",\"children\":[],\"id\":\"968\"},\"969\":{\"title\":\"Выборг\",\"children\":[],\"id\":\"969\"},\"970\":{\"title\":\"Новороссийск\",\"children\":[],\"id\":\"970\"},\"971\":{\"title\":\"Таганрог\",\"children\":[],\"id\":\"971\"},\"972\":{\"title\":\"Дзержинск\",\"children\":[],\"id\":\"972\"},\"973\":{\"title\":\"Сургут\",\"children\":[],\"id\":\"973\"},\"974\":{\"title\":\"Находка\",\"children\":[],\"id\":\"974\"},\"975\":{\"title\":\"Бийск\",\"children\":[],\"id\":\"975\"},\"976\":{\"title\":\"Братск\",\"children\":[],\"id\":\"976\"},\"977\":{\"title\":\"Крым\",\"children\":[11463,11464,959,146,11469,11470],\"id\":\"977\"},\"980\":{\"title\":\"Страны Балтии\",\"children\":[206,117,179],\"id\":\"980\"},\"983\":{\"title\":\"Турция\",\"children\":[103668,103669,103670,103671,103672,103673,103674,103675,103676,103677,103678,103679,103680,103681,103682,103683,103684,103685,103686,103687,103688,103689,103690,103691,103692,103693,103694,103695,103696,103697,103742,103698,103699,103700,103701,103702,103703,103704,103705,103706,103707,103708,103709,103710,103711,103712,103713,103714,103715,103716,103717,103718,103719,103720,103721,103722,103723,103724,103725,103726,103727,103728,103729,103730,103731,103732,103733,103734,103735,103736,103737,103738,103739,103740,103741,103743,103744,103745,103746,103747,103748],\"id\":\"983\"},\"994\":{\"title\":\"Индия\",\"children\":[],\"id\":\"994\"},\"995\":{\"title\":\"Таиланд\",\"children\":[],\"id\":\"995\"},\"1004\":{\"title\":\"Ближний Восток\",\"children\":[1056,181,210],\"id\":\"1004\"},\"1056\":{\"title\":\"Египет\",\"children\":[],\"id\":\"1056\"},\"1058\":{\"title\":\"Туапсе\",\"children\":[],\"id\":\"1058\"},\"1091\":{\"title\":\"Нижневартовск\",\"children\":[],\"id\":\"1091\"},\"1107\":{\"title\":\"Анапа\",\"children\":[],\"id\":\"1107\"},\"10002\":{\"title\":\"Северная Америка\",\"children\":[95,84],\"id\":\"10002\"},\"10003\":{\"title\":\"Южная Америка\",\"children\":[93,94],\"id\":\"10003\"},\"10083\":{\"title\":\"Хорватия\",\"children\":[],\"id\":\"10083\"},\"10174\":{\"title\":\"Санкт-Петербург и Ленинградская область\",\"children\":[10864,10865,969,10867,10871,2,10891,10892],\"id\":\"10174\"},\"10176\":{\"title\":\"Ненецкий автономный округ\",\"children\":[],\"id\":\"10176\"},\"10231\":{\"title\":\"Республика Алтай\",\"children\":[],\"id\":\"10231\"},\"10233\":{\"title\":\"Республика Тыва\",\"children\":[],\"id\":\"10233\"},\"10243\":{\"title\":\"Еврейская автономная область\",\"children\":[],\"id\":\"10243\"},\"10251\":{\"title\":\"Чукотский автономный округ\",\"children\":[],\"id\":\"10251\"},\"10303\":{\"title\":\"Талдыкорган\",\"children\":[],\"id\":\"10303\"},\"10306\":{\"title\":\"Усть-Каменогорск\",\"children\":[],\"id\":\"10306\"},\"10347\":{\"title\":\"Кривой Рог\",\"children\":[],\"id\":\"10347\"},\"10366\":{\"title\":\"Мариуполь\",\"children\":[],\"id\":\"10366\"},\"10369\":{\"title\":\"Белая Церковь\",\"children\":[],\"id\":\"10369\"},\"10645\":{\"title\":\"Белгород и область\",\"children\":[4,10649],\"id\":\"10645\"},\"10649\":{\"title\":\"Старый Оскол\",\"children\":[],\"id\":\"10649\"},\"10650\":{\"title\":\"Брянск и область\",\"children\":[],\"id\":\"10650\"},\"10658\":{\"title\":\"Владимир и область\",\"children\":[192,10664,10668],\"id\":\"10658\"},\"10664\":{\"title\":\"Ковров\",\"children\":[],\"id\":\"10664\"},\"10668\":{\"title\":\"Муром\",\"children\":[],\"id\":\"10668\"},\"10672\":{\"title\":\"Воронеж и область\",\"children\":[],\"id\":\"10672\"},\"10687\":{\"title\":\"Иваново и область\",\"children\":[],\"id\":\"10687\"},\"10693\":{\"title\":\"Калуга и область\",\"children\":[6,967],\"id\":\"10693\"},\"10699\":{\"title\":\"Кострома и область\",\"children\":[],\"id\":\"10699\"},\"10705\":{\"title\":\"Курск и область\",\"children\":[10710,8],\"id\":\"10705\"},\"10710\":{\"title\":\"Железногорск\",\"children\":[],\"id\":\"10710\"},\"10712\":{\"title\":\"Липецк и область\",\"children\":[],\"id\":\"10712\"},\"10716\":{\"title\":\"Балашиха\",\"children\":[],\"id\":\"10716\"},\"10722\":{\"title\":\"Воскресенск\",\"children\":[],\"id\":\"10722\"},\"10723\":{\"title\":\"Дмитров\",\"children\":[],\"id\":\"10723\"},\"10734\":{\"title\":\"Коломна\",\"children\":[],\"id\":\"10734\"},\"10735\":{\"title\":\"Красногорск\",\"children\":[],\"id\":\"10735\"},\"10739\":{\"title\":\"Можайск\",\"children\":[],\"id\":\"10739\"},\"10745\":{\"title\":\"Орехово-Зуево\",\"children\":[],\"id\":\"10745\"},\"10747\":{\"title\":\"Подольск\",\"children\":[],\"id\":\"10747\"},\"10750\":{\"title\":\"Раменское\",\"children\":[],\"id\":\"10750\"},\"10752\":{\"title\":\"Сергиев Посад\",\"children\":[],\"id\":\"10752\"},\"10754\":{\"title\":\"Серпухов\",\"children\":[],\"id\":\"10754\"},\"10765\":{\"title\":\"Щелково\",\"children\":[],\"id\":\"10765\"},\"10772\":{\"title\":\"Орел и область\",\"children\":[],\"id\":\"10772\"},\"10776\":{\"title\":\"Рязань и область\",\"children\":[],\"id\":\"10776\"},\"10795\":{\"title\":\"Смоленск и область\",\"children\":[],\"id\":\"10795\"},\"10802\":{\"title\":\"Тамбов и область\",\"children\":[],\"id\":\"10802\"},\"10819\":{\"title\":\"Тверь и область\",\"children\":[],\"id\":\"10819\"},\"10830\":{\"title\":\"Новомосковск\",\"children\":[],\"id\":\"10830\"},\"10832\":{\"title\":\"Тула и область\",\"children\":[10830,15],\"id\":\"10832\"},\"10839\":{\"title\":\"Рыбинск\",\"children\":[],\"id\":\"10839\"},\"10841\":{\"title\":\"Ярославль и область\",\"children\":[10839,21154,16],\"id\":\"10841\"},\"10842\":{\"title\":\"Архангельск и область\",\"children\":[20,10849],\"id\":\"10842\"},\"10849\":{\"title\":\"Северодвинск\",\"children\":[],\"id\":\"10849\"},\"10853\":{\"title\":\"Вологда и область\",\"children\":[21,968],\"id\":\"10853\"},\"10857\":{\"title\":\"Калининград и область\",\"children\":[],\"id\":\"10857\"},\"10864\":{\"title\":\"Волхов\",\"children\":[],\"id\":\"10864\"},\"10865\":{\"title\":\"Всеволожск\",\"children\":[],\"id\":\"10865\"},\"10867\":{\"title\":\"Гатчина\",\"children\":[],\"id\":\"10867\"},\"10871\":{\"title\":\"Кириши\",\"children\":[],\"id\":\"10871\"},\"10891\":{\"title\":\"Сосновый Бор\",\"children\":[],\"id\":\"10891\"},\"10892\":{\"title\":\"Тихвин\",\"children\":[],\"id\":\"10892\"},\"10894\":{\"title\":\"Апатиты\",\"children\":[],\"id\":\"10894\"},\"10897\":{\"title\":\"Мурманск и область\",\"children\":[10894,23],\"id\":\"10897\"},\"10904\":{\"title\":\"Великий Новгород и Новгородская область\",\"children\":[],\"id\":\"10904\"},\"10926\":{\"title\":\"Псков и область\",\"children\":[10928,25],\"id\":\"10926\"},\"10928\":{\"title\":\"Великие Луки\",\"children\":[],\"id\":\"10928\"},\"10933\":{\"title\":\"Республика Карелия\",\"children\":[10934,18,10937],\"id\":\"10933\"},\"10934\":{\"title\":\"Кондопога\",\"children\":[],\"id\":\"10934\"},\"10937\":{\"title\":\"Сортавала\",\"children\":[],\"id\":\"10937\"},\"10939\":{\"title\":\"Республика Коми\",\"children\":[10940,19,10944,10945],\"id\":\"10939\"},\"10940\":{\"title\":\"Воркута\",\"children\":[],\"id\":\"10940\"},\"10944\":{\"title\":\"Усинск\",\"children\":[],\"id\":\"10944\"},\"10945\":{\"title\":\"Ухта\",\"children\":[],\"id\":\"10945\"},\"10946\":{\"title\":\"Астрахань и область\",\"children\":[],\"id\":\"10946\"},\"10950\":{\"title\":\"Волгоград и область\",\"children\":[38,10951,10959],\"id\":\"10950\"},\"10951\":{\"title\":\"Волжский\",\"children\":[],\"id\":\"10951\"},\"10959\":{\"title\":\"Камышин\",\"children\":[],\"id\":\"10959\"},\"10987\":{\"title\":\"Армавир\",\"children\":[],\"id\":\"10987\"},\"10993\":{\"title\":\"Ейск\",\"children\":[],\"id\":\"10993\"},\"10995\":{\"title\":\"Краснодарский край\",\"children\":[1107,10987,10993,35,970,239,1058],\"id\":\"10995\"},\"11004\":{\"title\":\"Республика Адыгея\",\"children\":[],\"id\":\"11004\"},\"11010\":{\"title\":\"Республика Дагестан\",\"children\":[],\"id\":\"11010\"},\"11012\":{\"title\":\"Республика Ингушетия\",\"children\":[],\"id\":\"11012\"},\"11013\":{\"title\":\"Республика Кабардино-Балкария\",\"children\":[],\"id\":\"11013\"},\"11015\":{\"title\":\"Республика Калмыкия\",\"children\":[],\"id\":\"11015\"},\"11020\":{\"title\":\"Карачаево-Черкесская Республика\",\"children\":[],\"id\":\"11020\"},\"11021\":{\"title\":\"Республика Северная Осетия-Алания\",\"children\":[],\"id\":\"11021\"},\"11024\":{\"title\":\"Чеченская Республика\",\"children\":[],\"id\":\"11024\"},\"11029\":{\"title\":\"Ростов-на-Дону и область\",\"children\":[11036,11043,238,39,971,11053],\"id\":\"11029\"},\"11036\":{\"title\":\"Волгодонск\",\"children\":[],\"id\":\"11036\"},\"11043\":{\"title\":\"Каменск-Шахтинский\",\"children\":[],\"id\":\"11043\"},\"11053\":{\"title\":\"Шахты\",\"children\":[],\"id\":\"11053\"},\"11057\":{\"title\":\"Ессентуки\",\"children\":[],\"id\":\"11057\"},\"11062\":{\"title\":\"Кисловодск\",\"children\":[],\"id\":\"11062\"},\"11063\":{\"title\":\"Минеральные Воды\",\"children\":[],\"id\":\"11063\"},\"11064\":{\"title\":\"Невинномысск\",\"children\":[],\"id\":\"11064\"},\"11067\":{\"title\":\"Пятигорск\",\"children\":[],\"id\":\"11067\"},\"11069\":{\"title\":\"Ставропольский край\",\"children\":[11057,11062,11063,11064,11067,36],\"id\":\"11069\"},\"11070\":{\"title\":\"Киров и область\",\"children\":[],\"id\":\"11070\"},\"11077\":{\"title\":\"Республика Марий Эл\",\"children\":[],\"id\":\"11077\"},\"11079\":{\"title\":\"Нижний Новгород и область\",\"children\":[20040,972,20044,47,11083],\"id\":\"11079\"},\"11083\":{\"title\":\"Саров\",\"children\":[],\"id\":\"11083\"},\"11084\":{\"title\":\"Оренбург и область\",\"children\":[48,11091],\"id\":\"11084\"},\"11091\":{\"title\":\"Орск\",\"children\":[],\"id\":\"11091\"},\"11095\":{\"title\":\"Пенза и область\",\"children\":[],\"id\":\"11095\"},\"11108\":{\"title\":\"Пермский край\",\"children\":[20237,50],\"id\":\"11108\"},\"11111\":{\"title\":\"Республика Башкортостан\",\"children\":[11114,20235,11115,11116,172],\"id\":\"11111\"},\"11114\":{\"title\":\"Нефтекамск\",\"children\":[],\"id\":\"11114\"},\"11115\":{\"title\":\"Салават\",\"children\":[],\"id\":\"11115\"},\"11116\":{\"title\":\"Стерлитамак\",\"children\":[],\"id\":\"11116\"},\"11117\":{\"title\":\"Республика Мордовия\",\"children\":[],\"id\":\"11117\"},\"11119\":{\"title\":\"Республика Татарстан\",\"children\":[11121,11122,43,236,11127],\"id\":\"11119\"},\"11121\":{\"title\":\"Альметьевск\",\"children\":[],\"id\":\"11121\"},\"11122\":{\"title\":\"Бугульма\",\"children\":[],\"id\":\"11122\"},\"11127\":{\"title\":\"Нижнекамск\",\"children\":[],\"id\":\"11127\"},\"11131\":{\"title\":\"Самара и область\",\"children\":[11132,51,11139,240],\"id\":\"11131\"},\"11132\":{\"title\":\"Жигулевск\",\"children\":[],\"id\":\"11132\"},\"11139\":{\"title\":\"Сызрань\",\"children\":[],\"id\":\"11139\"},\"11143\":{\"title\":\"Балаково\",\"children\":[],\"id\":\"11143\"},\"11146\":{\"title\":\"Саратов и область\",\"children\":[11143,194,11147],\"id\":\"11146\"},\"11147\":{\"title\":\"Энгельс\",\"children\":[],\"id\":\"11147\"},\"11148\":{\"title\":\"Удмуртская Республика\",\"children\":[11150,44,11152],\"id\":\"11148\"},\"11150\":{\"title\":\"Глазов\",\"children\":[],\"id\":\"11150\"},\"11152\":{\"title\":\"Сарапул\",\"children\":[],\"id\":\"11152\"},\"11153\":{\"title\":\"Ульяновск и область\",\"children\":[11155,195],\"id\":\"11153\"},\"11155\":{\"title\":\"Димитровград\",\"children\":[],\"id\":\"11155\"},\"11156\":{\"title\":\"Чувашская Республика\",\"children\":[37133,45],\"id\":\"11156\"},\"11158\":{\"title\":\"Курган и область\",\"children\":[],\"id\":\"11158\"},\"11162\":{\"title\":\"Екатеринбург и Свердловская область\",\"children\":[54,11164,11168,11171],\"id\":\"11162\"},\"11164\":{\"title\":\"Каменск-Уральский\",\"children\":[],\"id\":\"11164\"},\"11168\":{\"title\":\"Нижний Тагил\",\"children\":[],\"id\":\"11168\"},\"11171\":{\"title\":\"Первоуральск\",\"children\":[],\"id\":\"11171\"},\"11173\":{\"title\":\"Ишим\",\"children\":[],\"id\":\"11173\"},\"11175\":{\"title\":\"Тобольск\",\"children\":[],\"id\":\"11175\"},\"11176\":{\"title\":\"Тюмень и область\",\"children\":[11173,11175,55],\"id\":\"11176\"},\"11184\":{\"title\":\"Нефтеюганск\",\"children\":[],\"id\":\"11184\"},\"11193\":{\"title\":\"Ханты-Мансийский АО\",\"children\":[11184,1091,973,57],\"id\":\"11193\"},\"11212\":{\"title\":\"Миасс\",\"children\":[],\"id\":\"11212\"},\"11214\":{\"title\":\"Озерск\",\"children\":[],\"id\":\"11214\"},\"11217\":{\"title\":\"Сатка\",\"children\":[],\"id\":\"11217\"},\"11225\":{\"title\":\"Челябинск и область\",\"children\":[235,11212,11214,11217,56],\"id\":\"11225\"},\"11230\":{\"title\":\"Новый Уренгой\",\"children\":[],\"id\":\"11230\"},\"11231\":{\"title\":\"Ноябрьск\",\"children\":[],\"id\":\"11231\"},\"11232\":{\"title\":\"Ямало-Ненецкий АО\",\"children\":[11230,11231,58],\"id\":\"11232\"},\"11235\":{\"title\":\"Алтайский край\",\"children\":[197,975],\"id\":\"11235\"},\"11256\":{\"title\":\"Ангарск\",\"children\":[],\"id\":\"11256\"},\"11266\":{\"title\":\"Иркутск и область\",\"children\":[11256,976,63,11273],\"id\":\"11266\"},\"11273\":{\"title\":\"Усть-Илимск\",\"children\":[],\"id\":\"11273\"},\"11282\":{\"title\":\"Кемерово и область\",\"children\":[64,11287,237],\"id\":\"11282\"},\"11287\":{\"title\":\"Междуреченск\",\"children\":[],\"id\":\"11287\"},\"11302\":{\"title\":\"Ачинск\",\"children\":[],\"id\":\"11302\"},\"11309\":{\"title\":\"Красноярский край\",\"children\":[11302,20086,62,11310,11311],\"id\":\"11309\"},\"11310\":{\"title\":\"Минусинск\",\"children\":[],\"id\":\"11310\"},\"11311\":{\"title\":\"Норильск\",\"children\":[],\"id\":\"11311\"},\"11316\":{\"title\":\"Новосибирск и область\",\"children\":[],\"id\":\"11316\"},\"11318\":{\"title\":\"Омск и область\",\"children\":[],\"id\":\"11318\"},\"11330\":{\"title\":\"Республика Бурятия\",\"children\":[],\"id\":\"11330\"},\"11340\":{\"title\":\"Республика Хакасия\",\"children\":[],\"id\":\"11340\"},\"11351\":{\"title\":\"Северск\",\"children\":[],\"id\":\"11351\"},\"11353\":{\"title\":\"Томск и область\",\"children\":[11351,67],\"id\":\"11353\"},\"11374\":{\"title\":\"Белогорск\",\"children\":[],\"id\":\"11374\"},\"11375\":{\"title\":\"Благовещенск и Амурская область\",\"children\":[11374,77,11391],\"id\":\"11375\"},\"11391\":{\"title\":\"Тында\",\"children\":[],\"id\":\"11391\"},\"11398\":{\"title\":\"Камчатский край\",\"children\":[],\"id\":\"11398\"},\"11403\":{\"title\":\"Магадан и область\",\"children\":[],\"id\":\"11403\"},\"11409\":{\"title\":\"Приморский край\",\"children\":[75,974,11426],\"id\":\"11409\"},\"11426\":{\"title\":\"Уссурийск\",\"children\":[],\"id\":\"11426\"},\"11443\":{\"title\":\"Республика Саха (Якутия)\",\"children\":[],\"id\":\"11443\"},\"11450\":{\"title\":\"Южно-Сахалинск и Сахалинская область\",\"children\":[],\"id\":\"11450\"},\"11453\":{\"title\":\"Комсомольск-на-Амуре\",\"children\":[],\"id\":\"11453\"},\"11457\":{\"title\":\"Хабаровский край\",\"children\":[11453,76],\"id\":\"11457\"},\"11463\":{\"title\":\"Евпатория\",\"children\":[],\"id\":\"11463\"},\"11464\":{\"title\":\"Керчь\",\"children\":[],\"id\":\"11464\"},\"11469\":{\"title\":\"Феодосия\",\"children\":[],\"id\":\"11469\"},\"11470\":{\"title\":\"Ялта\",\"children\":[],\"id\":\"11470\"},\"20040\":{\"title\":\"Выкса\",\"children\":[],\"id\":\"20040\"},\"20044\":{\"title\":\"Кстово\",\"children\":[],\"id\":\"20044\"},\"20086\":{\"title\":\"Железногорск\",\"children\":[],\"id\":\"20086\"},\"20235\":{\"title\":\"Октябрьский\",\"children\":[],\"id\":\"20235\"},\"20237\":{\"title\":\"Березники\",\"children\":[],\"id\":\"20237\"},\"20524\":{\"title\":\"Запад\",\"children\":[20532,20550,20529,20534,20531,20530,20535,20533],\"id\":\"20524\"},\"20525\":{\"title\":\"Восток\",\"children\":[20537,20536,20539,20540,20538],\"id\":\"20525\"},\"20526\":{\"title\":\"Юг\",\"children\":[20543,20541,20542],\"id\":\"20526\"},\"20527\":{\"title\":\"Центр\",\"children\":[20545,20547,20544,20548,20549,20546],\"id\":\"20527\"},\"20528\":{\"title\":\"Север\",\"children\":[20552,20551],\"id\":\"20528\"},\"20529\":{\"title\":\"Львов и область\",\"children\":[],\"id\":\"20529\"},\"20530\":{\"title\":\"Ужгород и Закарпатская область\",\"children\":[],\"id\":\"20530\"},\"20531\":{\"title\":\"Тернополь и область\",\"children\":[],\"id\":\"20531\"},\"20532\":{\"title\":\"Ивано-Франковск и область\",\"children\":[],\"id\":\"20532\"},\"20533\":{\"title\":\"Черновцы и область\",\"children\":[],\"id\":\"20533\"},\"20534\":{\"title\":\"Ровно и область\",\"children\":[],\"id\":\"20534\"},\"20535\":{\"title\":\"Хмельницкий и область\",\"children\":[],\"id\":\"20535\"},\"20536\":{\"title\":\"Донецк и область\",\"children\":[21774,142,20554,24876,10366],\"id\":\"20536\"},\"20537\":{\"title\":\"Днепропетровск и область\",\"children\":[21775,141,10347,21773,28401],\"id\":\"20537\"},\"20538\":{\"title\":\"Харьков и область\",\"children\":[],\"id\":\"20538\"},\"20539\":{\"title\":\"Запорожье и область\",\"children\":[],\"id\":\"20539\"},\"20540\":{\"title\":\"Луганск и область\",\"children\":[24885,222,24893],\"id\":\"20540\"},\"20541\":{\"title\":\"Одесса и область\",\"children\":[],\"id\":\"20541\"},\"20542\":{\"title\":\"Херсон и область\",\"children\":[],\"id\":\"20542\"},\"20543\":{\"title\":\"Николаев и область\",\"children\":[],\"id\":\"20543\"},\"20544\":{\"title\":\"Киев и область\",\"children\":[10369,143],\"id\":\"20544\"},\"20545\":{\"title\":\"Винница и область\",\"children\":[],\"id\":\"20545\"},\"20546\":{\"title\":\"Черкассы и область\",\"children\":[],\"id\":\"20546\"},\"20547\":{\"title\":\"Житомир и область\",\"children\":[],\"id\":\"20547\"},\"20548\":{\"title\":\"Кировоград и область\",\"children\":[],\"id\":\"20548\"},\"20549\":{\"title\":\"Полтава и область\",\"children\":[21609,964],\"id\":\"20549\"},\"20550\":{\"title\":\"Луцк и Волынская область\",\"children\":[],\"id\":\"20550\"},\"20551\":{\"title\":\"Чернигов и область\",\"children\":[],\"id\":\"20551\"},\"20552\":{\"title\":\"Сумы и область\",\"children\":[],\"id\":\"20552\"},\"20554\":{\"title\":\"Краматорск\",\"children\":[],\"id\":\"20554\"},\"20571\":{\"title\":\"Жуковский\",\"children\":[],\"id\":\"20571\"},\"20574\":{\"title\":\"Кипр\",\"children\":[],\"id\":\"20574\"},\"20728\":{\"title\":\"Королёв\",\"children\":[],\"id\":\"20728\"},\"20809\":{\"title\":\"Кокшетау\",\"children\":[],\"id\":\"20809\"},\"20975\":{\"title\":\"Камбоджа\",\"children\":[],\"id\":\"20975\"},\"21154\":{\"title\":\"Тутаев\",\"children\":[],\"id\":\"21154\"},\"21609\":{\"title\":\"Кременчуг\",\"children\":[],\"id\":\"21609\"},\"21619\":{\"title\":\"Фрязино\",\"children\":[],\"id\":\"21619\"},\"21620\":{\"title\":\"Юбилейный\",\"children\":[],\"id\":\"21620\"},\"21622\":{\"title\":\"Железнодорожный\",\"children\":[],\"id\":\"21622\"},\"21623\":{\"title\":\"Ивантеевка\",\"children\":[],\"id\":\"21623\"},\"21773\":{\"title\":\"Никополь\",\"children\":[],\"id\":\"21773\"},\"21774\":{\"title\":\"Горловка\",\"children\":[],\"id\":\"21774\"},\"21775\":{\"title\":\"Днепродзержинск\",\"children\":[],\"id\":\"21775\"},\"21949\":{\"title\":\"Забайкальский край\",\"children\":[],\"id\":\"21949\"},\"24876\":{\"title\":\"Макеевка\",\"children\":[],\"id\":\"24876\"},\"24885\":{\"title\":\"Алчевск\",\"children\":[],\"id\":\"24885\"},\"24893\":{\"title\":\"Северодонецк\",\"children\":[],\"id\":\"24893\"},\"28401\":{\"title\":\"Павлоград\",\"children\":[],\"id\":\"28401\"},\"29386\":{\"title\":\"Абхазия\",\"children\":[],\"id\":\"29386\"},\"29403\":{\"title\":\"Астана и Акмолинская область\",\"children\":[163,20809],\"id\":\"29403\"},\"29404\":{\"title\":\"Актобе и область\",\"children\":[],\"id\":\"29404\"},\"29406\":{\"title\":\"Алматы и область\",\"children\":[162,10303],\"id\":\"29406\"},\"29407\":{\"title\":\"Атырау и область\",\"children\":[],\"id\":\"29407\"},\"29408\":{\"title\":\"Восточно-Казахстанская область\",\"children\":[165,10306],\"id\":\"29408\"},\"29409\":{\"title\":\"Тараз и Жамбылская область\",\"children\":[],\"id\":\"29409\"},\"29410\":{\"title\":\"Западно-Казахстанская область\",\"children\":[],\"id\":\"29410\"},\"29411\":{\"title\":\"Караганда и область\",\"children\":[],\"id\":\"29411\"},\"29412\":{\"title\":\"Костанай и область\",\"children\":[],\"id\":\"29412\"},\"29413\":{\"title\":\"Кызылорда и область\",\"children\":[],\"id\":\"29413\"},\"29414\":{\"title\":\"Актау и Мангистауская область\",\"children\":[],\"id\":\"29414\"},\"29415\":{\"title\":\"Павлодар и область\",\"children\":[],\"id\":\"29415\"},\"29416\":{\"title\":\"Северо-Казахстанская область\",\"children\":[],\"id\":\"29416\"},\"29417\":{\"title\":\"Южно-Казахстанская область\",\"children\":[],\"id\":\"29417\"},\"29629\":{\"title\":\"Могилёв и область\",\"children\":[],\"id\":\"29629\"},\"29630\":{\"title\":\"Минск и область\",\"children\":[],\"id\":\"29630\"},\"29631\":{\"title\":\"Гомель и область\",\"children\":[],\"id\":\"29631\"},\"29632\":{\"title\":\"Брест и область\",\"children\":[],\"id\":\"29632\"},\"29633\":{\"title\":\"Витебск и область\",\"children\":[],\"id\":\"29633\"},\"29634\":{\"title\":\"Гродно и область\",\"children\":[],\"id\":\"29634\"},\"37133\":{\"title\":\"Новочебоксарск\",\"children\":[],\"id\":\"37133\"},\"37147\":{\"title\":\"Климовск\",\"children\":[],\"id\":\"37147\"},\"102444\":{\"title\":\"Северный Кавказ\",\"children\":[11020,11010,11012,11013,11021,11069,11024],\"id\":\"102444\"},\"103668\":{\"title\":\"Провинция Агры\",\"children\":[],\"id\":\"103668\"},\"103669\":{\"title\":\"Провинция Адана\",\"children\":[],\"id\":\"103669\"},\"103670\":{\"title\":\"Провинция Адыяман\",\"children\":[],\"id\":\"103670\"},\"103671\":{\"title\":\"Провинция Айдын\",\"children\":[],\"id\":\"103671\"},\"103672\":{\"title\":\"Провинция Аксарай\",\"children\":[],\"id\":\"103672\"},\"103673\":{\"title\":\"Провинция Амасья\",\"children\":[],\"id\":\"103673\"},\"103674\":{\"title\":\"Провинция Анкара\",\"children\":[],\"id\":\"103674\"},\"103675\":{\"title\":\"Провинция Анталья\",\"children\":[],\"id\":\"103675\"},\"103676\":{\"title\":\"Провинция Ардахан\",\"children\":[],\"id\":\"103676\"},\"103677\":{\"title\":\"Провинция Артвин\",\"children\":[],\"id\":\"103677\"},\"103678\":{\"title\":\"Провинция Афьонкарахисар\",\"children\":[],\"id\":\"103678\"},\"103679\":{\"title\":\"Провинция Байбурт\",\"children\":[],\"id\":\"103679\"},\"103680\":{\"title\":\"Провинция Балыкесир\",\"children\":[],\"id\":\"103680\"},\"103681\":{\"title\":\"Провинция Бартын\",\"children\":[],\"id\":\"103681\"},\"103682\":{\"title\":\"Провинция Батман\",\"children\":[],\"id\":\"103682\"},\"103683\":{\"title\":\"Провинция Биледжик\",\"children\":[],\"id\":\"103683\"},\"103684\":{\"title\":\"Провинция Бингёль\",\"children\":[],\"id\":\"103684\"},\"103685\":{\"title\":\"Провинция Битлис\",\"children\":[],\"id\":\"103685\"},\"103686\":{\"title\":\"Провинция Болу\",\"children\":[],\"id\":\"103686\"},\"103687\":{\"title\":\"Провинция Бурдур\",\"children\":[],\"id\":\"103687\"},\"103688\":{\"title\":\"Провинция Бурса\",\"children\":[],\"id\":\"103688\"},\"103689\":{\"title\":\"Провинция Ван\",\"children\":[],\"id\":\"103689\"},\"103690\":{\"title\":\"Провинция Газиантеп\",\"children\":[],\"id\":\"103690\"},\"103691\":{\"title\":\"Провинция Гиресун\",\"children\":[],\"id\":\"103691\"},\"103692\":{\"title\":\"Провинция Гюмюшхане\",\"children\":[],\"id\":\"103692\"},\"103693\":{\"title\":\"Провинция Денизли\",\"children\":[],\"id\":\"103693\"},\"103694\":{\"title\":\"Провинция Диярбакыр\",\"children\":[],\"id\":\"103694\"},\"103695\":{\"title\":\"Провинция Дюздже\",\"children\":[],\"id\":\"103695\"},\"103696\":{\"title\":\"Провинция Зонгулдак\",\"children\":[],\"id\":\"103696\"},\"103697\":{\"title\":\"Провинция Измир\",\"children\":[],\"id\":\"103697\"},\"103698\":{\"title\":\"Провинция Йозгат\",\"children\":[],\"id\":\"103698\"},\"103699\":{\"title\":\"Провинция Кайсери\",\"children\":[],\"id\":\"103699\"},\"103700\":{\"title\":\"Провинция Карабюк\",\"children\":[],\"id\":\"103700\"},\"103701\":{\"title\":\"Провинция Караман\",\"children\":[],\"id\":\"103701\"},\"103702\":{\"title\":\"Провинция Карс\",\"children\":[],\"id\":\"103702\"},\"103703\":{\"title\":\"Провинция Кастамону\",\"children\":[],\"id\":\"103703\"},\"103704\":{\"title\":\"Провинция Кахраманмараш\",\"children\":[],\"id\":\"103704\"},\"103705\":{\"title\":\"Провинция Килис\",\"children\":[],\"id\":\"103705\"},\"103706\":{\"title\":\"Провинция Коджаэли\",\"children\":[],\"id\":\"103706\"},\"103707\":{\"title\":\"Провинция Конья\",\"children\":[],\"id\":\"103707\"},\"103708\":{\"title\":\"Провинция Кыркларели\",\"children\":[],\"id\":\"103708\"},\"103709\":{\"title\":\"Провинция Кыршехир\",\"children\":[],\"id\":\"103709\"},\"103710\":{\"title\":\"Провинция Кырыккале\",\"children\":[],\"id\":\"103710\"},\"103711\":{\"title\":\"Провинция Кютахья\",\"children\":[],\"id\":\"103711\"},\"103712\":{\"title\":\"Провинция Малатья\",\"children\":[],\"id\":\"103712\"},\"103713\":{\"title\":\"Провинция Маниса\",\"children\":[],\"id\":\"103713\"},\"103714\":{\"title\":\"Провинция Мардин\",\"children\":[],\"id\":\"103714\"},\"103715\":{\"title\":\"Провинция Мерсин\",\"children\":[],\"id\":\"103715\"},\"103716\":{\"title\":\"Провинция Мугла\",\"children\":[],\"id\":\"103716\"},\"103717\":{\"title\":\"Провинция Муш\",\"children\":[],\"id\":\"103717\"},\"103718\":{\"title\":\"Провинция Невшехир\",\"children\":[],\"id\":\"103718\"},\"103719\":{\"title\":\"Провинция Нигде\",\"children\":[],\"id\":\"103719\"},\"103720\":{\"title\":\"Провинция Орду\",\"children\":[],\"id\":\"103720\"},\"103721\":{\"title\":\"Провинция Османие\",\"children\":[],\"id\":\"103721\"},\"103722\":{\"title\":\"Провинция Ризе\",\"children\":[],\"id\":\"103722\"},\"103723\":{\"title\":\"Провинция Сакарья\",\"children\":[],\"id\":\"103723\"},\"103724\":{\"title\":\"Провинция Самсун\",\"children\":[],\"id\":\"103724\"},\"103725\":{\"title\":\"Провинция Сивас\",\"children\":[],\"id\":\"103725\"},\"103726\":{\"title\":\"Провинция Сиирт\",\"children\":[],\"id\":\"103726\"},\"103727\":{\"title\":\"Провинция Синоп\",\"children\":[],\"id\":\"103727\"},\"103728\":{\"title\":\"Провинция Стамбул\",\"children\":[],\"id\":\"103728\"},\"103729\":{\"title\":\"Провинция Текирдаг\",\"children\":[],\"id\":\"103729\"},\"103730\":{\"title\":\"Провинция Токат\",\"children\":[],\"id\":\"103730\"},\"103731\":{\"title\":\"Провинция Трабзон\",\"children\":[],\"id\":\"103731\"},\"103732\":{\"title\":\"Провинция Тунджели\",\"children\":[],\"id\":\"103732\"},\"103733\":{\"title\":\"Провинция Ушак\",\"children\":[],\"id\":\"103733\"},\"103734\":{\"title\":\"Провинция Хаккяри\",\"children\":[],\"id\":\"103734\"},\"103735\":{\"title\":\"Провинция Хатай\",\"children\":[],\"id\":\"103735\"},\"103736\":{\"title\":\"Провинция Чанаккале\",\"children\":[],\"id\":\"103736\"},\"103737\":{\"title\":\"Провинция Чанкыры\",\"children\":[],\"id\":\"103737\"},\"103738\":{\"title\":\"Провинция Чорум\",\"children\":[],\"id\":\"103738\"},\"103739\":{\"title\":\"Провинция Шанлыурфа\",\"children\":[],\"id\":\"103739\"},\"103740\":{\"title\":\"Провинция Ширнак\",\"children\":[],\"id\":\"103740\"},\"103741\":{\"title\":\"Провинция Ыгдыр\",\"children\":[],\"id\":\"103741\"},\"103742\":{\"title\":\"Провинция Испарта\",\"children\":[],\"id\":\"103742\"},\"103743\":{\"title\":\"Провинция Эдирне\",\"children\":[],\"id\":\"103743\"},\"103744\":{\"title\":\"Провинция Элязыг\",\"children\":[],\"id\":\"103744\"},\"103745\":{\"title\":\"Провинция Эрзинджан\",\"children\":[],\"id\":\"103745\"},\"103746\":{\"title\":\"Провинция Эрзурум\",\"children\":[],\"id\":\"103746\"},\"103747\":{\"title\":\"Провинция Эскишехир\",\"children\":[],\"id\":\"103747\"},\"103748\":{\"title\":\"Провинция Ялова\",\"children\":[],\"id\":\"103748\"}};", "_id" : { "$oid" : "54c29c70f1f6dbff33a794e5" } }, { "filename" : "tree.js", "content" : "function Tree(options) {\n var self = this;\n\n var template = options.template;\n\n var data = options.data;\n\n this.getElement = function() {\n \tif (!this.elem) render();\n \treturn this.elem;\n }\n\n function onTogglerClick(e) {\n \tself.toggle( $(e.currentTarget.parentNode) );\n }\n\n function onCheckboxChange(e) {\n var checked = e.target.checked;\n var id = e.target.value;\n var node = $(e.currentTarget.parentNode);\n\n if (checked) {\n self.open(node);\n }\n\n node.find('input').prop('checked', checked);\n }\n\n this.toggle = function(node) {\n \tensureChildrenRendered(node);\n \tnode.toggleClass(\"tree-open tree-closed\");\n };\n\n this.open = function(node) {\n ensureChildrenRendered(node);\n node.addClass(\"tree-open\").removeClass(\"tree-closed\");\n }\n\n this.close = function(node) {\n ensureChildrenRendered(node);\n node.addClass(\"tree-closed\").removeClass(\"tree-open\");\n }\n\n function ensureChildrenRendered(node) {\n var ul = node.children('ul');\n\n \tif (!ul.length) {\n \t\trenderChildren( node.data('id') ).appendTo(node);\n\n if (node.children('input').is(':checked')) {\n node.find('input').prop('checked', true);\n }\n \t}\n }\n\n function renderChildren(id) {\n \treturn $(template({\n \t\tchildren: data[id].children,\n \t\tdata: data\n \t}));\n }\n\n function render() {\n\n \tself.elem = renderChildren(0)\n \t .addClass('tree');\n\n \tself.elem.on('click', '.tree-toggler', onTogglerClick);\n\n self.elem.on('change', 'input', onCheckboxChange);\n }\n\n}", "_id" : { "$oid" : "54c29c70f1f6dbff33a794e6" } }, { "filename" : "tree.css", "content" : ".tree, .tree ul {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 2px;\n}\n\n.tree .tree-open ul {\n\tdisplay: block;\n}\n\n\n.tree .tree-closed ul {\n\tdisplay: none;\n}\n\n.tree-toggler {\n\tcolor: blue;\n\tcursor: pointer;\n\tfloat: left;\n\tmargin-left: -16px;\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tree-open .tree-toggler {\n\tbackground: url(//js.cx/tree/minus.gif) no-repeat center;\n}\n\n\n.tree-closed .tree-toggler {\n\tbackground: url(//js.cx/tree/plus.gif) no-repeat center;\n}\n\n.tree li {\n\tline-height: 1em;\n\tpadding-left: 16px;\n}", "_id" : { "$oid" : "54c29c70f1f6dbff33a794e7" } }, { "filename" : "index.html", "content" : "\n\n\n\t\n\t\n\n\t\n\t\n\t\n\t\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c70f1f6dbff33a794e8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c71f1f6dbff33a794e9" }, "plunkId" : "CbHewlREWMoRv6sLXqEi", "webPath" : "/task/tree-checkboxes/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\nВыбор регионов\n\n\n\n\n\n\n\n
        \n\n\n

        Выбор регионов для показов объявлений

        \n\n
        \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
        \n\n
        \n\n\n\n
        + 
        + 
        + 
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        + 
            
            
            
        + 
            
            
            
            
            
        + 
            
            
            
        + 
            
            
            
            
            
            
            
            
        + 
            
            
        + 
            
            
            
        + 
        + 
            
            
            
            
            
            
            
            
        + 
            
            
            
        + 
            
            
            
        + 
            
            
            
        + 
            
            
        + 
            
            
            
        + 
            
            
            
            
        + 
            
        + 
            
            
            
            
            
        + 
            
            
            
        + 
            
            
        + 
            
            
            
            
            
            
            
        + 
            
            
            
            
            
        + 
            
            
            
            
        + 
            
            
            
        + 
            
            
            
        + 
            
            
        + 
            
            
        + 
            
        + 
            
            
            
        + 
            
            
            
            
            
            
            
            
            
        + 
            
            
            
            
            
            
        + 
        + 
            
            
            
        + 
            
            
            
            
        + 
            
            
            
        + 
            
            
            
            
            
            
            
            
            
            
            
        + 
            
            
        + 
        + 
            
            
            
            
            
            
        + 
            
            
            
            
        + 
            
            
            
            
        + 
            
            
            
            
            
        + 
            
            
            
            
            
            
            
        + 
        + 
            
            
            
            
            
        + 
            
            
            
        + 
            
            
            
            
        + 
            
            
            
            
            
        + 
            
            
            
        + 
            
            
            
        + 
            
            
            
            
            
            
        + 
            
            
        + 
            
            
        + 
            
            
            
        + 
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        + 
        + 
        + 
            
            
            
            
            
        + 
            
            
            
            
            
            
        + 
            
            
            
            
        + 
            
            
            
            
            
            
            
            
        + 
            
            
            
            
            
            
        + 
            
            
        + 
            
            
        + 
            
            
            
        + 
            
            
            
        + 
            
            
            
        + 
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        + 
            
            
            
        + 
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        + 
        + 
            
            
            
            
            
            
            
            
            
            
            
        + 
            
            
        + 
            
            
        + 
            
            
        \n\n
        \n\n
        \n\n\n", "_id" : { "$oid" : "54c29c71f1f6dbff33a794ea" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c74f1f6dbff33a794f1" }, "plunkId" : "qf7B0uQ001syArvLvkV1", "webPath" : "/article/link-import/import-libs", "files" : [ { "filename" : "index.html", "content" : "\n\n...", "_id" : { "$oid" : "54c29c74f1f6dbff33a794f2" } }, { "filename" : "libs.html", "content" : "\n\n\n", "_id" : { "$oid" : "54c29c74f1f6dbff33a794f3" } }, { "filename" : "ui-dialog.html", "content" : "\n...template и код для диалогов...", "_id" : { "$oid" : "54c29c74f1f6dbff33a794f4" } }, { "filename" : "ui-tabs.html", "content" : "\n...template и код для табов...", "_id" : { "$oid" : "54c29c74f1f6dbff33a794f5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c74f1f6dbff33a794f6" }, "plunkId" : "L0YAjWI5V5LorXWmwvzk", "webPath" : "/article/link-import/import-show", "files" : [ { "filename" : "index.html", "content" : "\n\n \n\n \n\n \n\n \n\n", "_id" : { "$oid" : "54c29c74f1f6dbff33a794f7" } }, { "filename" : "timer.html", "content" : "\n\n \n\n

        0

        \n\n \n\n \n", "_id" : { "$oid" : "54c29c74f1f6dbff33a794f8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c75f1f6dbff33a794f9" }, "plunkId" : "6A657LoaImgepoEdeaq9", "webPath" : "/article/link-import/import-style", "files" : [ { "filename" : "index.html", "content" : "\n\n \n \n \n \n", "_id" : { "$oid" : "54c29c75f1f6dbff33a794fa" } }, { "filename" : "timer.html", "content" : "\n\n \n \n \n \n\n

        0

        \n\n \n\n \n", "_id" : { "$oid" : "54c29c75f1f6dbff33a794fb" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c75f1f6dbff33a794fd" }, "plunkId" : "oafbXT3KEx2RkcGIznuI", "webPath" : "/article/webcomponent-build/message", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n Доброе утро, страна!\n\n Внимание-внимание! Говорит информбюро!\n\n\n", "_id" : { "$oid" : "54c29c75f1f6dbff33a794fe" } }, { "filename" : "ui-message.html", "content" : "\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c75f1f6dbff33a794ff" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c76f1f6dbff33a79500" }, "plunkId" : "eSkcQV1UijmdedqHilua", "webPath" : "/article/webcomponent-build/ui-slider", "files" : [ { "filename" : "index.html", "content" : "\n\n \n \n \n \n \n \n\n \n\n \n\n
        0
        \n\n \n", "_id" : { "$oid" : "54c29c76f1f6dbff33a79501" } }, { "filename" : "jquery.html", "content" : "\n", "_id" : { "$oid" : "54c29c76f1f6dbff33a79502" } }, { "filename" : "ui-slider.html", "content" : "\n\n\n \n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c76f1f6dbff33a79503" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c77f1f6dbff33a7951f" }, "plunkId" : "1LAIOBDqEDLZBYsxLfPA", "webPath" : "/task/position-text-into-input/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        Добро пожаловать
        \n\n\n
        Скажи пароль, друг
        \n\n
        .. и заходи
        \n\n", "_id" : { "$oid" : "54c29c77f1f6dbff33a79520" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c77f1f6dbff33a79521" }, "plunkId" : "lwpsr4F9OqV5fwQslEgH", "webPath" : "/task/position-text-into-input/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
        Добро пожаловать
        \n\n\n\n
        Скажи пароль, друг
        \n\n
        .. и заходи
        \n\n\n", "_id" : { "$oid" : "54c29c77f1f6dbff33a79522" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c78f1f6dbff33a79523" }, "plunkId" : "njsYPrft70BO89GIbY8j", "webPath" : "/article/margin/h2-margin-top-position", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n

        Общие положения

        \n\n

        Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.

        \n
        \n\n
        \n

        Общие обязанности водителей

        \n\n

        Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:

        \n
          \n
        • водительское удостоверение на право управления транспортным средством соответствующей категории;
        • \n
        • ...и так далее...
        • \n
        \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c78f1f6dbff33a79524" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c78f1f6dbff33a79525" }, "plunkId" : "JuYwQKsDDd2jD23rsMZ9", "webPath" : "/article/margin/h2-margin-top", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n

        Общие положения

        \n\n

        Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.

        \n
        \n\n
        \n

        Общие обязанности водителей

        \n\n

        Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:

        \n
          \n
        • водительское удостоверение на право управления транспортным средством соответствующей категории;
        • \n
        • ...и так далее...
        • \n
        \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c78f1f6dbff33a79526" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c79f1f6dbff33a79527" }, "plunkId" : "deZpL3J2GyZAR001l0Vh", "webPath" : "/article/margin/hr-margin-left-src", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
        \n\n

        Общие положения

        \n
        \n\n

        Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.

        \n
        \n\n
        \n

        Общие обязанности водителей

        \n
        \n\n

        Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:

        \n
          \n
        • водительское удостоверение на право управления транспортным средством соответствующей категории;
        • \n
        • ...и так далее...
        • \n
        \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c79f1f6dbff33a79528" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c79f1f6dbff33a79529" }, "plunkId" : "LAiq9aeH8jVyxGLlbj8L", "webPath" : "/article/margin/hr-margin-left", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
        \n\n

        Общие положения (hr.margin)

        \n
        \n\n

        Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.

        \n
        \n\n
        \n

        Общие обязанности водителей (hr.position)

        \n
        \n\n

        Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:

        \n
          \n
        • водительское удостоверение на право управления транспортным средством соответствующей категории;
        • \n
        • ...и так далее...
        • \n
        \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c79f1f6dbff33a7952a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7af1f6dbff33a7952b" }, "plunkId" : "Kln6nFUQ3O8F6TBtpmga", "webPath" : "/article/margin/negative-margin-bottom", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n
        У DIV'а с холодильниками стоит margin-bottom: -1em
        \n\n
        \n Наши холодильники - самые лучшие холодильники в мире!\n Наши холодильники - самые лучшие холодильники в мире!\n Наши холодильники - самые лучшие холодильники в мире!\n Наши холодильники - самые лучшие холодильники в мире!\n
        \n\n\n Так считают: 5 человек\n\n\n\n Оставьте свой отзыв!\n\n\n\n", "_id" : { "$oid" : "54c29c7af1f6dbff33a7952c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7af1f6dbff33a7952e" }, "plunkId" : "JorruPckbNsg267krOD5", "webPath" : "/article/space-under-img/block", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7af1f6dbff33a7952f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7cf1f6dbff33a79530" }, "plunkId" : "kl6EbRlvX3gjgY8nMYE2", "webPath" : "/article/space-under-img/inline-p", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n p\n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7cf1f6dbff33a79531" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7cf1f6dbff33a79532" }, "plunkId" : "GGoRhBiDzzFnQryScMFc", "webPath" : "/article/space-under-img/inline", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7cf1f6dbff33a79533" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7df1f6dbff33a79534" }, "plunkId" : "bLKsi6pn6CCIqtFsigOw", "webPath" : "/article/space-under-img/valign-p", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n pp\n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7df1f6dbff33a79535" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7df1f6dbff33a79536" }, "plunkId" : "8qKc8dl5KZHELv1jnD0f", "webPath" : "/article/space-under-img/valign-small-lh", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7df1f6dbff33a79537" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7ef1f6dbff33a79538" }, "plunkId" : "Oa3x43lj2im07bDyx1Zx", "webPath" : "/article/space-under-img/valign-small", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7ef1f6dbff33a79539" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7ff1f6dbff33a7953a" }, "plunkId" : "yBNSQyhizlF8DO1Yg4Rv", "webPath" : "/article/space-under-img/valign", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n\n\n \n \n \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c7ff1f6dbff33a7953b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c7ff1f6dbff33a7953e" }, "plunkId" : "Ryvrlz4Wt25X6kY890PH", "webPath" : "/article/height-percent/height-percent-float-exact", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n
        \n
        \n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n
        \n
        \n\n\n", "_id" : { "$oid" : "54c29c7ff1f6dbff33a7953f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c80f1f6dbff33a79540" }, "plunkId" : "AW8KHlLASxqdMwY6XP71", "webPath" : "/article/height-percent/height-percent-float", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
        \n
        \n
        \n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n
        \n
        \n\n\n", "_id" : { "$oid" : "54c29c80f1f6dbff33a79541" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c81f1f6dbff33a79542" }, "plunkId" : "aw1tJLNHfDdjmtXeTNSj", "webPath" : "/article/height-percent/height-percent", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
        \n
        \n
        \n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n
        \n
        \n\n\n", "_id" : { "$oid" : "54c29c81f1f6dbff33a79543" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c82f1f6dbff33a79546" }, "plunkId" : "SKeJRyWVhYqaGd65ZhIB", "webPath" : "/task/select-elements-selector/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n

        Сообщения:

        \n
          \n
        • Сообщение 1
        • \n
        • Сообщение 2
        • \n
        • Сообщение 3
        • \n
        • Сообщение 4
        • \n
        • Сообщение 5
        • \n
        • ...
        • \n
        \n\n\nСсылка на архив\n..И на PDF\n\n\n\n\n", "_id" : { "$oid" : "54c29c82f1f6dbff33a79547" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c82f1f6dbff33a79549" }, "plunkId" : "LYXmwZAzBuhXIeWuSgCL", "webPath" : "/task/margin-between-pairs-size-1/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nТекст вверху без отступа от списка.\n
          \n
        • Маша
        • \n
        • Паша
        • \n
        • Даша
        • \n
        • Женя
        • \n
        • Саша
        • \n
        • Гоша
        • \n
        \nТекст внизу без отступа от списка.\n\n\n", "_id" : { "$oid" : "54c29c82f1f6dbff33a7954a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c82f1f6dbff33a7954b" }, "plunkId" : "7iBEDszmKE96L3zD7mRc", "webPath" : "/task/margin-between-pairs-size-1/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nТекст вверху без отступа от списка.\n
          \n
        • Маша
        • \n
        • Паша
        • \n
        • Даша
        • \n
        • Женя
        • \n
        • Саша
        • \n
        • Гоша
        • \n
        \nТекст внизу без отступа от списка.\n\n\n", "_id" : { "$oid" : "54c29c82f1f6dbff33a7954c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c83f1f6dbff33a7954e" }, "plunkId" : "i41YtzNBvS348eUpAABg", "webPath" : "/task/margin-between-pairs/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nТекст вверху без отступа от списка.\n
          \n
        • Маша
        • \n
        • Паша
        • \n
        • Даша
        • \n
        • Женя
        • \n
        • Саша
        • \n
        • Гоша
        • \n
        \nТекст внизу без отступа от списка.\n\n\n", "_id" : { "$oid" : "54c29c83f1f6dbff33a7954f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c83f1f6dbff33a79550" }, "plunkId" : "ZjjyU8g26pl5McdYML4e", "webPath" : "/task/margin-between-pairs/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nТекст вверху без отступа от списка.\n
          \n
        • Маша
        • \n
        • Паша
        • \n
        • Даша
        • \n
        • Женя
        • \n
        • Саша
        • \n
        • Гоша
        • \n
        \nТекст внизу без отступа от списка.\n\n\n", "_id" : { "$oid" : "54c29c83f1f6dbff33a79551" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c84f1f6dbff33a79552" }, "plunkId" : "psRlCNhanjwUvD2GC03O", "webPath" : "/article/css-selectors/nthchild-type", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
        \n
        Первый dt
        \n
        Описание dd
        \n
        Второй dt dt:nth-of-type(2n)
        \n
        Описание dd
        \n
        Третий dt
        \n
        Описание dd dd:nth-last-of-type(2)
        \n
        Четвёртый dt dt:nth-of-type(2n)
        \n
        Описание dd
        \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c84f1f6dbff33a79553" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c84f1f6dbff33a79554" }, "plunkId" : "kqpFEJodrVSMEBQbd5pp", "webPath" : "/article/css-selectors/nthchild", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
          \n
        • Древнерусский язык
        • \n
        • Древненовгородский диалект li:nth-child(2n)
        • \n
        • Западнорусский письменный язык li:nth-child(3)
        • \n
        • Украинский язык li:nth-child(2n)
        • \n
        • Белорусский язык
        • \n
        • Другие языки li:nth-child(2n)
        • \n
        \n\n\n", "_id" : { "$oid" : "54c29c84f1f6dbff33a79555" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c85f1f6dbff33a79556" }, "plunkId" : "zM1flHn8pZoigo5nN0uV", "webPath" : "/article/css-selectors/relation", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n

        Балтославянские языки

        \n\n
          \n
        1. Славянские языки\n
            \n
          1. Славянские микроязыки
          2. \n
          3. Праславянский язык
          4. \n
          5. Восточнославянские языки #e-slavic
          6. \n
          7. Западнославянские языки #e-slavic ~ li
          8. \n
          9. Южнославянские языки #e-slavic ~ li
          10. \n
          11. ... #e-slavic ~ li
          12. \n
          \n
        2. \n
        3. Балтийские языки\n
            \n
          1. Литовский язык
          2. \n
          3. Латышский язык #latvian\n
            1. Латгальский язык #latvian *
            \n
          4. \n
          5. Прусский язык #latvian + li
          6. \n
          7. ... (следующий элемент уже не #latvian + li)
          8. \n
          \n
        4. \n
        \n\n\n", "_id" : { "$oid" : "54c29c85f1f6dbff33a79557" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c85f1f6dbff33a7955a" }, "plunkId" : "D9PY0GEe4SwEf3TbP8mq", "webPath" : "/article/css-sprite/height48", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
          \n
        • \n
          \n
          Пример раздела
          \n
        • \n
        \n\n\n", "_id" : { "$oid" : "54c29c85f1f6dbff33a7955b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c85f1f6dbff33a7955c" }, "plunkId" : "EGYClgY266BSbeQKbsTq", "webPath" : "/article/css-sprite/sprite-tree-src", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n
          \n
        • \n
          \n
          Раздел 1
          В две строки
          \n
            \n
          • \n
            \n
            Раздел 1.1 в одну строку
            \n
          • \n
          • \n
            \n
            Страница 1.2
            в две строки
            \n
          • \n
          \n
        • \n
        • \n
          \n
          Раздел 2
          В две строки
          \n
        • \n
        \n\n\n", "_id" : { "$oid" : "54c29c85f1f6dbff33a7955d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c86f1f6dbff33a7955e" }, "plunkId" : "s1WkXsc7hw2LLIfDNTQo", "webPath" : "/article/css-sprite/sprite-tree", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n
          \n
        • \n
          \n
          Раздел 1
          В две строки
          \n
            \n
          • \n
            \n
            Раздел 1.1 в одну строку
            \n
          • \n
          • \n
            \n
            Страница 1.2
            в две строки
            \n
          • \n
          \n
        • \n
        • \n
          \n
          Раздел 2
          В две строки
          \n
        • \n
        \n\n\n", "_id" : { "$oid" : "54c29c86f1f6dbff33a7955f" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c86f1f6dbff33a79566" }, "plunkId" : "XTy09bGrZ6zNcgfUvG1k", "webPath" : "/task/inline-block-vs-float/gallery-float-diffsize", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
          \n
        • \n \n
          Картинка 1
          \n
        • \n\n
        • \n \n
          Картинка 2
          \n
        • \n\n
        • \n \n
          Картинка 3
          \n
        • \n\n
        • \n \n
          Картинка 4
          \n
        • \n\n
        • \n \n
          Картинка 5
          \n
        • \n\n
        • \n \n
          Картинка 6
          \n
        • \n\n
        • \n \n
          Картинка 7
          \n
        • \n\n
        • \n \n
          Картинка 8
          \n
        • \n\n
        • \n \n
          Картинка 9
          \n
        • \n\n
        \n\n", "_id" : { "$oid" : "54c29c86f1f6dbff33a79567" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c86f1f6dbff33a79568" }, "plunkId" : "rKBgDhFZkD2IUNhklrtK", "webPath" : "/task/inline-block-vs-float/gallery-inline-block", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
          \n
        • \n \n
          Картинка 1
          \n
        • \n\n
        • \n \n
          Картинка 2
          \n
        • \n\n
        • \n \n
          Картинка 3
          \n
        • \n\n
        • \n \n
          Картинка 4
          \n
        • \n\n
        • \n \n
          Картинка 5
          \n
        • \n\n
        • \n \n
          Картинка 6
          \n
        • \n\n
        \n\n", "_id" : { "$oid" : "54c29c86f1f6dbff33a79569" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c87f1f6dbff33a7956a" }, "plunkId" : "EovHkLVum7UYku27F3dP", "webPath" : "/task/inline-block-vs-float/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
          \n
        • \n \n
          Картинка 1
          \n
        • \n\n
        • \n \n
          Картинка 2
          \n
        • \n\n
        • \n \n
          Картинка 3
          \n
        • \n\n
        • \n \n
          Картинка 4
          \n
        • \n\n
        • \n \n
          Картинка 5
          \n
        • \n\n
        • \n \n
          Картинка 6
          \n
        • \n\n
        • \n \n
          Картинка 7
          \n
        • \n\n
        • \n \n
          Картинка 8
          \n
        • \n\n
        • \n \n
          Картинка 9
          \n
        • \n\n
        \n\n", "_id" : { "$oid" : "54c29c87f1f6dbff33a7956b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c87f1f6dbff33a7956d" }, "plunkId" : "6y2dh3XysXI66lpt8BhA", "webPath" : "/task/tree-with-multiline-nodes/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n
          \n
        • \n
          \n
          Раздел 1
          (занимает две строки)
          \n
            \n
          • \n
            \n
            Раздел 1.1
            \n
          • \n
          • \n
            \n
            Страница 1.2
            (занимает две строки)
            \n
          • \n
          \n
        • \n
        • \n
          \n
          Раздел 2
          (занимает две строки)
          \n
        • \n
        \n\n\n", "_id" : { "$oid" : "54c29c87f1f6dbff33a7956e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c87f1f6dbff33a7956f" }, "plunkId" : "hNq90FByt7Y1i3Rm1SIH", "webPath" : "/task/tree-with-multiline-nodes/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n\n
          \n
        • \n
          \n
          Раздел 1
          (занимает две строки)
          \n
            \n
          • \n
            \n
            Раздел 1.1
            \n
          • \n
          • \n
            \n
            Страница 1.2
            (занимает две строки)
            \n
          • \n
          \n
        • \n
        • \n
          \n
          Раздел 2
          (занимает две строки)
          \n
        • \n
        \n\n\n", "_id" : { "$oid" : "54c29c87f1f6dbff33a79570" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c88f1f6dbff33a79572" }, "plunkId" : "MkufljzsWadE8ysYsgRl", "webPath" : "/task/paginator-css/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nТекст Сверху\n\n
        \n \n \n
          \n
        • 1
        • \n
        • 2
        • \n
        • 3
        • \n
        • 4
        • \n
        • 5
        • \n
        • 6
        • \n
        • 7
        • \n
        • 8
        • \n
        • 9
        • \n
        \n
        \n\nТекст Снизу\n\n\n", "_id" : { "$oid" : "54c29c88f1f6dbff33a79573" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c89f1f6dbff33a79574" }, "plunkId" : "z3O9oQAwLOVubrACdRZ6", "webPath" : "/task/paginator-css/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\nТекст Сверху\n\n
        \n \n\n
          \n
        • 1
        • \n
        • 2
        • \n
        • 3
        • \n
        • 4
        • \n
        • 5
        • \n
        • 6
        • \n
        • 7
        • \n
        • 8
        • \n
        • 9
        • \n
        \n\n \n
        \nТекст Снизу\n\n\n", "_id" : { "$oid" : "54c29c89f1f6dbff33a79575" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c89f1f6dbff33a79577" }, "plunkId" : "45ygzy28iDYmDnVkkU5m", "webPath" : "/article/float/gallery-float", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
          \n
        • \n \n
          Картинка 1
          \n
        • \n\n
        • \n \n
          Картинка 2
          \n
        • \n\n
        • \n \n
          Картинка 3
          \n
        • \n\n
        • \n \n
          Картинка 4
          \n
        • \n\n
        • \n \n
          Картинка 5
          \n
        • \n\n
        • \n \n
          Картинка 6
          \n
        • \n\n
        • \n \n
          Картинка 7
          \n
        • \n\n
        • \n \n
          Картинка 8
          \n
        • \n\n
        • \n \n
          Картинка 9
          \n
        • \n\n
        \n\n", "_id" : { "$oid" : "54c29c89f1f6dbff33a79578" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8af1f6dbff33a79579" }, "plunkId" : "Z5kvBOgAMWLChDWSu8xv", "webPath" : "/article/float/two-columns-2", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        Шапка
        \n\n
        \n
        \n

        Персонажи:

        \n
          \n
        • Винни-Пух
        • \n
        • Ослик Иа
        • \n
        • Сова
        • \n
        • Кролик
        • \n
        \n
        \n
        \n
        \n
        \n\n

        Винни-Пух

        \n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n
        \n
        \n\n
        Низ
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c8af1f6dbff33a7957a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8bf1f6dbff33a7957b" }, "plunkId" : "ENmQVRHS50QGItPAGuwV", "webPath" : "/article/float/two-columns", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        Шапка
        \n\n
        \n
        \n

        Персонажи:

        \n
          \n
        • Винни-Пух
        • \n
        • Ослик Иа
        • \n
        • Сова
        • \n
        • Кролик
        • \n
        \n
        \n
        \n\n
        \n
        \n

        Винни-Пух

        \n\n \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n
        \n
        \n\n
        Низ
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c8bf1f6dbff33a7957c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8bf1f6dbff33a7957d" }, "plunkId" : "zoXxQB71FvLo3Jg5JEKF", "webPath" : "/article/float/winnie-block-bg", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

        Винни-Пух

        \n\n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n", "_id" : { "$oid" : "54c29c8bf1f6dbff33a7957e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8bf1f6dbff33a7957f" }, "plunkId" : "BBk3lhIZQFL8bZytMoNd", "webPath" : "/article/float/winnie-block", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

        Винни-Пух

        \n\n
        \n\n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n\n\n", "_id" : { "$oid" : "54c29c8bf1f6dbff33a79580" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8cf1f6dbff33a79581" }, "plunkId" : "YFsZV6Wy1zWPTj02SXwq", "webPath" : "/article/float/winnie-clear-1", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n\n

        Сова

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Персонаж мультфильма про Винни-Пуха. Очень умная.

        \n\n

        Говорит редко, но чрезвычайно мудро.

        \n\n\n\n", "_id" : { "$oid" : "54c29c8cf1f6dbff33a79582" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8cf1f6dbff33a79583" }, "plunkId" : "6iWt8jVjZ9lq8HnOWM5Z", "webPath" : "/article/float/winnie-clear-2", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n\n

        Сова

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Персонаж мультфильма про Винни-Пуха. Очень умная.

        \n\n

        Говорит редко, но чрезвычайно мудро.

        \n\n\n\n", "_id" : { "$oid" : "54c29c8cf1f6dbff33a79584" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8df1f6dbff33a79585" }, "plunkId" : "Sk8Jl16o2YIQFhM5wG3r", "webPath" : "/article/float/winnie-clear-3", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n\n
        \n

        Сова

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Персонаж мультфильма про Винни-Пуха. Очень умная.

        \n\n

        Говорит редко, но чрезвычайно мудро.

        \n\n\n\n", "_id" : { "$oid" : "54c29c8df1f6dbff33a79586" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8df1f6dbff33a79587" }, "plunkId" : "mG7VSsNEEPSV8NpEqiya", "webPath" : "/article/float/winnie-clear-4", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n
        \n\n\n", "_id" : { "$oid" : "54c29c8df1f6dbff33a79588" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8df1f6dbff33a79589" }, "plunkId" : "HKl6ubQz5xtee2S1v2Ep", "webPath" : "/article/float/winnie-clearfill-clearfix", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n
        \n\n\n", "_id" : { "$oid" : "54c29c8df1f6dbff33a7958a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8ef1f6dbff33a7958b" }, "plunkId" : "8pWJvTXpZz5pEiyibxE1", "webPath" : "/article/float/winnie-clearfill-div", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n
        \n\n\n", "_id" : { "$oid" : "54c29c8ef1f6dbff33a7958c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8ef1f6dbff33a7958d" }, "plunkId" : "zM9KBKzMYrhs674dhgt1", "webPath" : "/article/float/winnie-clearfill-float", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n
        \n\n\n", "_id" : { "$oid" : "54c29c8ef1f6dbff33a7958e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8ef1f6dbff33a7958f" }, "plunkId" : "kxNTwnISA7zQnLu1R6Wy", "webPath" : "/article/float/winnie-clearfill-overflow", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n
        \n\n

        Винни-Пух

        \n\n
        \n \n
        Кадр из советского мультфильма
        \n
        \n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).

        \n\n

        Один из самых известных героев детской литературы XX века.

        \n
        \n\n\n", "_id" : { "$oid" : "54c29c8ef1f6dbff33a79590" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8ff1f6dbff33a79591" }, "plunkId" : "QurYqg0BnhbQqzOZ7YjF", "webPath" : "/article/float/winnie-nofloat-1", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n\n", "_id" : { "$oid" : "54c29c8ff1f6dbff33a79592" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8ff1f6dbff33a79593" }, "plunkId" : "2EV0RYGu1YUuN1H7uA4i", "webPath" : "/article/float/winnie-nofloat-2", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n\n", "_id" : { "$oid" : "54c29c8ff1f6dbff33a79594" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c8ff1f6dbff33a79595" }, "plunkId" : "Q2SgzsTRf75HVaNTlBAO", "webPath" : "/article/float/winnie-nofloat-3", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n\n", "_id" : { "$oid" : "54c29c8ff1f6dbff33a79596" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c90f1f6dbff33a79597" }, "plunkId" : "zZVl3fWvbaMd1ARGIeRe", "webPath" : "/article/float/winnie-nofloat", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n\n", "_id" : { "$oid" : "54c29c90f1f6dbff33a79598" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c91f1f6dbff33a79599" }, "plunkId" : "mJDNTHazdW0SJaEJGbRq", "webPath" : "/article/float/winnie", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

        Винни-Пух

        \n\n\n\n

        Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.

        \n\n

        В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.

        \n\n\n\n

        Первый перевод «Винни-Пуха» в СССР вышел в 1958 году в Литве (лит. Mikė Pūkuotukas), его выполнил 20-летний литовский писатель Виргилюс Чепайтис, пользовавшийся польским переводом Ирены Тувим. Впоследствии Чепайтис, познакомившись с английским оригиналом, существенно переработал свой перевод, переиздававшийся в Литве неоднократно.

        \n\n

        История Винни-Пуха в России начинается с того же 1958 года, когда с книгой познакомился Борис Владимирович Заходер.

        \n\n\n\n\n

        В студии «Союзмультфильм» под руководством Фёдора Хитрука было создано три мультфильма.

        \n\n

        Сценарий написал Хитрук в соавторстве с Заходером; работа соавторов не всегда шла гладко, что стало в конечном счёте причиной прекращения выпуска мультфильмов (первоначально планировалось выпустить сериал по всей книге). Текст и картинки взяты с Wikipedia.

        \n\n\n", "_id" : { "$oid" : "54c29c91f1f6dbff33a7959a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c91f1f6dbff33a7959d" }, "plunkId" : "0sulyqC2a2GhOneiqH4C", "webPath" : "/task/modal-window/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
        \n\n\n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c91f1f6dbff33a7959e" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c91f1f6dbff33a7959f" }, "plunkId" : "vA0lLZUzwj5zovpPqw6D", "webPath" : "/task/modal-window/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n
        \n\n\n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n

        Текст Текст Текст

        \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c91f1f6dbff33a795a0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c92f1f6dbff33a795a1" }, "plunkId" : "BYAICzfjMf8mVnH30pO0", "webPath" : "/article/position/position-100-wrong", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n
        Прокрутите меня...
        \n\n", "_id" : { "$oid" : "54c29c92f1f6dbff33a795a2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c93f1f6dbff33a795a5" }, "plunkId" : "r2L8JeY3lYoBz7lDPjTw", "webPath" : "/task/center-ball-css/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
        \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
        \n\n\n\n", "_id" : { "$oid" : "54c29c93f1f6dbff33a795a6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c93f1f6dbff33a795a7" }, "plunkId" : "4h1dHUFnCqCBwuZUGPBl", "webPath" : "/task/center-ball-css/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
        \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n
        \n\n\n\n", "_id" : { "$oid" : "54c29c93f1f6dbff33a795a8" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c93f1f6dbff33a795aa" }, "plunkId" : "7ERv7F89MYEeIHSI8kOY", "webPath" : "/task/form-modal/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n

        Текст Текст Текст

        \n\n\n\n

        Текст Текст Текст

        \n\n\n
        \n
        \n
        \n\n
        \n Добро пожаловать!\n \n \n \n \n
        Логин
        Пароль
        \n\n
        \n\n
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c93f1f6dbff33a795ab" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c94f1f6dbff33a795ac" }, "plunkId" : "hInlkzgDUiiCshcXxJuB", "webPath" : "/task/form-modal/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n

        Текст Текст Текст

        \n\n\n\n

        Текст Текст Текст

        \n\n\n\n\n\n", "_id" : { "$oid" : "54c29c94f1f6dbff33a795ad" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c95f1f6dbff33a795af" }, "plunkId" : "k4JC9QjZOpxL6NEFfQ0A", "webPath" : "/article/css-center/vertical-align", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\nКартинка размером в 30px, значения vertical-align:\n\n
        \nbaseline(по умолчанию) \nmiddle(по середине) \nsubвровень с <sub> \nsuperвровень с <sup> \ntext-top(верхняя граница вровень с текстом) \ntext-bottom(нижняя граница вровень с текстом) \n
        \n\n\n", "_id" : { "$oid" : "54c29c95f1f6dbff33a795b0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c95f1f6dbff33a795b8" }, "plunkId" : "zMJPNKrcZlLmqrTwjzTr", "webPath" : "/task/carousel-animated/solution", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', start:0, end: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n var value = Math.round(start + (end - start)*delta);\n opts.elem.style[prop] = value + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress);\n}\n\nfunction linear(progress) {\n return progress;\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2);\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5);\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress));\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2;\n else\n return (2 - delta(2*(1-progress))) / 2;\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress);\n }\n}", "_id" : { "$oid" : "54c29c95f1f6dbff33a795b9" } }, { "filename" : "style.css", "content" : "body {\n padding: 10px\n}\n\n.carousel {\n position: relative;\n width: 398px;\n padding: 10px 40px;\n border: 1px solid #CCC;\n border-radius: 15px;\n background: #eee;\n}\n.carousel img {\n width: 130px;\n height: 130px;\n display: block; /* если не поставить block, в ряде браузеров будет inline -> лишнее пространтсво вокруг элементов */\n}\n.carousel .arrow {\n position: absolute;\n top: 57px;\n padding: 3px 8px 8px 9px;\n background: #ddd;\n border-radius: 15px;\n font-size: 24px;\n color: #444;\n text-decoration: none;\n}\n\n.carousel .arrow:hover {\n background: #ccc;\n}\n.carousel .left-arrow {\n left: 7px;\n}\n.carousel .right-arrow {\n right: 7px;\n}\n.gallery {\n width: 390px;\n overflow: hidden;\n}\n.gallery ul {\n height: 130px;\n width: 9999px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.gallery ul li {\n\tfloat: left;\n}", "_id" : { "$oid" : "54c29c95f1f6dbff33a795ba" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
        \n\n
        \n
          \n
        • \n
        • \n
        • \n
        • \n
        • \n
        • \n
        • \n
        • \n
        • \n
        • \n
        \n
        \n\n
        \n\n\n\n", "_id" : { "$oid" : "54c29c95f1f6dbff33a795bb" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c97f1f6dbff33a795bd" }, "plunkId" : "A9AUXjB236jhBrnaSMHw", "webPath" : "/task/animate-logo/solution", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', start:0, end: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n var value = Math.round(start + (end - start)*delta);\n opts.elem.style[prop] = value + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress);\n}\n\nfunction linear(progress) {\n return progress;\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2);\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5);\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress));\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2;\n else\n return (2 - delta(2*(1-progress))) / 2;\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress);\n }\n}", "_id" : { "$oid" : "54c29c97f1f6dbff33a795be" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\nКликните картинку для анимации. Расположение элементов при анимации не должно меняться!\n\n\n\n\n\n\n\n
        Догнать\n..и перегнать!
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c97f1f6dbff33a795bf" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c97f1f6dbff33a795c0" }, "plunkId" : "sSrzWi4Wjjv0FuGwd4mK", "webPath" : "/task/animate-logo/source", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', start:0, end: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n var value = Math.round(start + (end - start)*delta);\n opts.elem.style[prop] = value + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress);\n}\n\nfunction linear(progress) {\n return progress;\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2);\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5);\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress));\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2;\n else\n return (2 - delta(2*(1-progress))) / 2;\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress);\n }\n}", "_id" : { "$oid" : "54c29c97f1f6dbff33a795c1" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\nКликните картинку для анимации. Расположение элементов при анимации не должно меняться!\n\n\n\n\n\n\n
        Догнать\n..и перегнать!
        \n\nВ процессе анимации повторные нажатия на изображение игнорируются.\n\n\n\n\n", "_id" : { "$oid" : "54c29c97f1f6dbff33a795c2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c98f1f6dbff33a795c4" }, "plunkId" : "wMy1DWLj7GjYYNHwfSN0", "webPath" : "/task/animate-ball/solution", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', from:0, to: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n opts.elem.style[prop] = Math.round(start + (start - end)*delta) + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)\n}\n\nfunction linear(progress) {\n return progress\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2)\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5)\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress))\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5)\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2\n else\n return (2 - delta(2*(1-progress))) / 2\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress)\n }\n}", "_id" : { "$oid" : "54c29c98f1f6dbff33a795c5" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
        \n\n
        \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c98f1f6dbff33a795c6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c98f1f6dbff33a795c7" }, "plunkId" : "4RqUCjBU98JCN2JLkpjv", "webPath" : "/task/animate-ball/source", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', from:0, to: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n opts.elem.style[prop] = Math.round(start + (start - end)*delta) + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)\n}\n\nfunction linear(progress) {\n return progress\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2)\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5)\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress))\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5)\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2\n else\n return (2 - delta(2*(1-progress))) / 2\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress)\n }\n}", "_id" : { "$oid" : "54c29c98f1f6dbff33a795c8" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
        \n\n
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c98f1f6dbff33a795c9" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c99f1f6dbff33a795cb" }, "plunkId" : "9TcyWGjYalQB0DoGU831", "webPath" : "/task/animate-ball-hops/solution", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', from:0, to: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n opts.elem.style[prop] = Math.round(start + (start - end)*delta) + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)\n}\n\nfunction linear(progress) {\n return progress\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2)\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5)\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress))\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5)\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2\n else\n return (2 - delta(2*(1-progress))) / 2\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress)\n }\n}", "_id" : { "$oid" : "54c29c99f1f6dbff33a795cc" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
        \n\n
        \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c99f1f6dbff33a795cd" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c99f1f6dbff33a795ce" }, "plunkId" : "BDG42kyJbB253JRyIZzY", "webPath" : "/task/animate-ball-hops/source", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', from:0, to: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n opts.elem.style[prop] = Math.round(start + (start - end)*delta) + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)\n}\n\nfunction linear(progress) {\n return progress\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2)\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5)\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress))\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5)\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2\n else\n return (2 - delta(2*(1-progress))) / 2\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress)\n }\n}", "_id" : { "$oid" : "54c29c99f1f6dbff33a795cf" } }, { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n
        \n\n
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c99f1f6dbff33a795d0" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c99f1f6dbff33a795d1" }, "plunkId" : "unwVswkbNsEWKaomQTTQ", "webPath" : "/article/js-animation/move", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
        \n\t
        \n
        \n\n", "_id" : { "$oid" : "54c29c99f1f6dbff33a795d2" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9af1f6dbff33a795d3" }, "plunkId" : "PgaWjBhp2s27opX4aFHu", "webPath" : "/article/js-animation/move100", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
        \n
        \n
        \n\n\n", "_id" : { "$oid" : "54c29c9af1f6dbff33a795d4" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9af1f6dbff33a795d5" }, "plunkId" : "Unk5p6SJxvIpVZTSTWdF", "webPath" : "/article/js-animation/width", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
        \n\t
        \n
        \n\n", "_id" : { "$oid" : "54c29c9af1f6dbff33a795d6" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9af1f6dbff33a795db" }, "plunkId" : "zL1YqnmlsbsRli3ukIlY", "webPath" : "/task/animate-logo-css/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\nКликните картинку для анимации. Расположение элементов при анимации не должно меняться!\n\n\n\n\n\n\n
        Догнать\n..и перегнать!
        \n\nВ процессе анимации повторные клики на изображение игнорировать.\n\n\n\n\n", "_id" : { "$oid" : "54c29c9af1f6dbff33a795dc" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9bf1f6dbff33a795dd" }, "plunkId" : "zNuvQJLzkNpvLvXQlyNT", "webPath" : "/task/animate-logo-css/source", "files" : [ { "filename" : "animate.js", "content" : "/**\n Docs: http://learn.javascript.ru/tutorial/lib\n*/\n\nfunction animate(opts) {\n\n var start = new Date;\n var delta = opts.delta || linear;\n\n var timer = setInterval(function() {\n var progress = (new Date - start) / opts.duration;\n\n if (progress > 1) progress = 1;\n\n opts.step( delta(progress) );\n\n if (progress == 1) {\n clearInterval(timer);\n opts.complete && opts.complete();\n }\n }, opts.delay || 13);\n\n return timer;\n}\n\n/**\n Анимация стиля opts.prop у элемента opts.elem\n от opts.from до opts.to продолжительностью opts.duration\n в конце opts.complete\n\n Например: animateProp({ elem: ..., prop: 'height', start:0, end: 100, duration: 1000 })\n*/\nfunction animateProp(opts) {\n var start = opts.start, end = opts.end, prop = opts.prop;\n\n opts.step = function(delta) {\n var value = Math.round(start + (end - start)*delta);\n opts.elem.style[prop] = value + 'px';\n }\n return animate(opts);\n}\n\n// ------------------ Delta ------------------\n\nfunction elastic(progress) {\n return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress);\n}\n\nfunction linear(progress) {\n return progress;\n}\n\nfunction quad(progress) {\n return Math.pow(progress, 2);\n}\n\nfunction quint(progress) {\n return Math.pow(progress, 5);\n}\n\nfunction circ(progress) {\n return 1 - Math.sin(Math.acos(progress));\n}\n\nfunction back(progress) {\n return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);\n}\n\n\nfunction bounce(progress) {\n for(var a = 0, b = 1, result; 1; a += b, b /= 2) {\n if (progress >= (7 - 4 * a) / 11) {\n return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);\n }\n }\n}\n\nfunction makeEaseInOut(delta) {\n return function(progress) {\n if (progress < .5)\n return delta(2*progress) / 2;\n else\n return (2 - delta(2*(1-progress))) / 2;\n }\n}\n\n\nfunction makeEaseOut(delta) {\n return function(progress) {\n return 1 - delta(1 - progress);\n }\n}", "_id" : { "$oid" : "54c29c9bf1f6dbff33a795de" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\nКликните картинку для анимации. Расположение элементов при анимации не должно меняться!\n\n\n\n\n\n\n
        Догнать\n..и перегнать!
        \n\nВ процессе анимации повторные нажатия на изображение игнорируются.\n\n\n\n\n", "_id" : { "$oid" : "54c29c9bf1f6dbff33a795df" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9bf1f6dbff33a795e0" }, "plunkId" : "jEjZe8sEMe2gxgmKThBC", "webPath" : "/article/css-animation/boat", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c9bf1f6dbff33a795e1" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9cf1f6dbff33a795ea" }, "plunkId" : "PybkpH4MB7hV2PnXcr7o", "webPath" : "/task/rewrite-with-jquery/solution", "files" : [ { "filename" : "bagua.css", "content" : "#bagua-table th {\n\ttext-align:center;\n\tfont-weight:bold;\n}\n\n#bagua-table td {\n\twidth: 150px;\n\twhite-space: nowrap;\n\ttext-align:center;\n\tvertical-align: bottom;\n\tpadding-top: 5px;\n\tpadding-bottom: 12px;\n}\n\n#bagua-table .nw {\n\tbackground-color: #999;\n}\n\n#bagua-table .n {\n\tbackground-color: #03f;\n\tcolor: #fff;\n}\n\n#bagua-table .ne {\n\tbackground-color: #ff6;\n}\n\n#bagua-table .w {\n\tbackground-color: #ff0;\n}\n#bagua-table .c {\n\tbackground-color: #60c;\n\tcolor: #fff;\n}\n#bagua-table .e {\n\tbackground-color: #09f;\n\tcolor: #fff;\n}\n\n#bagua-table .sw {\n\tbackground-color: #963;\n\tcolor: #fff;\n}\n\n#bagua-table .s {\n\tbackground-color: #f60;\n\tcolor: #fff;\n}\n#bagua-table .se {\n\tbackground-color: #0c3;\n\tcolor: #fff;\n}", "_id" : { "$oid" : "54c29c9cf1f6dbff33a795eb" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n
        Bagua Chart: Direction, Element, Color, Meaning
        Northwest
        Metal
        Silver
        Elders\n
        North
        Water
        Blue
        Change\n
        Northeast
        Earth
        Yellow
        Direction\n
        West
        Metal
        Gold
        Youth\n
        Center
        All
        Purple
        Harmony\n
        East
        Wood
        Blue
        Future\n
        Southwest
        Earth
        Brown
        Tranquility\n
        South
        Fire
        Orange
        Fame\n
        Southeast
        Wood
        Green
        Romance\n
        \n\n \n\n\n", "_id" : { "$oid" : "54c29c9cf1f6dbff33a795ec" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9cf1f6dbff33a795ed" }, "plunkId" : "7I2kY60Rd7RJKwvJvxJG", "webPath" : "/task/rewrite-with-jquery/source", "files" : [ { "filename" : "bagua.css", "content" : "#bagua-table th {\n\ttext-align:center;\n\tfont-weight:bold;\n}\n\n#bagua-table td {\n\twidth: 150px;\n\twhite-space: nowrap;\n\ttext-align:center;\n\tvertical-align: bottom;\n\tpadding-top: 5px;\n\tpadding-bottom: 12px;\n}\n\n#bagua-table .nw {\n\tbackground-color: #999;\n}\n\n#bagua-table .n {\n\tbackground-color: #03f;\n\tcolor: #fff;\n}\n\n#bagua-table .ne {\n\tbackground-color: #ff6;\n}\n\n#bagua-table .w {\n\tbackground-color: #ff0;\n}\n#bagua-table .c {\n\tbackground-color: #60c;\n\tcolor: #fff;\n}\n#bagua-table .e {\n\tbackground-color: #09f;\n\tcolor: #fff;\n}\n\n#bagua-table .sw {\n\tbackground-color: #963;\n\tcolor: #fff;\n}\n\n#bagua-table .s {\n\tbackground-color: #f60;\n\tcolor: #fff;\n}\n#bagua-table .se {\n\tbackground-color: #0c3;\n\tcolor: #fff;\n}", "_id" : { "$oid" : "54c29c9cf1f6dbff33a795ee" } }, { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
        Bagua Chart: Direction, Element, Color, Meaning
        Northwest
        Metal
        Silver
        Elders\n
        North
        Water
        Blue
        Change\n
        Northeast
        Earth
        Yellow
        Direction\n
        West
        Metal
        Gold
        Youth\n
        Center
        All
        Purple
        Harmony\n
        East
        Wood
        Blue
        Future\n
        Southwest
        Earth
        Brown
        Tranquility\n
        South
        Fire
        Orange
        Fame\n
        Southeast
        Wood
        Green
        Romance\n
        \n\n \n\n\n", "_id" : { "$oid" : "54c29c9cf1f6dbff33a795ef" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9cf1f6dbff33a795f4" }, "plunkId" : "U7LFG9R99rTyXjfHWtWb", "webPath" : "/article/reflow/reflow", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
        0:00:10:20:30:40:50:60:70:80:90:100:110:120:130:140:150:160:170:180:19
        1:01:11:21:31:41:51:61:71:81:91:101:111:121:131:141:151:161:171:181:19
        2:02:12:22:32:42:52:62:72:82:92:102:112:122:132:142:152:162:172:182:19
        3:03:13:23:33:43:53:63:73:83:93:103:113:123:133:143:153:163:173:183:19
        4:04:14:24:34:44:54:64:74:84:94:104:114:124:134:144:154:164:174:184:19
        5:05:15:25:35:45:55:65:75:85:95:105:115:125:135:145:155:165:175:185:19
        6:06:16:26:36:46:56:66:76:86:96:106:116:126:136:146:156:166:176:186:19
        7:07:17:27:37:47:57:67:77:87:97:107:117:127:137:147:157:167:177:187:19
        8:08:18:28:38:48:58:68:78:88:98:108:118:128:138:148:158:168:178:188:19
        9:09:19:29:39:49:59:69:79:89:99:109:119:129:139:149:159:169:179:189:19
        10:010:110:210:310:410:510:610:710:810:910:1010:1110:1210:1310:1410:1510:1610:1710:1810:19
        11:011:111:211:311:411:511:611:711:811:911:1011:1111:1211:1311:1411:1511:1611:1711:1811:19
        12:012:112:212:312:412:512:612:712:812:912:1012:1112:1212:1312:1412:1512:1612:1712:1812:19
        13:013:113:213:313:413:513:613:713:813:913:1013:1113:1213:1313:1413:1513:1613:1713:1813:19
        14:014:114:214:314:414:514:614:714:814:914:1014:1114:1214:1314:1414:1514:1614:1714:1814:19
        15:015:115:215:315:415:515:615:715:815:915:1015:1115:1215:1315:1415:1515:1615:1715:1815:19
        16:016:116:216:316:416:516:616:716:816:916:1016:1116:1216:1316:1416:1516:1616:1716:1816:19
        17:017:117:217:317:417:517:617:717:817:917:1017:1117:1217:1317:1417:1517:1617:1717:1817:19
        18:018:118:218:318:418:518:618:718:818:918:1018:1118:1218:1318:1418:1518:1618:1718:1818:19
        19:019:119:219:319:419:519:619:719:819:919:1019:1119:1219:1319:1419:1519:1619:1719:1819:19
        \n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c9cf1f6dbff33a795f5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9df1f6dbff33a79609" }, "plunkId" : "F73N7ReafvleEJlbW3oo", "webPath" : "/article/setImmediate/setImmediate", "files" : [ { "filename" : "setImmediate.js", "content" : "if (!window.setImmediate) window.setImmediate = (function() {\n var head = { }, tail = head; // очередь вызовов, 1-связный список\n\n var ID = Math.random(); // уникальный идентификатор\n\n function onmessage(e) {\n if(e.data != ID) return; // не наше сообщение\n head = head.next;\n var func = head.func;\n delete head.func;\n func();\n }\n\n if(window.addEventListener) { // IE9+, другие браузеры\n window.addEventListener('message', onmessage, false);\n } else { // IE8\n window.attachEvent( 'onmessage', onmessage );\n }\n\n return window.postMessage ? function(func) {\n tail = tail.next = { func: func };\n window.postMessage(ID, \"*\");\n } :\n function(func) { // IE<8\n setTimeout(func, 0);\n };\n}());", "_id" : { "$oid" : "54c29c9df1f6dbff33a7960a" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c9df1f6dbff33a7960b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9df1f6dbff33a7960f" }, "plunkId" : "styZMIrqcGmGU511t1uM", "webPath" : "/article/range-textrange-selection/domRangeCreate", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n
        \n\t

        Соз|даем Range-объект

        \n\t

        От третье|го символа заголовка до десятого символа это абзаца.

        \n
        \n\n\n\n\n\n\n", "_id" : { "$oid" : "54c29c9df1f6dbff33a79610" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9ef1f6dbff33a79611" }, "plunkId" : "bu8YKcKf77nYkKUHiFSJ", "webPath" : "/article/range-textrange-selection/domRangeHighlight", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
        \n Найдем в этом тексте слово \"бабуля\" и подсветим его синим фоном\n
        \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c9ef1f6dbff33a79612" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9ef1f6dbff33a79613" }, "plunkId" : "SXXlZhRFRypXYzzLFdSZ", "webPath" : "/article/range-textrange-selection/fix-ie", "files" : [ { "filename" : "fixIERangeObject.js", "content" : "/*\n This code is to fix Microsoft TextRange object (IE8 and below), to give equivalent of\n HTML5 Range object's startContainer,startOffset,endContainer and endOffset properties.\n\n Originally from: https://gist.github.com/1115251 (Munnawwar)\n*/\n\n/**\n * @param {window object} [win] Optional prameter. You could send an IFrame.contentWindow too.\n */\nfunction fixIERangeObject(range, win) { //Only for IE8 and below.\n win=win || window;\n\n if(!range) return null;\n if(!range.startContainer && win.document.selection) { //IE8 and below\n\n var _findTextNode=function(parentElement,text) {\n //Iterate through all the child text nodes and check for matches\n //As we go through each text node keep removing the text value (substring) from the beginning of the text variable.\n var container=null,offset=-1;\n for(var node=parentElement.firstChild; node; node=node.nextSibling) {\n if(node.nodeType==3) {//Text node\n var find=node.nodeValue;\n var pos=text.indexOf(find);\n if(pos==0 && text!=find) { //text==find is a special case\n text=text.substring(find.length);\n } else {\n container=node;\n offset=text.length-1; //Offset to the last character of text. text[text.length-1] will give the last character.\n break;\n }\n }\n }\n //Debug Message\n //alert(container.nodeValue);\n return {node: container,offset: offset}; //nodeInfo\n }\n\n var rangeCopy1=range.duplicate(), rangeCopy2=range.duplicate(); //Create a copy\n var rangeObj1=range.duplicate(), rangeObj2=range.duplicate(); //More copies :P\n\n rangeCopy1.collapse(true); //Go to beginning of the selection\n rangeCopy1.moveEnd('character',1); //Select only the first character\n rangeCopy2.collapse(false); //Go to the end of the selection\n rangeCopy2.moveStart('character',-1); //Select only the last character\n\n //Debug Message\n // alert(rangeCopy1.text); //Should be the first character of the selection\n var parentElement1=rangeCopy1.parentElement(), parentElement2=rangeCopy2.parentElement();\n\n //If user clicks the input button without selecting text, then moveToElementText throws an error.\n if(parentElement1 instanceof HTMLInputElement || parentElement2 instanceof HTMLInputElement) {\n return null;\n }\n rangeObj1.moveToElementText(parentElement1); //Select all text of parentElement\n rangeObj1.setEndPoint('EndToEnd',rangeCopy1); //Set end point to the first character of the 'real' selection\n rangeObj2.moveToElementText(parentElement2);\n rangeObj2.setEndPoint('EndToEnd',rangeCopy2); //Set end point to the last character of the 'real' selection\n\n var text1=rangeObj1.text; //Now we get all text from parentElement's first character upto the real selection's first character\n var text2=rangeObj2.text; //Here we get all text from parentElement's first character upto the real selection's last character\n\n var nodeInfo1=_findTextNode(parentElement1,text1);\n var nodeInfo2=_findTextNode(parentElement2,text2);\n\n //Finally we are here\n range.startContainer=nodeInfo1.node;\n range.startOffset=nodeInfo1.offset;\n range.endContainer=nodeInfo2.node;\n range.endOffset=nodeInfo2.offset+1; //End offset comes 1 position after the last character of selection.\n }\n return range;\n}\n\nfunction getRangeObject(win) { //Gets the first range object\n win=win || window;\n if (win.getSelection) { // Firefox/Chrome/Safari/Opera/IE9\n try {\n return win.getSelection().getRangeAt(0); //W3C DOM Range Object\n } catch(e) {/*If no text is selected an exception might be thrown*/}\n }\n else if(win.document.selection) { // IE8\n var range=win.document.selection.createRange(); //Microsoft TextRange Object\n return fixIERangeObject(range,win);\n }\n return null;\n}", "_id" : { "$oid" : "54c29c9ef1f6dbff33a79614" } }, { "filename" : "index.html", "content" : "\n\n \n \n \n\n \n \n \n Выделите текст:\n
        The quick brown fox jumped over the lazy dog
        \n \n \n", "_id" : { "$oid" : "54c29c9ef1f6dbff33a79615" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9ef1f6dbff33a79616" }, "plunkId" : "Tj2yjzabGMeF898GonCq", "webPath" : "/article/range-textrange-selection/ieTextRangeHighlight", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
        \n Найдем в этом тексте слово \"бабуля\" и подсветим его синим фоном\n
        \n
        \n \n
        \n\n\n\n", "_id" : { "$oid" : "54c29c9ef1f6dbff33a79617" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29c9ff1f6dbff33a79618" }, "plunkId" : "uPKxszvrgpjj9tEY1G8S", "webPath" : "/article/range-textrange-selection/setSelection", "files" : [ { "filename" : "index.html", "content" : "\n\n\n \n\n\n\n
        \n Снова будем выделять бабулю, на этот раз без поиска.\n
        \n
        \n \n
        \n\n\n\n\n", "_id" : { "$oid" : "54c29c9ff1f6dbff33a79619" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29ca0f1f6dbff33a7961b" }, "plunkId" : "DDHEKOum8rHO07t1N9Bn", "webPath" : "/article/drag-and-drop-plus/dragTree", "files" : [ { "filename" : "DragAvatar.js", "content" : "/**\n * \"Аватар\" - элемент, который перетаскивается.\n *\n * В простейшем случае аватаром является сам переносимый элемент\n * Также аватар может быть клонированным элементом\n * Также аватар может быть иконкой и вообще чем угодно.\n */\nfunction DragAvatar(dragZone, dragElem) {\n /** \"родительская\" зона переноса */\n this._dragZone = dragZone;\n\n /**\n * подэлемент родительской зоны, к которому относится аватар\n * по умолчанию - элемент, соответствующий всей зоне\n * может быть уточнен в initFromEvent\n */\n this._dragZoneElem = dragElem;\n\n /**\n * Сам элемент аватара, который будет носиться по экрану.\n * Инициализуется в initFromEvent\n */\n this._elem = dragElem;\n}\n\n/**\n * Инициализовать this._elem и позиционировать его\n * При необходимости уточнить this._dragZoneElem\n * @param downX Координата X нажатия мыши\n * @param downY Координата Y нажатия мыши\n * @param event Текущее событие мыши\n */\nDragAvatar.prototype.initFromEvent = function(downX, downY, event) {\n /* override */\n};\n\n/**\n * Возвращает информацию о переносимом элементе для DropTarget\n * @param event\n */\nDragAvatar.prototype.getDragInfo = function(event) {\n // тут может быть еще какая-то информация, необходимая для обработки конца или процесса переноса\n return {\n elem: this._elem,\n dragZoneElem: this._dragZoneElem,\n dragZone: this._dragZone\n };\n};\n\n/**\n * Возвращает текущий самый глубокий DOM-элемент под this._elem\n * Приватное свойство _currentTargetElem обновляется при каждом передвижении\n */\nDragAvatar.prototype.getTargetElem = function() {\n return this._currentTargetElem;\n};\n\n/**\n * При каждом движении мыши перемещает this._elem\n * и записывает текущий элемент под this._elem в _currentTargetElem\n * @param event\n */\nDragAvatar.prototype.onDragMove = function(event) {\n this._elem.style.left = event.pageX - this._shiftX + 'px';\n this._elem.style.top = event.pageY - this._shiftY + 'px';\n\n this._currentTargetElem = getElementUnderClientXY(this._elem, event.clientX, event.clientY);\n};\n\n/**\n * Действия с аватаром, когда перенос не удался\n * Например, можно вернуть элемент обратно или уничтожить\n */\nDragAvatar.prototype.onDragCancel = function() {\n /* override */\n};\n\n/**\n * Действия с аватаром после успешного переноса\n */\nDragAvatar.prototype.onDragEnd = function() {\n /* override */\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a7961c" } }, { "filename" : "DragManager.js", "content" : "var dragManager = new function() {\n\n var dragZone, avatar, dropTarget;\n var downX, downY;\n\n var self = this;\n\n function onMouseDown(e){\n\n if (e.which != 1 ) { // не левой кнопкой\n return false;\n }\n\n dragZone = findDragZone(e);\n\n if (!dragZone) {\n\t return;\n }\n\n // запомним, что элемент нажат на текущих координатах pageX/pageY\n downX = e.pageX;\n downY = e.pageY;\n\n return false;\n }\n\n function onMouseMove(e) {\n if (!dragZone) return; // элемент не зажат\n\n if ( !avatar ) { // элемент нажат, но пока не начали его двигать\n if ( Math.abs(e.pageX-downX) < 3 && Math.abs(e.pageY-downY) < 3 ) {\n return;\n }\n // попробовать захватить элемент\n avatar = dragZone.onDragStart(downX, downY, e);\n\n if (!avatar) { // не получилось, значит перенос продолжать нельзя\n cleanUp(); // очистить приватные переменные, связанные с переносом\n return;\n }\n }\n\n // отобразить перенос объекта, перевычислить текущий элемент под курсором\n avatar.onDragMove(e);\n\n // найти новый dropTarget под курсором: newDropTarget\n // текущий dropTarget остался от прошлого mousemove\n // *оба значения: и newDropTarget и dropTarget могут быть null\n var newDropTarget = findDropTarget(e);\n\n if (newDropTarget != dropTarget) {\n // уведомить старую и новую зоны-цели о том, что с них ушли/на них зашли\n dropTarget && dropTarget.onDragLeave(newDropTarget, avatar, e);\n newDropTarget && newDropTarget.onDragEnter(dropTarget, avatar, e);\n }\n\n dropTarget = newDropTarget;\n\n dropTarget && dropTarget.onDragMove(avatar, e);\n\n return false;\n }\n\n function onMouseUp(e) {\n\n if (e.which != 1 ) { // не левой кнопкой\n return false;\n }\n\n if (avatar) { // если уже начали передвигать\n\n if (dropTarget) {\n // завершить перенос и избавиться от аватара, если это нужно\n // эта функция обязана вызвать avatar.onDragEnd/onDragCancel\n dropTarget.onDragEnd(avatar, e);\n } else {\n avatar.onDragCancel();\n }\n\n }\n\n cleanUp();\n }\n\n function cleanUp() {\n // очистить все промежуточные объекты\n dragZone = avatar = dropTarget = null;\n }\n\n function findDragZone(event) {\n var elem = event.target;\n while(elem != document && !elem.dragZone) {\n elem = elem.parentNode;\n }\n return elem.dragZone;\n }\n\n function findDropTarget(event) {\n // получить элемент под аватаром\n var elem = avatar.getTargetElem();\n\n while(elem != document && !elem.dropTarget) {\n elem = elem.parentNode;\n }\n\n if (!elem.dropTarget) {\n return null;\n }\n\n return elem.dropTarget;\n }\n\n document.ondragstart = function() {\n return false;\n }\n\n document.onmousemove = onMouseMove;\n document.onmouseup = onMouseUp;\n document.onmousedown = onMouseDown;\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a7961d" } }, { "filename" : "DragZone.js", "content" : "/**\n * Зона, из которой можно переносить объекты\n * Умеет обрабатывать начало переноса на себе и создавать \"аватар\"\n * @param elem DOM-элемент, к которому привязана зона\n */\nfunction DragZone(elem) {\n elem.dragZone = this;\n this._elem = elem;\n}\n\n/**\n * Создать аватар, соответствующий зоне.\n * У разных зон могут быть разные типы аватаров\n */\nDragZone.prototype._makeAvatar = function() {\n /* override */\n};\n\n/**\n * Обработать начало переноса.\n *\n * Получает координаты изначального нажатия мышки, событие.\n *\n * @param downX Координата изначального нажатия по X\n * @param downY Координата изначального нажатия по Y\n * @param event текущее событие мыши\n *\n * @return аватар или false, если захватить с данной точки ничего нельзя\n */\nDragZone.prototype.onDragStart = function(downX, downY, event) {\n\n var avatar = this._makeAvatar();\n\n if (!avatar.initFromEvent(downX, downY, event)) {\n return false;\n }\n\n return avatar;\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a7961e" } }, { "filename" : "DropTarget.js", "content" : "/**\n * Зона, в которую объекты можно класть\n * Занимается индикацией передвижения по себе, добавлением в себя\n */\nfunction DropTarget(elem) {\n elem.dropTarget = this;\n this._elem = elem;\n\n /**\n * Подэлемент, над которым в настоящий момент находится аватар\n */\n this._targetElem = null;\n}\n\n/**\n * Возвращает DOM-подэлемент, над которым сейчас пролетает аватар\n *\n * @return DOM-элемент, на который можно положить или undefined\n */\nDropTarget.prototype._getTargetElem = function(avatar, event) {\n return this._elem;\n};\n\n/**\n * Спрятать индикацию переноса\n * Вызывается, когда аватар уходит с текущего this._targetElem\n */\nDropTarget.prototype._hideHoverIndication = function(avatar) {\n /* override */\n};\n\n/**\n * Показать индикацию переноса\n * Вызывается, когда аватар пришел на новый this._targetElem\n */\nDropTarget.prototype._showHoverIndication = function(avatar) {\n /* override */\n};\n\n/**\n * Метод вызывается при каждом движении аватара\n */\nDropTarget.prototype.onDragMove = function(avatar, event) {\n\n var newTargetElem = this._getTargetElem(avatar, event);\n\n if (this._targetElem != newTargetElem) {\n\n this._hideHoverIndication(avatar);\n this._targetElem = newTargetElem;\n this._showHoverIndication(avatar);\n }\n};\n\n/**\n * Завершение переноса.\n * Алгоритм обработки (переопределить функцию и написать в потомке):\n * 1. Получить данные переноса из avatar.getDragInfo()\n * 2. Определить, возможен ли перенос на _targetElem (если он есть)\n * 3. Вызвать avatar.onDragEnd() или avatar.onDragCancel()\n * Если нужно подтвердить перенос запросом на сервер, то avatar.onDragEnd(),\n * а затем асинхронно, если сервер вернул ошибку, avatar.onDragCancel()\n * При этом аватар должен уметь \"откатываться\" после onDragEnd.\n *\n * При любом завершении этого метода нужно (делается ниже):\n * снять текущую индикацию переноса\n * обнулить this._targetElem\n */\nDropTarget.prototype.onDragEnd = function(avatar, event) {\n this._hideHoverIndication(avatar);\n this._targetElem = null;\n};\n\n/**\n * Вход аватара в DropTarget\n */\nDropTarget.prototype.onDragEnter = function(fromDropTarget, avatar, event) {\n};\n\n/**\n * Выход аватара из DropTarget\n */\nDropTarget.prototype.onDragLeave = function(toDropTarget, avatar, event) {\n this._hideHoverIndication();\n this._targetElem = null;\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a7961f" } }, { "filename" : "TreeDragAvatar.js", "content" : "function TreeDragAvatar(dragZone, dragElem) {\n DragAvatar.apply(this, arguments);\n}\n\nextend(TreeDragAvatar, DragAvatar);\n\nTreeDragAvatar.prototype.initFromEvent = function(downX, downY, event) {\n if (event.target.tagName != 'SPAN') return false;\n\n this._dragZoneElem = event.target;\n var elem = this._elem = this._dragZoneElem.cloneNode(true);\n elem.className = 'avatar';\n\n // создать вспомогательные свойства shiftX/shiftY\n var coords = getCoords(this._dragZoneElem);\n this._shiftX = downX - coords.left;\n this._shiftY = downY - coords.top;\n\n // инициировать начало переноса\n document.body.appendChild(elem);\n elem.style.zIndex = 9999;\n elem.style.position = 'absolute';\n\n return true;\n};\n\n/**\n * Вспомогательный метод\n */\nTreeDragAvatar.prototype._destroy = function() {\n this._elem.parentNode.removeChild(this._elem);\n};\n\n/**\n * При любом исходе переноса элемент-клон больше не нужен\n */\nTreeDragAvatar.prototype.onDragCancel = function() {\n this._destroy();\n};\n\nTreeDragAvatar.prototype.onDragEnd = function() {\n this._destroy();\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79620" } }, { "filename" : "TreeDragZone.js", "content" : "function TreeDragZone(elem) {\n DragZone.apply(this, arguments);\n}\n\nextend(TreeDragZone, DragZone);\n\nTreeDragZone.prototype._makeAvatar = function() {\n return new TreeDragAvatar(this, this._elem);\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79621" } }, { "filename" : "TreeDropTarget.js", "content" : "function TreeDropTarget(elem) {\n TreeDropTarget.parent.constructor.apply(this, arguments);\n}\n\nextend(TreeDropTarget, DropTarget);\n\nTreeDropTarget.prototype._showHoverIndication = function() {\n this._targetElem && this._targetElem.classList.add('hover');\n};\n\nTreeDropTarget.prototype._hideHoverIndication = function() {\n this._targetElem && this._targetElem.classList.remove('hover');\n};\n\nTreeDropTarget.prototype._getTargetElem = function(avatar, event) {\n var target = avatar.getTargetElem();\n if (target.tagName != 'SPAN') {\n return;\n }\n\n // проверить, может быть перенос узла внутрь самого себя или в себя?\n var elemToMove = avatar.getDragInfo(event).dragZoneElem.parentNode;\n\n var elem = target;\n while(elem) {\n if (elem == elemToMove) return; // попытка перенести родителя в потомка\n elem = elem.parentNode;\n }\n\n return target;\n};\n\nTreeDropTarget.prototype.onDragEnd = function(avatar, event) {\n\n if (!this._targetElem) {\n // перенос закончился вне подходящей точки приземления\n avatar.onDragCancel();\n return;\n }\n\n this._hideHoverIndication();\n\n // получить информацию об объекте переноса\n var avatarInfo = avatar.getDragInfo(event);\n\n avatar.onDragEnd(); // аватар больше не нужен, перенос успешен\n\n // вставить элемент в детей в отсортированном порядке\n var elemToMove = avatarInfo.dragZoneElem.parentNode; //
      4. \n var title = avatarInfo.dragZoneElem.innerHTML; // переносимый заголовок\n\n // получить контейнер для узлов дерева, соответствующий точке преземления\n var ul = this._targetElem.parentNode.getElementsByTagName('UL')[0];\n if (!ul) { // нет детей, создадим контейнер\n ul = document.createElement('UL');\n this._targetElem.parentNode.appendChild(ul);\n }\n\n // вставить новый узел в нужное место среди потомков, в алфавитном порядке\n var li = null;\n for(var i=0; i < ul.children.length; i++) {\n li = ul.children[i];\n var childTitle = li.children[0].innerHTML;\n if (childTitle > title) {\n break;\n }\n }\n\n ul.insertBefore(elemToMove, li);\n\n this._targetElem = null;\n};", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79622" } }, { "filename" : "lib.js", "content" : "function getCoords(elem) {\n var box = elem.getBoundingClientRect();\n\n var body = document.body;\n var docElem = document.documentElement;\n\n var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;\n var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;\n\n var clientTop = docElem.clientTop || body.clientTop || 0;\n var clientLeft = docElem.clientLeft || body.clientLeft || 0;\n\n var top = box.top + scrollTop - clientTop;\n var left = box.left + scrollLeft - clientLeft;\n\n return { top: Math.round(top), left: Math.round(left) };\n}\n\nfunction getElementUnderClientXY(elem, clientX, clientY) {\n var display = elem.style.display || '';\n elem.style.display = 'none';\n\n var target = document.elementFromPoint(clientX, clientY);\n\n elem.style.display = display;\n\n if (!target || target == document) { // это бывает при выносе за границы окна\n target = document.body; // поправить значение, чтобы был именно элемент\n }\n\n return target;\n}\n\nfunction extend(Child, Parent) {\n function F() { }\n F.prototype = Parent.prototype\n Child.prototype = new F()\n Child.prototype.constructor = Child\n Child.parent = Parent.prototype\n}", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79623" } }, { "filename" : "dragTree.css", "content" : "#tree span:hover {\n cursor: pointer;\n font-weight: bold;\n}\n\n/* #tree span.hover, для приоритета перед :hover также добавлен подселектор */\n#tree span.hover, #tree span.hover:hover {\n color: red;\n font-weight: bold;\n cursor: pointer;\n}\n\nspan.avatar {\n padding: 1px;\n border: 1px dotted black;\n background: white;\n cursor: pointer;\n opacity: 0.6;\n filter:progid:DXImageTransform.Microsoft.Alpha(opacity=60); /* IE opacity */\n}", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79624" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n \n \n \n \n \n \n \n \n\n\n\nВозьмите за любой заголовок и поменяйте ему родителя.
        \nВ собственных детей перенести нельзя.
        \nПотомки всегда отсортированы по алфавиту.\n\n
          \n
        • Древо жизни (сверхмалая часть)\n
            \n
          • Грибы\n
              \n
            • Древесные\n
                \n
              • Чага
              • \n
              \n
            • \n
            • Наземные\n
                \n
              • Опята
              • \n
              • Подосиновики
              • \n
              \n\n
            • \n
            \n
          • \n
          • Животные\n
              \n
            • Земноводные\n
                \n
              • Лягушки
              • \n
              • Саламандры
              • \n
              • Тритоны
              • \n
              \n
            • \n
            • Млекопитающие\n
                \n
              • Коровы
              • \n
              • Ослы
              • \n
              • Собаки
              • \n
              • Тигры
              • \n
              \n
            • \n
            \n
          • \n
          \n
        • \n
        \n\n\n\n\n", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79625" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c29ca0f1f6dbff33a7962f" }, "plunkId" : "dLGNU3cuU4XhaCXT8eRo", "webPath" : "/article/clickjacking/clickjacking", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n
        Нажмите, чтобы разбогатеть сейчас:
        \n\n\n\nНажми тут!\n\n
        ..И ваша жизнь удалась!
        \n\n\n", "_id" : { "$oid" : "54c29ca0f1f6dbff33a79630" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c3ea0512cfeb4f48fc15c2" }, "plunkId" : "HUP5byLVjTVC5jZl5YyI", "webPath" : "/task/tree-count/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n
          \n
        • Животные\n
            \n
          • Млекопитающие\n
              \n
            • Коровы
            • \n
            • Ослы
            • \n
            • Собаки
            • \n
            • Тигры
            • \n
            \n
          • \n
          • Другие\n
              \n
            • Змеи
            • \n
            • Птицы
            • \n
            • Ящерицы
            • \n
            \n
          • \n
          \n
        • \n
        • Рыбы\n
            \n
          • Аквариумные\n
              \n
            • Гуппи
            • \n
            • Скалярии
            • \n
            \n\n
          • \n
          • Морские\n
              \n
            • Морская форель
            • \n
            \n
          • \n
          \n
        • \n
        \n\n\n\n\n", "_id" : { "$oid" : "54c3ea0512cfeb4f48fc15c3" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c3ea0512cfeb4f48fc15c4" }, "plunkId" : "OEvwAMmeEH2HQUDdKswr", "webPath" : "/task/tree-count/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n
          \n
        • Животные\n
            \n
          • Млекопитающие\n
              \n
            • Коровы
            • \n
            • Ослы
            • \n
            • Собаки
            • \n
            • Тигры
            • \n
            \n
          • \n
          • Другие\n
              \n
            • Змеи
            • \n
            • Птицы
            • \n
            • Ящерицы
            • \n
            \n
          • \n
          \n
        • \n
        • Рыбы\n
            \n
          • Аквариумные\n
              \n
            • Гуппи
            • \n
            • Скалярии
            • \n
            \n\n
          • \n
          • Морские\n
              \n
            • Морская форель
            • \n
            \n
          • \n
          \n
        • \n
        \n\n\n\n\n", "_id" : { "$oid" : "54c3ea0512cfeb4f48fc15c5" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54c3efbc12cfeb4f48fc1646" }, "plunkId" : "ecXodeWkQUWxZDv4M8W4", "webPath" : "/article/multi-insert/benchmark", "files" : [ { "filename" : "documentfragment-bench.js", "content" : "var DocumentFragmentTest = new function() {\n var benchList = document.getElementById('bench-list');\n\n var items = [];\n for(var i=0; i<100; i++) {\n var li = document.createElement('li');\n li.innerHTML = i;\n items.push(li);\n }\n\n this.insertPlain = new function() {\n\n this.setup = function() {\n while(benchList.firstChild) {\n benchList.removeChild(benchList.firstChild);\n }\n }\n\n this.work = function() {\n for(var i=0; i\n\n\n \n\n\n\nВставляются 100 элементов LI в пустой UL.\n\n\n\n\n\n
          \n\n\n\n\n\n", "_id" : { "$oid" : "54c4d6f62ca71e206c14bc3a" } } ], "description" : "Fork from http://javascript.ru", "__v" : 2 },{ "_id" : { "$oid" : "54c526bb70865b381ee24e5b" }, "plunkId" : "P5QJ6YoLyHEMuwahQI79", "webPath" : "/article/styles-and-classes/getiecomputedstyle", "files" : [ { "filename" : "getiecomputedstyle.js", "content" : "function getIEComputedStyle(elem, prop) {\n var value = elem.currentStyle[prop] || 0;\n\n // we use 'left' property as a place holder so backup values\n var leftCopy = elem.style.left;\n var runtimeLeftCopy = elem.runtimeStyle.left;\n\n // assign to runtimeStyle and get pixel value\n elem.runtimeStyle.left = elem.currentStyle.left;\n elem.style.left = (prop === \"fontSize\") ? \"1em\" : value;\n value = elem.style.pixelLeft + \"px\";\n\n // restore values for left\n elem.style.left = leftCopy;\n elem.runtimeStyle.left = runtimeLeftCopy;\n\n return value;\n}", "_id" : { "$oid" : "54c526bb70865b381ee24e5c" } }, { "filename" : "index.html", "content" : "\n\n\n \n \n\n\n\n\n\n
          Тестовый элемент с margin 1%
          \n\n\n\n", "_id" : { "$oid" : "54c526bb70865b381ee24e5d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54d5c32a59612a6f7a133c8a" }, "plunkId" : "Yf8CyrLas1qGpPX633i7", "webPath" : "/task/pageyoffset-polyfill/solution", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
          \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . \n
          \n\n\n\n\n\n\n\n", "_id" : { "$oid" : "54d5c32a59612a6f7a133c8b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54d5c32b59612a6f7a133c8c" }, "plunkId" : "NA9yOpZ4NvN23KHjGTRd", "webPath" : "/task/pageyoffset-polyfill/source", "files" : [ { "filename" : "index.html", "content" : "\n\n\n\n\n\n\n\n
          \n\n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . \n
          \n\n\n\n\n", "_id" : { "$oid" : "54d5c32b59612a6f7a133c8d" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 },{ "_id" : { "$oid" : "54de0b4ea269a91669948b32" }, "plunkId" : "RZfrNUGDjufCx90MGM1b", "webPath" : "/task/hoverintent/solution", "files" : [ { "filename" : "hoverIntent.js", "content" : "function HoverIntent(options) {\n\n options = Object.create(options); // not to modify the object\n options.interval = options.interval || 100;\n\n // скорость меньше 1px/ms считается остановкой над элементом\n options.sensitivity = options.sensitivity || 0.1;\n var elem = options.elem;\n\n // instantiate variables\n // cX, cY = current X and Y position of mouse, updated by mousemove event\n // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval\n var cX, cY, pX, pY, cTime, pTime;\n var checkSpeedInterval;\n var isOverElement;\n var isHover;\n\n // A private function for handling mouse 'hovering'\n elem.addEventListener(\"mouseover\", function(event) {\n\n if (isOverElement) {\n // если мы и так над элементом, то это всплывший переход внутри него\n // мы и так уже замеряем скорость, поэтому этот переход лишний\n return;\n }\n\n isOverElement = true;\n\n // при каждом движении мыши mousemove мы будем вычислять расстояние между\n // предыдущими и текущими координатами курсора\n // если оно меньше sensivity, то скорость маленькая и это наведение на элемент\n // pX, pY - \"предыдущие\" координаты\n pX = event.pageX;\n pY = event.pageY;\n pTime = Date.now();\n\n elem.addEventListener('mousemove', onMouseMove);\n });\n\n elem.addEventListener(\"mouseout\", function(event) {\n // если ушли вовне элемента\n if (event.relatedTarget && !elem.contains(event.relatedTarget)) {\n isOverElement = false;\n elem.removeEventListener('mousemove', onMouseMove);\n if (isHover) {\n // если была остановка над элементом\n options.out.call(elem, event);\n isHover = false;\n }\n }\n });\n\n function onMouseMove(event) {\n cX = event.pageX;\n cY = event.pageY;\n cTime = Date.now();\n\n if (pTime == cTime) return; // когда mousemove вместе с mouseover\n\n var speed = Math.sqrt(Math.pow(pX - cX, 2) + Math.pow(pY - cY, 2)) / (cTime - pTime);\n\n if (speed < options.sensitivity) {\n // если с предыдущей позиции меньше sensivity дистанция, то \"остановка на элементе\"\n elem.removeEventListener(\"mousemove\", onMouseMove);\n isHover = true;\n options.over.call(elem, event);\n } else {\n // следующее измерение с текущей точки\n pX = cX;\n pY = cY;\n pTime = cTime;\n }\n }\n\n}", "_id" : { "$oid" : "54de0b4ea269a91669948b33" } }, { "filename" : "index.html", "content" : "\n\n\n \n Document\n \n \n\n\n\n\n
          \n 12\n :\n 30\n :\n 00\n
          \n\n \n\n\n\n\n\n", "_id" : { "$oid" : "54de0b58a269a91669948b38" } }, { "filename" : "style.css", "content" : ".hours {\n color: red;\n}\n\n.minutes {\n color: green;\n}\n\n.seconds {\n color: blue;\n}\n\n.clock {\n border: 1px dashed black;\n padding: 5px;\n display: inline-block;\n margin: 30px;\n background: yellow;\n}\n\n.tooltip {\n position: absolute;\n background: #eee;\n border: 1px brown solid;\n padding: 3px;\n}", "_id" : { "$oid" : "54de0b5ba269a91669948b3b" } } ], "description" : "Fork from http://javascript.ru", "__v" : 2 },{ "_id" : { "$oid" : "54de11f66094e9391ebf7e99" }, "plunkId" : "SJ5WoYEySpBz6O31v1Hb", "webPath" : "/task/hoverintent/source", "files" : [ { "filename" : "hoverIntent.js", "content" : "function HoverIntent(options) {\n /* ваш код */\n}", "_id" : { "$oid" : "54de11f66094e9391ebf7e9a" } }, { "filename" : "style.css", "content" : ".hours {\n color: red;\n}\n\n.minutes {\n color: green;\n}\n\n.seconds {\n color: blue;\n}\n\n.clock {\n border: 1px dashed black;\n padding: 5px;\n display: inline-block;\n margin: 30px;\n background: yellow;\n}\n\n.tooltip {\n position: absolute;\n background: #eee;\n border: 1px brown solid;\n padding: 3px;\n}", "_id" : { "$oid" : "54de11f66094e9391ebf7e9b" } }, { "filename" : "index.html", "content" : "\n\n\n \n Document\n \n \n\n\n\n\n
          \n 12\n :\n 30\n :\n 00\n
          \n\n \n\n\n\n\n\n", "_id" : { "$oid" : "54de11f66094e9391ebf7e9c" } } ], "description" : "Fork from http://javascript.ru", "__v" : 0 }]