diff --git a/2-ui/2-events/index.md b/2-ui/2-events/index.md
index ffec0857..07f06fdd 100644
--- a/2-ui/2-events/index.md
+++ b/2-ui/2-events/index.md
@@ -1,3 +1,3 @@
-# Events
+# Introduction into Events
An introduction to browser events, event properties and handling patterns.
diff --git a/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/solution.md b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/solution.md
new file mode 100644
index 00000000..e69de29b
diff --git a/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/solution.view/index.html b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/solution.view/index.html
new file mode 100755
index 00000000..56756633
--- /dev/null
+++ b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/solution.view/index.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+ Click on a list item to select it.
+
+
+
+
Christopher Robin
+
Winnie-the-Pooh
+
Tigger
+
Kanga
+
Rabbit. Just rabbit.
+
+
+
+
+
+
diff --git a/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/source.view/index.html b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/source.view/index.html
new file mode 100755
index 00000000..e18d4a99
--- /dev/null
+++ b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/source.view/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+ Click on a list item to select it.
+
+
+
+
Christopher Robin
+
Winnie-the-Pooh
+
Tigger
+
Kanga
+
Rabbit. Just rabbit.
+
+
+
+
+
+
diff --git a/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/task.md b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/task.md
new file mode 100644
index 00000000..f358616e
--- /dev/null
+++ b/2-ui/3-event-details/1-mouse-clicks/01-selectable-list/task.md
@@ -0,0 +1,17 @@
+importance: 5
+
+---
+
+# Selectable list
+
+Create a list where elements are selectable, like in file-managers.
+
+- A click on a list element selects only that element (adds the class `.selected`), deselects all others.
+- If a click is made with `key:Ctrl` (`key:Cmd` for Mac), then the selection is toggled on the element, but other elements are not modified.
+
+The demo:
+
+[iframe border="1" src="solution" height=180]
+
+P.S. For this task we can assume that list items are text-only. No nested tags.
+P.P.S. Prevent the native browser selection of the text on clicks.
diff --git a/2-ui/3-event-details/1-mouse-clicks/article.md b/2-ui/3-event-details/1-mouse-clicks/article.md
new file mode 100644
index 00000000..c5d80ad6
--- /dev/null
+++ b/2-ui/3-event-details/1-mouse-clicks/article.md
@@ -0,0 +1,260 @@
+# Mouse: clicks, coordinates
+
+In this chapter we'll get into more details of mouse events and their properties.
+
+[cut]
+
+## Mouse event types
+
+We can split mouse events into two categories: "simple" and "complex"
+
+### Simple events
+
+The most used simple events are:
+
+`mousedown/mouseup`
+: Mouse button is clicked/released over an element.
+
+`mouseover/mouseout`
+: Mouse pointer comes over/out an element.
+
+`mousemove`
+: Every mouse move over an element triggers that event.
+
+There are several other event types too, we'll cover them later.
+
+### Complex events
+
+`click`
+: Triggers after `mousedown` and then `mouseup` over the same element.
+
+`contextmenu`
+: Triggers after `mousedown` if the right mouse button was used.
+
+`dblclick`
+: Triggers after a double click over an element.
+
+Complex events are made of simple ones, so in theory we could live without them. But they exist, and that's good, because they are convenient.
+
+For touchscreen devices mouse events also happen, because they are emulated.
+
+### Events order
+
+An action may trigger multiple events.
+
+For instance, a click first triggers `mousedown`, when the button is pressed, then `mouseup` and `click` when it's released.
+
+In cases when a single action initiated multiple events, their order is fixed. That is, the handlers are be called in the order `mousedown` -> `mouseup` -> `click`. Events are handled in sequence: `onmouseup` finishes before `onclick` runs.
+
+```online
+Click the button below and you'll see which events happen. Try double-click too.
+
+On the teststand below all mouse events are logged, and if there are more than 1 second delay between them, then they are separated by a horizontal ruler.
+
+Also we can see the `which` property that allows to detect the mouse button. We'll cover it a bit later.
+
+
+```
+
+## Getting the button: which
+
+Click-related events always have the `which` property that allows to see the button.
+
+It is not used for `click` and `contextmenu` events, because the former happens only on left-click, and the latter -- only on right-click.
+
+But if we track `mousedown` and `mouseup`, then we need it, because they trigger on any button.
+
+There are the three possible values:
+
+- `event.which == 1` -- the left button
+- `event.which == 2` - the middle button
+- `event.which == 3` - the right button
+
+The middle button is somewhat exotic right now.
+
+## Modifiers: shift, alt, ctrl and meta
+
+All mouse events include the information about pressed modifier keys.
+
+The properties are:
+
+- `shiftKey`
+- `altKey`
+- `ctrlKey`
+- `metaKey` (for Mac)
+
+For instance, the button below only works on `key:Alt+Shift`+click:
+
+```html autorun height=60
+
+
+
+```
+
+```warn header="Attention: on Mac it's usually `Cmd` instead of `Ctrl`"
+On Windows and Linux there are modifier keys `key:Alt`, `key:Shift` and `key:Ctrl`. On Mac there's one more: `key:Cmd`, that corresponds to the property `metaKey`.
+
+In most cases when Windows/Linux uses `key:Ctrl`, on Mac people use `key:Cmd`. So where a Windows user presses `key:Ctrl+Enter` or `key:Ctrl+A`, a Mac user would press `key:Cmd+Enter` or `key:Cmd+A`, and so on, most apps use `key:Cmd` instead of `key:Ctrl`.
+
+So if we want to support combinations like `key:Ctrl`+click, then for Mac it makes sense to use `key:Cmd`+click. That's more comfortable for Mac users.
+
+Even if we'd like to force Mac users to `key:Ctrl`+click -- that's kind of difficult. The problem is: a regular click with `key:Ctrl` is interpreted as a *right click* on Mac, and it generates the `contextmenu` event, not `click` like Windows/Linux.
+
+So if we want users of all operational systems to feel comfortable, then together with `ctrlKey` we should use `metaKey`.
+
+For JS-code it means that we should check `if (event.ctrlKey || event.metaKey)`.
+```
+
+```warn header="There are also mobile devices"
+Keyboard combinations are good as an addition to the workflow. So that if you have keyboard -- it works. And if your device doesn't have it -- then there's another way to do the same.
+```
+
+## Coordinates: clientX/Y, pageX/Y
+
+All mouse events have coordinates in two flavours:
+
+1. Window-relative: `clientX` and `clientY`.
+2. Document-relative: `pageX` and `pageY`.
+
+See more about coordinates the chapter .
+
+For instance, if we have a window of the size 500x500, and the mouse is in the center, then `clientX` and `clientY` are `250`.
+
+If we scroll the page, but the mouse is still in the center, then `clientX/Y` don't change, because they are window-relative.
+
+````online
+Move the mouse over the input field to see `clientX/clientY`:
+
+```html autorun height=50
+
+```
+````
+
+That's like `elem.getBoundingClientRect()` and `position:fixed`.
+
+Document-relative coordinates are counted from the left-upper corner of the document, not the window. In case of a scrolled page, they also include the scrolled out left-upper part.
+
+These coordinates are connected by the formulas:
+
+```js
+// for an arbitrary mouse event
+event.pageX = pageXOffset + event.clientX
+event.pageY = pageYOffset + event.clientY
+```
+
+So technically we don't need `pageX/Y`, because we can always calculate them using the formulas. But it's good that we have them, as a matter of convenience.
+
+## No selection on mousedown
+
+Mouse clicks have a side-effect that may be disturbing. A double click or an occasional cursor move with a pressed button select the text.
+
+If we want to handle click events ourselves, then the "extra" selection doesn't look good.
+
+For instance, a double-click on the text below selects it in addition to our handler:
+
+```html autorun height=50
+Double-click me
+```
+
+There's a CSS way to stop the selection: the `user-select` property from [CSS UI Draft](https://www.w3.org/TR/css-ui-4/).
+
+It's yet in the draft, so browser support it with prefixes:
+
+```html autorun height=50
+
+
+Before...
+
+ Unselectable
+
+...After
+```
+
+Now if you double-click on `"Unselectable"`, it doesn't get selected. Seems to work.
+
+...But there is a side-effect! The text became truly unselectable. Even if a user starts the selection from `"Before"` and ends with `"After"`, the selection skips `"Unselectable"` part. Do we really want to make our text unselectable?
+
+Most of time, not really. A user may want to select it, for copying or other needs. That may be disturbing if we don't allow him to do it. So the solution is not that good.
+
+What we want is to "fix" our interface. We don't want the selection to occur on double-click, that's it.
+
+An alternative solution would be to handle `mousedown`, like this:
+
+```html autorun height=50
+Before...
+
+ Double-click me
+
+...After
+```
+
+The selection is started on `mousedown` as a default browser action. So if we prevent it, then the bold element is not selected any more on clicks. That's as intended.
+
+From the other hand, the text inside it is still selectable. The only limitation: the selection should start not on the text itself, but from "before" or "after" it. Usually that's not a problem.
+
+````smart header="Canceling the selection"
+Instead of *preventing* the selection, we can cancel it "post-factum" in the event handler.
+
+Here's how:
+
+```html autorun height=50
+Before...
+
+ Double-click me
+
+...After
+```
+
+If you double-click on the bold element, then the selection appears and then is immediately removed. That doesn't look nice, and is not fully reliable though.
+````
+
+````smart header="Preventing copying"
+If we want to disable selection to protect our content from copy-pasting, then we can use another event: `oncopy`.
+
+```html autorun height=80 no-beautify
+
+ Dear user,
+ The copying is forbidden for you.
+ If you know JS or HTML, then that's not a problem of course,
+ otherwise we're sorry.
+
+```
+If you try to copy a piece of text in the `
`, that won't work, because the default action `oncopy` is prevented.
+
+Surely that doesn't stop from opening HTML-source and doing things manually, but not everyone knows how to do it.
+````
+
+## Summary
+
+Mouse events have following properties:
+
+- Button: `which`
+- Modifier keys (`true` if pressed): `altKey`, `ctrlKey`, `shiftKey` and `metaKey` (Mac).
+ - If you want to handle `key:Ctrl`, then don't forget Mac users, they use `key:Cmd`, so it's better to check `if (e.metaKey || e.ctrlKey)`.
+
+- Window-relative coordinates: `clientX/clientY`
+- Document-relative coordinates: `pageX/clientX`
+
+In the tasks below it's also important to deal with the selection as an unwanted side-effect of clicks.
+
+There are several ways, for instance:
+1. CSS-property `user-select:none` (with browser prefixes) completely disables it.
+2. Cancel the selection post-factum using `getSelection().removeAllRanges()`.
+3. Handle `mousedown` and prevent the default action.
+
+The third way is preferred most of the time.
diff --git a/2-ui/3-event-details/1-mouse-clicks/head.html b/2-ui/3-event-details/1-mouse-clicks/head.html
new file mode 100644
index 00000000..461f0e85
--- /dev/null
+++ b/2-ui/3-event-details/1-mouse-clicks/head.html
@@ -0,0 +1,47 @@
+
diff --git a/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md b/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md
new file mode 100644
index 00000000..bb5f4e17
--- /dev/null
+++ b/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md
@@ -0,0 +1,204 @@
+# Загрузка документа: DOMContentLoaded, load, beforeunload, unload
+
+Процесс загрузки HTML-документа, условно, состоит из трёх стадий:
+
+- `DOMContentLoaded` -- браузер полностью загрузил HTML и построил DOM-дерево.
+- `load` -- браузер загрузил все ресурсы.
+- `beforeunload/unload` -- уход со страницы.
+
+Все эти стадии очень важны. На каждую можно повесить обработчик, чтобы совершить полезные действия:
+
+- `DOMContentLoaded` -- означает, что все DOM-элементы разметки уже созданы, можно их искать, вешать обработчики, создавать интерфейс, но при этом, возможно, ещё не догрузились какие-то картинки или стили.
+- `load` -- страница и все ресурсы загружены, используется редко, обычно нет нужды ждать этого момента.
+- `beforeunload/unload` -- можно проверить, сохранил ли посетитель изменения, уточнить, действительно ли он хочет покинуть страницу.
+
+Далее мы рассмотрим важные детали этих событий.
+
+[cut]
+
+## DOMContentLoaded
+
+Событие `DOMContentLoaded` происходит на `document` и поддерживается во всех браузерах, кроме IE8-. Про поддержку аналогичного функционала в старых IE мы поговорим в конце главы.
+
+Обработчик на него вешается только через `addEventListener`:
+
+```js
+document.addEventListener("DOMContentLoaded", ready);
+```
+
+Пример:
+
+```html run height=150
+
+
+
+```
+
+В примере выше обработчик `DOMContentLoaded` сработает сразу после загрузки документа, не дожидаясь получения картинки.
+
+Поэтому на момент вывода `alert` и сама картинка будет невидна и её размеры -- неизвестны (кроме случая, когда картинка взята из кеша браузера).
+
+В своей сути, событие `onDOMContentLoaded` -- простое, как пробка. Полностью создано DOM-дерево -- и вот событие. Но с ним связан ряд существенных тонкостей.
+
+### DOMContentLoaded и скрипты
+
+Если в документе есть теги `
+```
+
+Такое поведение прописано в стандарте. Его причина -- скрипт может захотеть получить информацию со страницы, зависящую от стилей, например, ширину элемента, и поэтому обязан дождаться загрузки `style.css`.
+
+**Побочный эффект -- так как событие `DOMContentLoaded` будет ждать выполнения скрипта, то оно подождёт и загрузки стилей, которые идут перед `
+
+
+```
+
+## window.onunload
+
+Когда человек уходит со страницы или закрывает окно, на `window` срабатывает событие `unload`. В нём можно сделать что-то, не требующее ожидания, например, закрыть вспомогательные popup-окна, но отменить сам переход нельзя.
+
+Это позволяет другое событие -- `onbeforeunload`, которое поэтому используется гораздо чаще.
+
+## window.onbeforeunload [#window.onbeforeunload]
+
+Если посетитель инициировал переход на другую страницу или нажал "закрыть окно", то обработчик `onbeforeunload` может приостановить процесс и спросить подтверждение.
+
+Для этого ему нужно вернуть строку, которую браузеры покажут посетителю, спрашивая -- нужно ли переходить.
+
+Например:
+
+```js
+window.onbeforeunload = function() {
+ return "Данные не сохранены. Точно перейти?";
+};
+```
+
+```warn header="Firefox игнорирует текст, он показывает своё сообщение"
+Firefox игнорирует текст, а всегда показывает своё сообщение. Это сделано в целях большей безопасности посетителя, чтобы его нельзя было ввести в заблуждение сообщением.
+```
+
+```online
+Кликните на кнопку в `IFRAME'е` ниже, чтобы поставить обработчик, а затем по ссылке, чтобы увидеть его в действии:
+
+[iframe src="window-onbeforeunload" border="1" height="80" link]
+```
+
+## Эмуляция DOMContentLoaded для IE8-
+
+Прежде чем что-то эмулировать, заметим, что альтернативой событию `onDOMContentLoaded` является вызов функции `init` из скрипта в самом конце `BODY`, когда основная часть DOM уже готова:
+
+```html
+
+ ...
+
+
+```
+
+Причина, по которой обычно предпочитают именно событие -- одна: удобство. Вешается обработчик и не надо ничего писать в конец `BODY`.
+
+### Мини-скрипт documentReady
+Если вы всё же хотите использовать `onDOMContentLoaded` кросс-браузерно, то нужно либо подключить какой-нибудь фреймворк -- почти все предоставляют такой функционал, либо использовать функцию из мини-библиотеки [jquery.documentReady.js](https://github.com/Couto/jquery.parts/blob/master/jquery.documentReady.js).
+
+Несмотря на то, что в названии содержится слово "jquery", эта библиотечка не требует [jQuery](http://jquery.com). Наоборот, она представляет собой единственную функцию с названием `$`, вызов которой `$(callback)` добавляет обработчик `callback` на `DOMContentLoaded` (можно вызывать много раз), либо, если документ уже загружен -- выполняет его тут же.
+
+Пример использования:
+
+```html run
+
+
+
+
+
+
Текст страницы
+```
+
+Здесь `alert` сработает до загрузки картинки, но после создания DOM, в частности, после появления текста. И так будет для всех браузеров, включая даже очень старые IE.
+
+````smart header="Как именно эмулируется `DOMContentLoaded`?"
+Технически, эмуляция `DOMContentLoaded` для старых IE осуществляется очень забавно.
+
+Основной приём -- это попытка прокрутить документ вызовом:
+
+```js
+document.documentElement.doScroll("left");
+```
+
+Метод `doScroll` работает только в IE и "методом тыка" было обнаружено, что он бросает исключение, если DOM не полностью создан.
+
+Поэтому библиотека пытается вызвать прокрутку, если не получается -- через `setTimeout(.., 1)` пытается прокрутить его ещё раз, и так до тех пор, пока действие не перестанет вызывать ошибку. На этом этапе документ считается загрузившимся.
+
+Внутри фреймов и в очень старых браузерах такой подход может ошибаться, поэтому дополнительно ставится резервный обработчик на `onload`, чтобы уж точно сработал.
+````
+
+## Итого
+
+- Самое востребованное событие из описанных -- без сомнения, `DOMContentLoaded`. Многие страницы сделаны так, что инициализуют интерфейсы именно по этому событию.
+
+ Это удобно, ведь можно в `` написать скрипт, который будет запущен в момент, когда все DOM-элементы доступны.
+
+ С другой стороны, следует иметь в виду, что событие `DOMContentLoaded` будет ждать не только, собственно, HTML-страницу, но и внешние скрипты, подключенные тегом `
+
+
+
+ Уйти на EXAMPLE.COM
+
+
+