init
This commit is contained in:
parent
06f61d8ce8
commit
f301cb744d
2271 changed files with 103162 additions and 0 deletions
|
@ -0,0 +1,42 @@
|
|||
Дело в том, что обработчик из атрибута `onclick` делается браузером как функция с заданным телом.
|
||||
|
||||
То есть, он будет таким:
|
||||
|
||||
```js
|
||||
function(event) {
|
||||
handler()
|
||||
}
|
||||
```
|
||||
|
||||
При этом возвращаемое `handler` значение никак не используется и не влияет на результат.
|
||||
|
||||
Рабочий вариант:
|
||||
|
||||
```html
|
||||
<!--+ run -->
|
||||
<script>
|
||||
function handler() {
|
||||
alert("...");
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<a href="http://w3.org" onclick="*!*return handler()*/!*">w3.org</a>
|
||||
```
|
||||
|
||||
Альтернатива -- передать и использовать объект события для вызова `event.preventDefault()` (или кросс-браузерного варианта для поддержки старых IE).
|
||||
|
||||
```html
|
||||
<!--+ run -->
|
||||
<script>
|
||||
*!*
|
||||
function handler(event) {
|
||||
alert("...");
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue=false);
|
||||
}
|
||||
*/!*
|
||||
</script>
|
||||
|
||||
<a href="http://w3.org" onclick="*!*handler(event)*/!*">w3.org</a>
|
||||
```
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Почему не работает return false?
|
||||
|
||||
[importance 3]
|
||||
|
||||
Почему в этом документе `return false` не работает?
|
||||
|
||||
```html
|
||||
<!--+ autorun run -->
|
||||
<script>
|
||||
function handler() {
|
||||
alert("...");
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<a href="http://w3.org" onclick="handler()">w3.org</a>
|
||||
```
|
||||
|
||||
По замыслу, переход на `w3.org` при клике должен отменяться. Однако, на самом деле он происходит.
|
||||
|
||||
В чём дело и как поправить, сохранив `onclick` в HTML?
|
|
@ -0,0 +1,29 @@
|
|||
Это -- классическая задача на тему делегирования.
|
||||
|
||||
В реальной жизни, мы можем перехватить событие и создать AJAX-запрос к серверу, который сохранит информацию о том, по какой ссылке ушел посетитель.
|
||||
|
||||
Мы перехватываем событие на `contents` и поднимаемся до `parentNode` пока не получим `A` или не упремся в контейнер.
|
||||
|
||||
```js
|
||||
contents.onclick = function(evt) {
|
||||
var target = evt.target;
|
||||
|
||||
function handleLink(href) {
|
||||
var isLeaving = confirm('Уйти на '+href+'?');
|
||||
if (!isLeaving) return false;
|
||||
}
|
||||
|
||||
while(target != this) {
|
||||
if (target.nodeName == 'A') {
|
||||
*!*
|
||||
return handleLink(target.getAttribute('href')); // (*)
|
||||
*/!*
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
В строке `(*)` используется атрибут, а не свойство `href`, чтобы показать в `confirm` именно то, что написано в HTML-атрибуте, так как свойство может отличаться, оно обязано содержать полный валидный адрес.
|
||||
|
||||
[edit src="solution"]Полное решение[/edit].
|
|
@ -0,0 +1 @@
|
|||
{"name":"links","plunk":"I3ev2PoF4K7oKDy9y7pd"}
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="contents">
|
||||
<p>
|
||||
Как насчет почитать <a href="http://wikipedia.org">Википедию</a>, или посетить <a href="http://w3.org"><i>W3.org</i></a> и узнать про современные стандарты?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById('contents').onclick = function(evt) {
|
||||
var evt = evt || event
|
||||
var target = evt.target || evt.srcElement
|
||||
|
||||
function handleLink(href) {
|
||||
var isLeaving = confirm('Уйти на '+href+'?')
|
||||
if (!isLeaving) return false
|
||||
}
|
||||
|
||||
while(target != this) {
|
||||
if (target.nodeName == 'A') {
|
||||
return handleLink(target.getAttribute('href'));
|
||||
}
|
||||
target = target.parentNode
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
{"name":"links","plunk":"I3ev2PoF4K7oKDy9y7pd"}
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="contents">
|
||||
<p>
|
||||
Как насчет почитать <a href="http://wikipedia.org">Википедию</a>, или посетить <a href="http://w3.org"><i>W3.org</i></a> и узнать про современные стандарты?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById('contents').onclick = function(evt) {
|
||||
var evt = evt || event
|
||||
var target = evt.target || evt.srcElement
|
||||
|
||||
function handleLink(href) {
|
||||
var isLeaving = confirm('Уйти на '+href+'?')
|
||||
if (!isLeaving) return false
|
||||
}
|
||||
|
||||
while(target != this) {
|
||||
if (target.nodeName == 'A') {
|
||||
return handleLink(target.getAttribute('href'));
|
||||
}
|
||||
target = target.parentNode
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
# Поймайте переход по ссылке
|
||||
|
||||
[importance 5]
|
||||
|
||||
Сделайте так, чтобы при клике на ссылки внутри <code><DIV id="contents"></code> пользователю выводился вопрос о том, действительно ли он хочет покинуть страницу и если он не хочет, то прерывать переход по ссылке.
|
||||
|
||||
Так это должно работать:
|
||||
|
||||
[iframe height=100 border=1 src="solution"]
|
||||
|
||||
Детали:
|
||||
<ul>
|
||||
<li>Содержимое блока `DIV` может быть загружено динамически и присвоено при помощи `innerHTML`. Так что найти все ссылки и поставить на них обработчики нельзя. Используйте делегирование.</li>
|
||||
<li>Содержимое может содержать вложенные теги, *в том числе внутри ссылок*, например, `<a href=".."><i>...</i></a>`.</li>
|
||||
</ul>
|
||||
|
||||
[edit src="task" task/]
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"name":"links-src","plunk":"xRcQ5t44wND5znpLOjlp"}
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="contents">
|
||||
<p>
|
||||
Как насчет почитать <a href="http://wikipedia.org">Википедию</a>, или посетить <a href="http://w3.org"><i>W3.org</i></a> и узнать про современные стандарты?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
Решение состоит в том, чтобы добавить обработчик на контейнер `#thumbs` и отслеживать клики на ссылках.
|
||||
|
||||
Когда происходит событие, обработчик должен изменять `src` `#largeImg` на `href` ссылки и заменять `alt` на ее `title`.
|
||||
|
||||
Код решения:
|
||||
|
||||
```js
|
||||
var largeImg = document.getElementById('largeImg');
|
||||
|
||||
document.getElementById('thumbs').onclick = function(e) {
|
||||
e = e || window.event;
|
||||
var target = e.target || e.srcElement;
|
||||
|
||||
while(target != this) {
|
||||
|
||||
if (target.nodeName == 'A') {
|
||||
showThumbnail(target.href, target.title);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = target.parentNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function showThumbnail(href, title) {
|
||||
largeImg.src = href;
|
||||
largeImg.alt = title;
|
||||
}
|
||||
```
|
||||
|
||||
**Предзагрузка картинок**
|
||||
|
||||
Для того, чтобы картинка загрузилась, достаточно создать новый элемент `IMG` и указать ему `src`, вот так:
|
||||
|
||||
```js
|
||||
var imgs = thumbs.getElementsByTagName('img');
|
||||
for(var i=0; i<imgs.length; i++) {
|
||||
var url = imgs[i].parentNode.href;
|
||||
|
||||
*!*
|
||||
var img = document.createElement('img');
|
||||
img.src = url;
|
||||
*/!*
|
||||
}
|
||||
```
|
||||
|
||||
Как только элемент создан и ему назначен `src`, браузер сам начинает скачивать файл картинки.
|
||||
|
||||
При правильных настройках сервера как-то использовать этот элемент не обязательно -- картинка уже закеширована.
|
||||
|
||||
|
||||
**Семантичная верстка**
|
||||
|
||||
Для списка картинок используется `DIV`. С точки зрения семантики более верный вариант -- список `UL/LI`.
|
||||
|
||||
[edit src="solution"]Полное решение[/edit]
|
|
@ -0,0 +1 @@
|
|||
{"name":"gallery","plunk":"xbazFxOWnIxSwcvEHrVb"}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 75%/120% Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: bold 190%/100% Arial, Helvetica, sans-serif;
|
||||
margin: 0 0 .2em;
|
||||
}
|
||||
h2 em {
|
||||
font: normal 80%/100% Arial, Helvetica, sans-serif;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
#largeImg {
|
||||
border: solid 1px #ccc;
|
||||
width: 550px;
|
||||
height: 400px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#thumbs a {
|
||||
border: solid 1px #ccc;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 3px;
|
||||
margin: 2px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#thumbs a:hover {
|
||||
border-color: #FF9900;
|
||||
}
|
||||
|
||||
#thumbs li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#thumbs {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"name":"gallery","plunk":"xbazFxOWnIxSwcvEHrVb"}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 75%/120% Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: bold 190%/100% Arial, Helvetica, sans-serif;
|
||||
margin: 0 0 .2em;
|
||||
}
|
||||
h2 em {
|
||||
font: normal 80%/100% Arial, Helvetica, sans-serif;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
#largeImg {
|
||||
border: solid 1px #ccc;
|
||||
width: 550px;
|
||||
height: 400px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#thumbs a {
|
||||
border: solid 1px #ccc;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 3px;
|
||||
margin: 2px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#thumbs a:hover {
|
||||
border-color: #FF9900;
|
||||
}
|
||||
|
||||
#thumbs li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#thumbs {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Галерея</title>
|
||||
<link rel="stylesheet" type="text/css" href="gallery.css">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<p><img id="largeImg" src="http://js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
|
||||
|
||||
<ul id="thumbs">
|
||||
<!-- При наведении на изображение показывается встроенная подсказка браузера (title) -->
|
||||
<li><a href="http://js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="http://js.cx/gallery/img2-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="http://js.cx/gallery/img3-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="http://js.cx/gallery/img4-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="http://js.cx/gallery/img5-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="http://js.cx/gallery/img6-thumb.jpg"></a></li>
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
var largeImg = document.getElementById('largeImg');
|
||||
|
||||
var thumbs = document.getElementById('thumbs');
|
||||
|
||||
thumbs.onclick = function(e) {
|
||||
e = e || window.event;
|
||||
var target = e.target || e.srcElement;
|
||||
|
||||
while(target != this) {
|
||||
|
||||
if (target.nodeName == 'A') {
|
||||
showThumbnail(target.href, target.title);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = target.parentNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function showThumbnail(href, title) {
|
||||
largeImg.src = href;
|
||||
largeImg.alt = title;
|
||||
}
|
||||
|
||||
|
||||
/* предзагрузка */
|
||||
var imgs = thumbs.getElementsByTagName('img');
|
||||
for(var i=0; i<imgs.length; i++) {
|
||||
var url = imgs[i].parentNode.href;
|
||||
var img = document.createElement('img');
|
||||
img.src = url;
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Галерея</title>
|
||||
<link rel="stylesheet" type="text/css" href="gallery.css">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<p><img id="largeImg" src="http://js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
|
||||
|
||||
<ul id="thumbs">
|
||||
<!-- При наведении на изображение показывается встроенная подсказка браузера (title) -->
|
||||
<li><a href="http://js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="http://js.cx/gallery/img2-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="http://js.cx/gallery/img3-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="http://js.cx/gallery/img4-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="http://js.cx/gallery/img5-thumb.jpg"></a></li>
|
||||
<li><a href="http://js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="http://js.cx/gallery/img6-thumb.jpg"></a></li>
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
var largeImg = document.getElementById('largeImg');
|
||||
|
||||
var thumbs = document.getElementById('thumbs');
|
||||
|
||||
thumbs.onclick = function(e) {
|
||||
e = e || window.event;
|
||||
var target = e.target || e.srcElement;
|
||||
|
||||
while(target != this) {
|
||||
|
||||
if (target.nodeName == 'A') {
|
||||
showThumbnail(target.href, target.title);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = target.parentNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function showThumbnail(href, title) {
|
||||
largeImg.src = href;
|
||||
largeImg.alt = title;
|
||||
}
|
||||
|
||||
|
||||
/* предзагрузка */
|
||||
var imgs = thumbs.getElementsByTagName('img');
|
||||
for(var i=0; i<imgs.length; i++) {
|
||||
var url = imgs[i].parentNode.href;
|
||||
var img = document.createElement('img');
|
||||
img.src = url;
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
# Галерея изображений
|
||||
|
||||
[importance 5]
|
||||
|
||||
Создайте галерею изображений, в которой основное изображение изменяется при клике на уменьшенный вариант.
|
||||
|
||||
Результат должен выглядеть так:
|
||||
|
||||
[iframe src="solution" height=600]
|
||||
|
||||
Для обработки событий используйте делегирование, т.е. не более одного обработчика.
|
||||
|
||||
[edit src="task" task/]
|
||||
|
||||
P.S. Обратите внимание -- клик может быть как на маленьком изображении `IMG`, так и на `A` вне него. При этом `event.target` будет, соответственно, либо `IMG`, либо `A`.
|
||||
|
||||
Дополнительно:
|
||||
|
||||
<ul>
|
||||
<li>Если получится -- сделайте предзагрузку больших изображений, чтобы при клике они появлялись сразу.</li>
|
||||
<li>Всё ли в порядке с семантической вёрсткой в HTML исходного документа? Если нет -- поправьте, чтобы было, как нужно.</li>
|
||||
</ul>
|
|
@ -0,0 +1 @@
|
|||
{"name":"gallery-src","plunk":"kzfUa6aitkLvyQYfgAsv"}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 75%/120% Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: bold 190%/100% Arial, Helvetica, sans-serif;
|
||||
margin: 0 0 .2em;
|
||||
}
|
||||
h2 em {
|
||||
font: normal 80%/100% Arial, Helvetica, sans-serif;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
#largeImg {
|
||||
border: solid 1px #ccc;
|
||||
width: 550px;
|
||||
height: 400px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#thumbs a {
|
||||
border: solid 1px #ccc;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 3px;
|
||||
margin: 2px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#thumbs a:hover {
|
||||
border-color: #FF9900;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Галерея</title>
|
||||
<link rel="stylesheet" type="text/css" href="gallery.css">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<p><img id="largeImg" src="http://js.cx/gallery/img1-lg.jpg" alt="Large image"></p>
|
||||
|
||||
<div id="thumbs">
|
||||
<!-- При наведении на изображение показывается встроенная подсказка браузера (title) -->
|
||||
<a href="http://js.cx/gallery/img2-lg.jpg" title="Image 2"><img src="http://js.cx/gallery/img2-thumb.jpg"></a>
|
||||
<a href="http://js.cx/gallery/img3-lg.jpg" title="Image 3"><img src="http://js.cx/gallery/img3-thumb.jpg"></a>
|
||||
<a href="http://js.cx/gallery/img4-lg.jpg" title="Image 4"><img src="http://js.cx/gallery/img4-thumb.jpg"></a>
|
||||
<a href="http://js.cx/gallery/img5-lg.jpg" title="Image 5"><img src="http://js.cx/gallery/img5-thumb.jpg"></a>
|
||||
<a href="http://js.cx/gallery/img6-lg.jpg" title="Image 6"><img src="http://js.cx/gallery/img6-thumb.jpg"></a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,152 @@
|
|||
# Действия браузера по умолчанию
|
||||
|
||||
Многие события влекут за собой действие браузера.
|
||||
|
||||
Например:
|
||||
<ul>
|
||||
<li>Клик по ссылке инициирует переход на новый URL</li>
|
||||
<li>Нажатие на кнопку "отправить" в форме -- посылку ее на сервер</li>
|
||||
<li>Двойной клик на тексте -- инициирует его выделение.</li>
|
||||
</ul>
|
||||
|
||||
**Зачастую, мы полностью обрабатываем событие в JavaScript, и такое действие браузера нам не нужно.**
|
||||
|
||||
К счастью, его можно отменить.
|
||||
|
||||
[cut]
|
||||
## Отмена действия браузера
|
||||
|
||||
Есть два способа отменить действие браузера:
|
||||
<ul>
|
||||
<li>**Основной способ -- это воспользоваться объектом события. Для отмены действия браузера существует стандартный метод `event.preventDefault()`.**</li>
|
||||
<li>Если же обработчик назначен через `on...` (не через `addEventListener/attachEvent`), то можно просто вернуть `false` из обработчика.</li>
|
||||
</ul>
|
||||
|
||||
В следующем примере при клике по ссылке переход не произойдет:
|
||||
|
||||
```html
|
||||
<!--+ autorun -->
|
||||
<a href="/" onclick="return false">Нажми здесь</a>
|
||||
или
|
||||
<a href="/" onclick="event.preventDefault()">здесь</a>
|
||||
```
|
||||
|
||||
[warn header="Возвращать `true` не нужно"]
|
||||
Вообще говоря, значение, которое возвращает обработчик, игнорируется.
|
||||
|
||||
Единственное исключение -- это `return false` из обработчика, назначенного через `onсобытие`.
|
||||
|
||||
Иногда в коде начинающих разработчиков можно увидеть `return` других значений. Но они не нужны и никак не обрабатываются.
|
||||
[/warn]
|
||||
|
||||
### Пример: меню
|
||||
|
||||
Рассмотрим задачу, когда нужно создать меню для сайта, например такое:
|
||||
|
||||
```html
|
||||
<ul id="menu" class="menu">
|
||||
<li><a href="/php">PHP</a></li>
|
||||
<li><a href="/html">HTML</a></li>
|
||||
<li><a href="/javascript">JavaScript</a></li>
|
||||
<li><a href="/flash">Flash</a></li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
Данный пример при помощи CSS может выводиться так:
|
||||
|
||||
[iframe height=70 src="menu" link edit]
|
||||
|
||||
**Все элементы меню являются ссылками, то есть тегами `<a>`.**
|
||||
|
||||
Это потому, что некоторые посетители очень любят сочетание "правый клик - открыть в новом окне". Да, мы можем использовать и `<button>` и `<span>`, но если правый клик не работает -- это их огорчает. Кроме того, если на сайт зайдёт поисковик, то по ссылке из `<a href="...">` он перейдёт, а выполнить сложный JavaScript и получить результат -- вряд ли захочет.
|
||||
|
||||
**Значение `<a href="...">` -- это "запасной вариант", для правого клика и для поисковиков, а обычно клик будет обрабатываться JavaScript.**
|
||||
|
||||
Например, вот так:
|
||||
|
||||
```js
|
||||
menu.onclick = function(event) {
|
||||
if (event.target.nodeName != 'A') return;
|
||||
|
||||
var href = event.target.getAttribute('href');
|
||||
alert(href); // может быть подгрузка с сервера, генерация интерфейса и т.п.
|
||||
|
||||
*!*
|
||||
return false; // отменить переход по url
|
||||
*/!*
|
||||
};
|
||||
```
|
||||
|
||||
В конце `return false`, иначе браузер перейдёт по адресу из `href`.
|
||||
|
||||
Так как мы применили делегирование, то меню может увеличиваться, можно добавить вложенные списки `ul/li`, стилизовать их при помощи CSS -- меню продолжит работать.
|
||||
|
||||
## Другие действия браузера
|
||||
|
||||
Действий браузера по умолчанию достаточно много.
|
||||
|
||||
Вот некоторые примеры событий, которые вызывают действие браузера:
|
||||
<ul>
|
||||
<li>`mousedown` -- нажатие кнопкой мыши в то время как курсор находится на тексте начинает его выделение.</li>
|
||||
<li>`click` на `<input type="checkbox">` -- ставит или убирает галочку.</li>
|
||||
<li>`submit` -- при нажатии на `<input type="submit">` в форме данные отправляются на сервер.</li>
|
||||
<li>`wheel` -- движение колёсика мыши инициирует прокрутку.</li>
|
||||
<li>`keydown` -- при нажатии клавиши в поле ввода появляется символ.</li>
|
||||
<li>`contextmenu` -- при правом клике показывается контекстное меню браузера.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
Все эти действия можно отменить, если мы хотим обработать событие исключительно при помощи JavaScript.
|
||||
|
||||
[warn header="События могут быть связаны между собой"]
|
||||
Некоторые события естественным образом вытекают друг из друга.
|
||||
|
||||
Например, нажатие мышкой `mousedown` на поле ввода `<input>` приводит к фокусировке внутрь него. Если отменить действие `mousedown`, то и фокуса не будет.
|
||||
|
||||
Попробуйте нажать мышкой на первый `<input>` -- произойдёт событие `onfocus`. Это обычная ситуация.
|
||||
|
||||
Но если нажать на второй, то фокусировки не произойдёт.
|
||||
|
||||
```html
|
||||
<!--+ run autorun -->
|
||||
<input value="Фокус работает" onfocus="this.value=''">
|
||||
<input *!*onmousedown="return false"*/!* onfocus="this.value=''" value="Кликни меня">
|
||||
```
|
||||
|
||||
...С другой стороны, во второй `<input>` можно перейти с первого нажатием клавиши [key Tab], и тогда фокусировка сработает. То есть, дело здесь именно в `onmousedown="return false"`.
|
||||
[/warn]
|
||||
|
||||
## Особенности IE8-
|
||||
|
||||
**В IE8- для отмены действия по умолчанию нужно назначить свойство `event.returnValue = false`.**
|
||||
|
||||
Кроссбраузерный код для отмены действия по умолчанию:
|
||||
|
||||
```js
|
||||
element.onclick = function(event) {
|
||||
event = event || window.event;
|
||||
|
||||
if (event.preventDefault) { // если метод существует
|
||||
event.preventDefault(); // то вызвать его
|
||||
} else { // иначе вариант IE<9:
|
||||
event.returnValue = false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Можно записать в одну строку:
|
||||
|
||||
```js
|
||||
...
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue=false);
|
||||
...
|
||||
```
|
||||
|
||||
## Итого
|
||||
|
||||
<ul>
|
||||
<li>Браузер имеет встроенные действия при ряде событий -- переход по ссылке, отправка формы и т.п. Как правило, их можно отменить.</li>
|
||||
<li>Есть два способа отменить действие по умолчанию: первый -- использовать `event.preventDefault()` (IE<9: `event.returnValue=false`), второй -- `return false` из обработчика. Второй способ работает только если обработчик назначен через `onсобытие`.</li>
|
||||
</ul>
|
||||
|
||||
|
1
02-ui/02-events-and-interfaces/07-default-browser-action/menu/.plnkr
Executable file
1
02-ui/02-events-and-interfaces/07-default-browser-action/menu/.plnkr
Executable file
|
@ -0,0 +1 @@
|
|||
{"name":"menu","plunk":"TV5XwdELtOWY1cdMYEc5"}
|
19
02-ui/02-events-and-interfaces/07-default-browser-action/menu/index.html
Executable file
19
02-ui/02-events-and-interfaces/07-default-browser-action/menu/index.html
Executable file
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="menu.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul id="menu" class="menu">
|
||||
<li><a href="/php">PHP</a></li>
|
||||
<li><a href="/html">HTML</a></li>
|
||||
<li><a href="/javascript">JavaScript</a></li>
|
||||
<li><a href="/flash">Flash</a></li>
|
||||
</ul>
|
||||
|
||||
<script src="menu.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
25
02-ui/02-events-and-interfaces/07-default-browser-action/menu/menu.css
Executable file
25
02-ui/02-events-and-interfaces/07-default-browser-action/menu/menu.css
Executable file
|
@ -0,0 +1,25 @@
|
|||
.menu li {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.menu > li a {
|
||||
display: inline-block;
|
||||
margin: 0 2px;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
font: 14px/100% Arial, Helvetica, sans-serif;
|
||||
padding: .5em 2em .55em;
|
||||
text-shadow: 0 1px 1px rgba(0,0,0,.3);
|
||||
border-radius: .5em;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.2);
|
||||
color: #d9eef7;
|
||||
border: solid 1px #0076a3;
|
||||
background: #0095cd;
|
||||
}
|
||||
|
||||
.menu > li:hover a {
|
||||
text-decoration: none;
|
||||
background: #007ead;
|
||||
}
|
8
02-ui/02-events-and-interfaces/07-default-browser-action/menu/menu.js
Executable file
8
02-ui/02-events-and-interfaces/07-default-browser-action/menu/menu.js
Executable file
|
@ -0,0 +1,8 @@
|
|||
menu.onclick = function(event) {
|
||||
if (event.target.nodeName != 'A') return;
|
||||
|
||||
var href = event.target.getAttribute('href');
|
||||
alert(href);
|
||||
|
||||
return false; // prevent url change
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue