Skip to content

Commit 497c9fd

Browse files
committed
up
1 parent cf9969f commit 497c9fd

File tree

14 files changed

+223
-551
lines changed

14 files changed

+223
-551
lines changed

2-ui/2-events/7-default-browser-action/1-why-return-false-fails/solution.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
Дело в том, что обработчик из атрибута `onclick` делается браузером как функция с заданным телом.
1+
When the browser reads the `on*` attribute like `onclick`, it creates the handler from its content.
22

3-
То есть, в данном случае он будет таким:
3+
For `onclick="handler()"` the function will be:
44

55
```js
66
function(event) {
7-
handler() // тело взято из атрибута onclick
7+
handler() // the content of onclick
88
}
99
```
1010

11-
При этом возвращаемое `handler` значение никак не используется и не влияет на результат.
11+
Now we can see that the value returned by `handler()` is not used and does not affect the result.
1212

13-
Рабочий вариант:
13+
The fix is simple:
1414

1515
```html run
1616
<script>
@@ -23,7 +23,7 @@ function(event) {
2323
<a href="http://w3.org" onclick="*!*return handler()*/!*">w3.org</a>
2424
```
2525

26-
Также можно использовать объект события для вызова `event.preventDefault()`, например:
26+
Also we can use `event.preventDefault()`, like this:
2727

2828
```html run
2929
<script>
@@ -37,4 +37,3 @@ function(event) {
3737

3838
<a href="http://w3.org" onclick="*!*handler(event)*/!*">w3.org</a>
3939
```
40-

2-ui/2-events/7-default-browser-action/1-why-return-false-fails/task.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ importance: 3
22

33
---
44

5-
# Почему не работает return false?
5+
# Why "return false" doesn't work?
66

7-
Почему в этом документе `return false` не работает?
7+
Why in the code below `return false` doesn't work at all?
88

99
```html autorun run
1010
<script>
@@ -14,9 +14,9 @@ importance: 3
1414
}
1515
</script>
1616

17-
<a href="http://w3.org" onclick="handler()">w3.org</a>
17+
<a href="http://w3.org" onclick="handler()">the browser will go to w3.org</a>
1818
```
1919

20-
По замыслу, переход на `w3.org` при клике должен отменяться. Однако, на самом деле он происходит.
20+
The browser follows the URL on click, but we don't want it.
2121

22-
В чём дело и как поправить?
22+
How to fix?
Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,5 @@
1-
Это -- классическая задача на тему делегирования.
1+
That's a great use of the event delegation pattern.
22

3-
В реальной жизни, мы можем перехватить событие и создать AJAX-запрос к серверу, который сохранит информацию о том, по какой ссылке ушел посетитель.
4-
5-
Мы перехватываем событие на `contents` и поднимаемся до `parentNode` пока не получим `A` или не упремся в контейнер.
6-
7-
```js
8-
contents.onclick = function(evt) {
9-
var target = evt.target;
10-
11-
function handleLink(href) {
12-
var isLeaving = confirm('Уйти на ' + href + '?');
13-
if (!isLeaving) return false;
14-
}
15-
16-
while (target != this) {
17-
if (target.nodeName == 'A') {
18-
*!*
19-
return handleLink(target.getAttribute('href')); // (*)
20-
*/!*
21-
}
22-
target = target.parentNode;
23-
}
24-
};
25-
```
26-
27-
В строке `(*)` используется атрибут, а не свойство `href`, чтобы показать в `confirm` именно то, что написано в HTML-атрибуте, так как свойство может отличаться, оно обязано содержать полный валидный адрес.
3+
In real life instead of asking we can send a "logging" request to the server that saves the information about where the visitor left. Or we can load the content and show it right in the page (if allowable).
284

5+
All we need is to catch the `contents.onclick` and use `confirm` to ask the user. A good idea would be to use `link.getAttribute('href')` instead of `link.href` for the URL. See the solution for details.

2-ui/2-events/7-default-browser-action/2-catch-link-navigation/solution.view/index.html

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,25 @@
1616
<fieldset id="contents">
1717
<legend>#contents</legend>
1818
<p>
19-
Как насчет почитать <a href="http://wikipedia.org">Википедию</a>, или посетить <a href="http://w3.org"><i>W3.org</i></a> и узнать про современные стандарты?
19+
How about to read <a href="http://wikipedia.org">Wikipedia</a> or visit <a href="http://w3.org"><i>W3.org</i></a> and learn about modern standards?
2020
</p>
2121
</fieldset>
2222

2323
<script>
24-
document.getElementById('contents').onclick = function(event) {
24+
contents.onclick = function(event) {
2525

2626
function handleLink(href) {
27-
var isLeaving = confirm('Уйти на ' + href + '?');
27+
let isLeaving = confirm(`Leave for ${href}?`);
2828
if (!isLeaving) return false;
2929
}
3030

31-
var target = event.target;
31+
let target = event.target.closest('a');
3232

33-
while (target != this) {
34-
if (target.nodeName == 'A') {
35-
return handleLink(target.getAttribute('href'));
36-
}
37-
target = target.parentNode;
33+
if (target && contents.contains(target)) {
34+
return handleLink(target.getAttribute('href'));
3835
}
39-
}
36+
};
4037
</script>
38+
4139
</body>
42-
43-
</html>
40+
</html>

2-ui/2-events/7-default-browser-action/2-catch-link-navigation/source.view/index.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
<fieldset id="contents">
1717
<legend>#contents</legend>
1818
<p>
19-
Как насчет почитать <a href="http://wikipedia.org">Википедию</a>, или посетить <a href="http://w3.org"><i>W3.org</i></a> и узнать про современные стандарты?
19+
How about to read <a href="http://wikipedia.org">Wikipedia</a> or visit <a href="http://w3.org"><i>W3.org</i></a> and learn about modern standards?
2020
</p>
2121
</fieldset>
2222

2323
</body>
24-
25-
</html>
24+
</html>

2-ui/2-events/7-default-browser-action/2-catch-link-navigation/task.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@ importance: 5
22

33
---
44

5-
# Поймайте переход по ссылке
5+
# Catch links in the element
66

7-
Сделайте так, чтобы при клике на ссылки внутри элемента `#contents` пользователю выводился вопрос о том, действительно ли он хочет покинуть страницу и если он не хочет, то прерывать переход по ссылке.
7+
Make all links inside the element with `id="contents"` ask the user if he really wants to leave. And if he doesn't then don't follow.
88

9-
Так это должно работать:
9+
Like this:
1010

1111
[iframe height=100 border=1 src="solution"]
1212

13-
Детали:
14-
15-
- Содержимое `#contents` может быть загружено динамически и присвоено при помощи `innerHTML`. Так что найти все ссылки и поставить на них обработчики нельзя. Используйте делегирование.
16-
- Содержимое может содержать вложенные теги, *в том числе внутри ссылок*, например, `<a href=".."><i>...</i></a>`.
13+
Details:
1714

15+
- HTML inside the element may be loaded or regenerated dynamically at any time, so we can't find all links and put handlers on them. Use the event delegation.
16+
- The content may have nested tags. Inside links too, like `<a href=".."><i>...</i></a>`.
Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1 @@
1-
Решение состоит в том, чтобы добавить обработчик на контейнер `#thumbs` и отслеживать клики на ссылках.
2-
3-
Когда происходит событие, обработчик должен изменять `src` `#largeImg` на `href` ссылки и заменять `alt` на ее `title`.
4-
5-
Код решения:
6-
7-
```js
8-
var largeImg = document.getElementById('largeImg');
9-
10-
document.getElementById('thumbs').onclick = function(e) {
11-
var target = e.target;
12-
13-
while (target != this) {
14-
15-
if (target.nodeName == 'A') {
16-
showThumbnail(target.href, target.title);
17-
return false;
18-
}
19-
20-
target = target.parentNode;
21-
}
22-
23-
}
24-
25-
function showThumbnail(href, title) {
26-
largeImg.src = href;
27-
largeImg.alt = title;
28-
}
29-
```
30-
31-
**Предзагрузка картинок**
32-
33-
Для того, чтобы картинка загрузилась, достаточно создать новый элемент `IMG` и указать ему `src`, вот так:
34-
35-
```js
36-
var imgs = thumbs.getElementsByTagName('img');
37-
for (var i = 0; i < imgs.length; i++) {
38-
var url = imgs[i].parentNode.href;
39-
40-
*!*
41-
var img = document.createElement('img');
42-
img.src = url;
43-
*/!*
44-
}
45-
```
46-
47-
Как только элемент создан и ему назначен `src`, браузер сам начинает скачивать файл картинки.
48-
49-
При правильных настройках сервера как-то использовать этот элемент не обязательно -- картинка уже закеширована.
50-
51-
**Семантичная верстка**
52-
53-
Для списка картинок используется `DIV`. С точки зрения семантики более верный вариант -- список `UL/LI`.
54-
1+
The solution is to assign the handler to the container and track clicks. If a click is on the `<a>` link, then change `src` of `#largeImg` to the `href` of the thumbnail.

2-ui/2-events/7-default-browser-action/3-image-gallery/solution.view/index.html

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,48 @@
22
<html>
33

44
<head>
5-
<title>Галерея</title>
5+
<title>Gallery</title>
66
<link rel="stylesheet" href="gallery.css">
77
<meta charset="utf-8">
88
</head>
99

1010
<body>
1111

12-
<p><img id="largeImg" src="https://js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
12+
<p><img id="largeImg" src="https://en.js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
1313

1414
<ul id="thumbs">
15-
<!-- При наведении на изображение показывается встроенная подсказка браузера (title) -->
15+
<!-- the browser shows a small built-in tooltip on hover with the text from "title" attribute -->
1616
<li>
17-
<a href="https://js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="https://js.cx/gallery/img2-thumb.jpg"></a>
17+
<a href="https://en.js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="https://en.js.cx/gallery/img2-thumb.jpg"></a>
1818
</li>
1919
<li>
20-
<a href="https://js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="https://js.cx/gallery/img3-thumb.jpg"></a>
20+
<a href="https://en.js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="https://en.js.cx/gallery/img3-thumb.jpg"></a>
2121
</li>
2222
<li>
23-
<a href="https://js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="https://js.cx/gallery/img4-thumb.jpg"></a>
23+
<a href="https://en.js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="https://en.js.cx/gallery/img4-thumb.jpg"></a>
2424
</li>
2525
<li>
26-
<a href="https://js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="https://js.cx/gallery/img5-thumb.jpg"></a>
26+
<a href="https://en.js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="https://en.js.cx/gallery/img5-thumb.jpg"></a>
2727
</li>
2828
<li>
29-
<a href="https://js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="https://js.cx/gallery/img6-thumb.jpg"></a>
29+
<a href="https://en.js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="https://en.js.cx/gallery/img6-thumb.jpg"></a>
3030
</li>
3131
</ul>
3232

3333
<script>
34-
var largeImg = document.getElementById('largeImg');
35-
36-
var thumbs = document.getElementById('thumbs');
37-
38-
thumbs.onclick = function(e) {
39-
var target = e.target;
40-
41-
while (target != this) {
42-
43-
if (target.nodeName == 'A') {
44-
showThumbnail(target.href, target.title);
45-
return false;
46-
}
47-
48-
target = target.parentNode;
49-
}
34+
thumbs.onclick = function(event) {
35+
let thumbnail = event.target.closest('a');
5036

37+
if (!thumbnail) return;
38+
showThumbnail(target.href, target.title);
39+
event.preventDefault();
5140
}
5241

5342
function showThumbnail(href, title) {
5443
largeImg.src = href;
5544
largeImg.alt = title;
5645
}
57-
58-
59-
/* предзагрузка */
60-
var imgs = thumbs.getElementsByTagName('img');
61-
for (var i = 0; i < imgs.length; i++) {
62-
var url = imgs[i].parentNode.href;
63-
var img = document.createElement('img');
64-
img.src = url;
65-
}
6646
</script>
6747

6848
</body>
69-
70-
</html>
49+
</html>

2-ui/2-events/7-default-browser-action/3-image-gallery/source.view/index.html

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,33 @@
22
<html>
33

44
<head>
5-
<title>Галерея</title>
5+
<title>Gallery</title>
66
<link rel="stylesheet" href="gallery.css">
77
<meta charset="utf-8">
88
</head>
99

1010
<body>
1111

12-
<p><img id="largeImg" src="https://js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
12+
<p><img id="largeImg" src="https://en.js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
1313

14-
<div id="thumbs">
15-
<!-- При наведении на изображение показывается встроенная подсказка браузера (title) -->
16-
<a href="https://js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="https://js.cx/gallery/img2-thumb.jpg"></a>
17-
<a href="https://js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="https://js.cx/gallery/img3-thumb.jpg"></a>
18-
<a href="https://js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="https://js.cx/gallery/img4-thumb.jpg"></a>
19-
<a href="https://js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="https://js.cx/gallery/img5-thumb.jpg"></a>
20-
<a href="https://js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="https://js.cx/gallery/img6-thumb.jpg"></a>
21-
</div>
14+
<ul id="thumbs">
15+
<!-- the browser shows a small built-in tooltip on hover with the text from "title" attribute -->
16+
<li>
17+
<a href="https://en.js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="https://en.js.cx/gallery/img2-thumb.jpg"></a>
18+
</li>
19+
<li>
20+
<a href="https://en.js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="https://en.js.cx/gallery/img3-thumb.jpg"></a>
21+
</li>
22+
<li>
23+
<a href="https://en.js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="https://en.js.cx/gallery/img4-thumb.jpg"></a>
24+
</li>
25+
<li>
26+
<a href="https://en.js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="https://en.js.cx/gallery/img5-thumb.jpg"></a>
27+
</li>
28+
<li>
29+
<a href="https://en.js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="https://en.js.cx/gallery/img6-thumb.jpg"></a>
30+
</li>
31+
</ul>
2232

2333
</body>
24-
25-
</html>
34+
</html>

2-ui/2-events/7-default-browser-action/3-image-gallery/task.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,12 @@ importance: 5
22

33
---
44

5-
# Галерея изображений
5+
# Image gallery
66

7-
Создайте галерею изображений, в которой основное изображение изменяется при клике на уменьшенный вариант.
7+
Create an image gallery where the main image changes by the click on a thumbnail.
88

9-
Результат должен выглядеть так:
9+
Like this:
1010

1111
[iframe src="solution" height=600]
1212

13-
Для обработки событий используйте делегирование, т.е. не более одного обработчика.
14-
15-
P.S. Обратите внимание -- клик может быть как на маленьком изображении `IMG`, так и на `A` вне него. При этом `event.target` будет, соответственно, либо `IMG`, либо `A`.
16-
17-
Дополнительно:
18-
19-
- Если получится -- сделайте предзагрузку больших изображений, чтобы при клике они появлялись сразу.
20-
- Всё ли в порядке с семантической вёрсткой в HTML исходного документа? Если нет -- поправьте, чтобы было, как нужно.
13+
P.S. Use event delegation.

0 commit comments

Comments
 (0)