Window

Движение мыши

Каждый раз, когда перемещается курсов мыши, срабатывает событие «mousemove» из набора JavaScript mouse events. Оно может быть использовано для отслеживания положения мыши. Это применяется при реализации возможности перетаскивания элементов мышью.

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

<p>Потяните за край панели, чтобы изменить ее ширину:</p>
<div style="background: orange; width: 60px; height: 20px">
</div>
<script>
  var lastX; // Отслеживает последнюю позицию X мыши
  var rect = document.querySelector("div");
  rect.addEventListener("mousedown", function(event) {
    if (event.which == 1) {
      lastX = event.pageX;
      addEventListener("mousemove", moved);
      event.preventDefault(); // Предотвращает выделение
    }
  });

  function buttonPressed(event) {
    if (event.buttons == null)
      return event.which != 0;
    else
      return event.buttons != 0;
  }
  function moved(event) {
    if (!buttonPressed(event)) {
      removeEventListener("mousemove", moved);
    } else {
      var dist = event.pageX - lastX;
      var newWidth = Math.max(10, rect.offsetWidth + dist);
      rect.style.width = newWidth + "px";
      lastX = event.pageX;
    }
  }
</script>

Обратите внимание, что обработчик «mousemove» зарегистрирован для всего окна. Даже если во время изменения размеров мышь выходит за пределы панели, мы все равно обновляем ширину панели и прекращаем JavaScript touch events, когда клавиша мыши была отпущена

Мы должны прекратить изменение размера панели, когда пользователь отпускает клавишу мыши. К сожалению, не все браузеры устанавливают для событий «mousemove» свойство which. Существует стандартное свойство buttons, которое предоставляет аналогичную информацию, но оно также поддерживается не во всех браузерах. К счастью, все основные браузеры поддерживают что-то одно: либо buttons, либо which. Функция buttonPressed в приведенном выше примере сначала пытается использовать свойство buttons, и, если оно не доступно, переходит к which.

Когда курсор мыши наводится или покидает узел, запускаются события «mouseover» или «mouseout«. Они могут использоваться для создания эффектов при наведении курсора мыши, вывода какой-нибудь подписи или изменения стиля элемента.

Чтобы создать такой эффект, недостаточно просто начать его отображение при возникновении события «mouseover» и завершить после события «mouseout«. Когда мышь перемещается от узла к одному из его дочерних элементов, для родительского узла происходит событие «mouseout«. Хотя указатель мыши не покинул диапазон распространения узла.

Что еще хуже, эти JavaScript event распространяются так же, как и другие события. Когда мышь покидает один из дочерних узлов, для которого зарегистрирован обработчик, возникнет событие «mouseout«.

Чтобы обойти эту проблему, можно использовать свойство объекта события relatedTarget. В случае возникновения события «mouseover» оно указывает, на какой элемент был наведен курсор мыши до этого. А в случае возникновения «mouseout» — к какому элементу перемещается указатель. Мы будем изменять эффект наведения мыши только, когда relatedTarget находится вне нашего целевого узла.

В этом случае мы изменяем поведение, потому что курсор мыши был наведен на узел из-за его пределов (или наоборот):

<p>Наведите курсор мыши на этот <strong>абзац</strong>.</p>
<script>
  var para = document.querySelector("p");
  function isInside(node, target) {
    for (; node != null; node = node.parentNode)
      if (node == target) return true;
  }
  para.addEventListener("mouseover", function(event) {
    if (!isInside(event.relatedTarget, para))
      para.style.color = "red";
  });
  para.addEventListener("mouseout", function(event) {
    if (!isInside(event.relatedTarget, para))
      para.style.color = "";
  });
</script>

Функция isInside отслеживает родительские связи заданного узла или пока не будет достигнута верхняя часть документа (когда node равен нулю). Либо не будет найден родительский элемент, который нам нужен.

Эффект наведения гораздо проще создать с помощью псевдоселектора CSS :hover, как показано в следующем примере. Но когда эффект наведения предполагает что-то более сложное, чем просто изменение стиля целевого узла, тогда нужно использовать прием с использованием событий «mouseover» и «mouseout» (JavaScript mouse events):

<style>
  p:hover { color: red }
</style>
<p>Наведите курсор мыши на этот <strong>абзац</strong>.</p>

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

More Examples

Example

You can also refer to an external «named» function.

This example demonstrates how to execute a function when a user clicks on a <button> element:

document.getElementById(«myBtn»).addEventListener(«click», myFunction);function myFunction() {  document.getElementById(«demo»).innerHTML = «Hello World»;
}

Example

You can add many events to the same element, without overwriting existing
events.

This example demonstrates how to add two click events on the same <button> element:

document.getElementById(«myBtn»).addEventListener(«click», myFunction);document.getElementById(«myBtn»).addEventListener(«click», someOtherFunction);

Example

You can add events of different types to the same element.

This example demonstrates how to add many events on the same <button> element:

document.getElementById(«myBtn»).addEventListener(«mouseover», myFunction);document.getElementById(«myBtn»).addEventListener(«click», someOtherFunction);
document.getElementById(«myBtn»).addEventListener(«mouseout», someOtherFunction);

Example

When passing parameter values, use an «anonymous function» that calls the
specified function with the parameters:

document.getElementById(«myBtn»).addEventListener(«click», function() {  myFunction(p1, p2);});

Example

Change the background color of a <button> element:

document.getElementById(«myBtn»).addEventListener(«click», function() {  this.style.backgroundColor = «red»;});

Example

Using the optional useCapture parameter to demonstrate the
difference between bubbling and capturing:

document.getElementById(«myDiv»).addEventListener(«click», myFunction, true);

Example

Using the removeEventListener() method to remove an event handler that has
been attached with the addEventListener() method:

// Attach an event handler to <div>document.getElementById(«myDIV»).addEventListener(«mousemove», myFunction);// Remove the event handler from <div>document.getElementById(«myDIV»).removeEventListener(«mousemove», myFunction);

Example

For browsers that don’t support the addEventListener() method, you can use
the attachEvent() method.

This example demonstrates a cross-browser solution:

var x = document.getElementById(«myBtn»);if (x.addEventListener) {                    // For all major browsers, except IE 8 and earlier
  x.addEventListener(«click», myFunction);} else if (x.attachEvent) {                  // For IE 8 and earlier versions
  x.attachEvent(«onclick», myFunction);}

addEventListener() Code Example

Simple example demonstrating addEventListener()

This is a simple example I made which shows you in action.

When a user clicks the button, a message is displayed. Another button click hides the message. Here’s the relevant JavaScript:

Going by the syntax shown previously for :

  • target: HTML element with
  • function: anonymous (arrow) function that sets up code necessary to reveal/hide the message
  • useCapture: left to default value of

My function is able to reveal/hide the message by adding/removing a CSS class called «reveal» which changes the message element’s visibility.

Of course in your code, feel free to customize this function. You may also replace the anonymous function with a named function of your own.

event.defaultPrevented

Свойство установлено в , если действие по умолчанию было предотвращено, и , если нет.

Рассмотрим практическое применение этого свойства для улучшения архитектуры.

Помните, в главе Всплытие и погружение мы говорили о и упоминали, что останавливать «всплытие» – плохо?

Иногда вместо этого мы можем использовать , чтобы просигналить другим обработчикам, что событие обработано.

Давайте посмотрим практический пример.

По умолчанию браузер при событии (клик правой кнопкой мыши) показывает контекстное меню со стандартными опциями. Мы можем отменить событие по умолчанию и показать своё меню, как здесь:

Теперь в дополнение к этому контекстному меню реализуем контекстное меню для всего документа.

При правом клике должно показываться ближайшее контекстное меню.

Проблема заключается в том, что когда мы кликаем по элементу , то мы получаем два меню: контекстное меню для кнопки и (событие всплывает вверх) контекстное меню для документа.

Как это поправить? Одно из решений – это подумать: «Когда мы обрабатываем правый клик в обработчике на кнопке, остановим всплытие», и вызвать :

Теперь контекстное меню для кнопки работает как задумано. Но цена слишком высока. Мы навсегда запретили доступ к информации о правых кликах для любого внешнего кода, включая счётчики, которые могли бы собирать статистику, и т.п. Это слегка неразумно.

Альтернативным решением было бы проверить в обработчике , было ли отменено действие по умолчанию? Если да, тогда событие было обработано, и нам не нужно на него реагировать.

Сейчас всё работает правильно. Если у нас есть вложенные элементы и каждый из них имеет контекстное меню, то код также будет работать. Просто убедитесь, что проверяете в каждом обработчике .

event.stopPropagation() и event.preventDefault()

Как мы можем видеть, и (также известный как ) – это две разные функции. Они никак не связаны друг с другом.

Архитектура вложенных контекстных меню

Есть также несколько альтернативных путей, чтобы реализовать вложенные контекстные меню. Одним из них является единый глобальный объект с обработчиком и методами, позволяющими хранить в нём другие обработчики.

Объект будет перехватывать любой клик правой кнопкой мыши, просматривать сохранённые обработчики и запускать соответствующий.

Но при этом каждый фрагмент кода, которому требуется контекстное меню, должен знать об этом объекте и использовать его вместо собственного обработчика .

Как же пофиксить эту проблему?

Делегированием событий.

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

В нашем примере это список  с классом , который появляется при загрузке страницы. Мы можем повесить слушатель событий прямо на него.

Лучше рассматривать делегирование событий, как ответственных родителей и нерадивых детишек. В этом случае родители это просто боги, а детям приходиться слушать всё, что говорят их родители. Прекрасный аспект тут в том, что если бы мы добавили больше детей (или инпутов), то родители бы остались такими же в правах — они были с самого начала или другими словами, прямо с загрузки страницы.

Давайте прикрепим слушатель событий:

Теперь у нас есть слушатель событий на , а не на каждом отдельном потомке. Так что же тогда произойдет, если мы кликнем на инпут после того, как загрузилась страница и выведем в консоль ?

 это отсылка к объекту, на котом сработало событие. Или другими словами, он указывает на HTML элемент на котором сработало событие.

Событие в нашем случае это клик. Объект на котором отработало событие это .

**  рассматривается, как часть объекта  — поэтому мы видимо их обоих**

Синтаксис

Чувствительная к регистру строка, представляющая тип обрабатываемого события.
Объект, который принимает уведомление, когда событие указанного типа произошло. Это должен быть объект, реализующий интерфейс  или просто функция JavaScript.
 Необязательный
Объект , который определяет характеристики объекта, прослушивающего событие. Доступны следующие варианты:

  • :   указывает, что события этого типа будут отправлены зарегистрированному обработчику  перед отправкой на , расположенный ниже в дереве DOM.
  • : указывает, что обработчик должен быть вызван не более одного раза после добавления. Если , обработчик автоматически удаляется при вызове.
  • :   указывает, что обработчик никогда не вызовет . Если всё же вызов будет произведён, браузер должен игнорировать его и генерировать консольное предупреждение. Пример
  • Это API не было стандартизировано.: указывает, что обработчик должен быть добавлен в системную группу. Доступно только в коде, запущенном в XBL или в расширении Chrome.
Необязательный

Если равно , указывает, что пользователь желает начать захват. После инициализации захвата все события указанного типа будут отправлены в зарегистрированный  перед отправкой в какой-либо  под ним в дереве DOM. События, восходящие вверх по дереву, не будут вызывать обработчиков, которым назначено использовать захват. Смотрите  для более детального объяснения. Значение  по умолчанию равно .

Note: Для обработчиков событий прикреплённых к цели события, событие  находиться в целевой фазе, а не в фазах захвата или всплытия. События в целевой фазе инициируют все обработчики на элементе в том порядке, в котором они были зарегистрированы независимо от параметра .

Note:  не всегда был опциональным. Лучше указывать данный параметр для повышения совместимости.

Это API не было стандартизировано.
Если равно , обработчик будет получать сгенерированные события, посланные со страницы (по умолчанию равно  для chrome и  для обычных веб-страниц). Этот параметр доступен только в Gecko и в основном полезен для использования в дополнениях и самом браузере. Смотрите Взаимодействие между привилегированными и непривилегированными страницами для примеров использования.

Прежде чем использовать определённое значение в объекте , рекомендуется убедиться, что браузер пользователя поддерживает его, поскольку это дополнение, которое не все браузеры поддерживали исторически.

Событие загрузки

Когда завершается загрузка страницы, для объектов тела документа и окна возникает JavaScript event «load». Оно используется для планирования инициализации действий, для которых требуется загрузка всего документа. Не забывайте, что содержимое <script> запускается сразу, когда встречается этот тег. Иногда это слишком рано. Например, когда скрипт должен сделать что-то с частями документа, которые загружаются после тега <script>.

<img> и теги скриптов, которые загружают внешние файлы, также содержат событие «load«. Оно указывает, что файл, который был связан с ними, загружен. Как и события фокуса ввода, события загрузки не распространяются.

Когда мы закрываем страницу или переходим на другую (например, нажав на ссылку), срабатывает событие «beforeunload«. Оно применяется, чтобы предотвратить возможность случайной потери пользователем того, с чем он работал, после закрытия документа.

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

Пишем делегирование событий в JavaScript

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

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

А если этот элемент является инпутом, то тогда мы выводим в консоль  и выполняем последующий JavaScript код на этом узле потомке.

Очень важно, что теперь мы можем быть уверены в том, что пользователь кликнул нужный узел потомок, пусть даже инпуты не были добавлены в DOM после начальной загрузки страницы

Инициализация обработчика через атрибут

Этот способ позволяет прописать обработчик напрямую в разметке. Выполняется это посредством указания JavaScript кода в атрибуте . Вместо необходимо написать имя (тип) события (например: ).

Пример, в котором назначим HTML-элементу обработчик события , используя атрибут:

<!-- onclick - атрибут, содержащий код, который будет выполняться всякий раз при наступлении события click на этом элементе -->
<button type="button" onclick="alert(Date())">Текущая дата</button>

Если код, который нужно поместить в атрибут достаточно большой, то в этом случае его лучше оформить в виде функции, а в атрибут поместить её вызов.

Например:

<script>
  // функция sum
  function sum() {
    const number1 = +document.querySelector('#number1').value;
    const number2 = +document.querySelector('#number2').value;
    const sum = number1 + number2;
    document.querySelector('#answer').textContent = sum;
  }
</script>

<input type="text" id="number1">
<input type="text" id="number2">
<div id="answer"></div>
<button type="button" onclick="sum()">Посчитать</button>

В этом примере мы указали в качестве обработчика функцию .

При этом задавать обработчик напрямую в разметке не является хорошей практикой, т.к. это приведёт к смешиванию JavaScript и HTML кода.

More Examples

Example

You can also refer to an external «named» function:

document.addEventListener(«click», myFunction);function myFunction() {  document.getElementById(«demo»).innerHTML = «Hello World»;
}

Example

You can add many events to the document, without overwriting existing events.

This example demonstrates how to add two click events to the document:

document.addEventListener(«click», myFunction);document.addEventListener(«click», someOtherFunction);

Example

You can add events of different types to the document.

This example demonstrates how to add many events to the document:

document.addEventListener(«mouseover», myFunction);document.addEventListener(«click», someOtherFunction);
document.addEventListener(«mouseout», someOtherFunction);

Example

When passing parameter values, use an «anonymous function» that calls the
specified function with the parameters:

document.addEventListener(«click», function() {  myFunction(p1, p2);});

Example

Change the background color of the document’s <body> element:

document.addEventListener(«click», function(){  document.body.style.backgroundColor = «red»;});

Example

Using the removeEventListener() method to remove an event handler that has
been attached with the addEventListener() method:

// Attach an event handler to the documentdocument.addEventListener(«mousemove», myFunction);// Remove the event handler from the document
document.removeEventListener(«mousemove», myFunction);

Example

For browsers that don’t support the addEventListener() method, you can use
the attachEvent() method.

This example demonstrates a cross-browser solution:

if (document.addEventListener) {                // For all major browsers, except IE 8 and earlier  document.addEventListener(«click», myFunction);} else if (document.attachEvent) {              // For IE 8 and earlier versions
  document.attachEvent(«onclick», myFunction);}

Погружение

Существует ещё одна фаза из жизненного цикла события – «погружение» (иногда её называют «перехват»). Она очень редко используется в реальном коде, однако тоже может быть полезной.

Стандарт DOM Events описывает 3 фазы прохода события:

  1. Фаза погружения (capturing phase) – событие сначала идёт сверху вниз.
  2. Фаза цели (target phase) – событие достигло целевого(исходного) элемента.
  3. Фаза всплытия (bubbling stage) – событие начинает всплывать.

Картинка из спецификации демонстрирует, как это работает при клике по ячейке , расположенной внутри таблицы:

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

Ранее мы говорили только о всплытии, потому что другие стадии, как правило, не используются и проходят незаметно для нас.

Обработчики, добавленные через -свойство или через HTML-атрибуты, или через с двумя аргументами, ничего не знают о фазе погружения, а работают только на 2-ой и 3-ей фазах.

Чтобы поймать событие на стадии погружения, нужно использовать третий аргумент вот так:

Существуют два варианта значений опции :

  • Если аргумент (по умолчанию), то событие будет поймано при всплытии.
  • Если аргумент , то событие будет перехвачено при погружении.

Обратите внимание, что хоть и формально существует 3 фазы, 2-ую фазу («фазу цели»: событие достигло элемента) нельзя обработать отдельно, при её достижении вызываются все обработчики: и на всплытие, и на погружение. Давайте посмотрим и всплытие и погружение в действии:

Давайте посмотрим и всплытие и погружение в действии:

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

Если вы кликните по , то последовательность следующая:

  1. → → → (фаза погружения, первый обработчик)
  2. (фаза цели, срабатывают обработчики, установленные и на погружение и на всплытие, так что выведется два раза)
  3. → → → (фаза всплытия, второй обработчик)

Существует свойство , содержащее номер фазы, на которой событие было поймано. Но оно используется редко, мы обычно и так знаем об этом в обработчике.

Чтобы убрать обработчик , нужна та же фаза

Если мы добавили обработчик вот так , то мы должны передать то же значение аргумента в , когда снимаем обработчик.

На каждой фазе разные обработчики на одном элементе срабатывают в порядке назначения

Если у нас несколько обработчиков одного события, назначенных на один элемент, в рамках одной фазы, то их порядок срабатывания – тот же, в котором они установлены:

Примечания по использованию

Обработчик событий может быть задан либо как колбэк-функция, либо как объект реализующий , чей (en-US) метод служит как колбэк-функция.

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

Например, колбэк обработчика событий, который может использоваться для обработки и может выглядеть так:

В более старых версиях спецификации DOM третьим параметром было логическое значение, указывающее, следует ли захватывать событие на этапе погружения. Со временем стало ясно, что необходимо больше вариантов. Вместо добавления дополнительных параметров в функцию (усложняя ситуацию при использовании необязательных значений) третий параметр был изменён на объект, который может содержать различные свойства, определяющие значения параметров для настройки обработчика событий.

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

Например, если вы хотите проверить параметр :

Этот код создаёт объект с геттером для свойства passive, устанавливающим флаг  в , если он вызван. Это означает, что если браузер проверяет значение свойства на объекте , значение будет установлено в true; в противном случае он останется ложным. Затем мы вызываем , чтобы настроить фальшивый обработчик событий, указав эти параметры для проверки опций, если браузер распознает объект в качестве третьего параметра.

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

Если вы хотите добавить обработчик событий, использующий параметры, о которых идёт речь, вы можете сделать это подобным образом:

Здесь мы добавляем обработчик события элемента . Для третьего параметра, если имеет значение , мы указываем объект с ; в противном случае мы знаем, что нам нужно передать логическое значение, и мы передаём как значение параметра .

Вы можете использовать стороннюю библиотеку, такую как Modernizr или Detect It, чтобы проверить поддержку необходимого свойства.

Узнайте больше о из  Web Incubator Community Group.

Примеры

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

Результат
script.js
example.css
index.html

Обработчики сработают в порядке «сверху-вниз»: → → .

JS-код здесь такой:

Никто не мешает назначить обработчики для обеих стадий, вот так:

Кликните по внутреннему элементу , чтобы увидеть порядок прохода события:

Результат
script.js
example.css
index.html

Должно быть → → → → → . Заметим, что элемент участвует в обоих стадиях.

Как видно из примера, один и тот же обработчик можно назначить на разные стадии. При этом номер текущей стадии он, при необходимости, может получить из свойства (=1, если погружение, =3, если всплытие).

Possible mistakes

If you’re starting to work with events – please note some subtleties.

We can set an existing function as a handler:

But be careful: the function should be assigned as , not .

If we add parentheses, then becomes is a function call. So the last line actually takes the result of the function execution, that is (as the function returns nothing), and assigns it to . That doesn’t work.

…On the other hand, in the markup we do need the parentheses:

The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content.

So the markup generates this property:

Don’t use for handlers.

Such a call won’t work:

DOM-property case matters.

Assign a handler to , not , because DOM properties are case-sensitive.

Итого

Чтобы сгенерировать событие из кода, вначале надо создать объект события.

Базовый конструктор принимает обязательное имя события и – объект с двумя свойствами:

  • чтобы событие всплывало.
  • если мы хотим, чтобы работал.

Особые конструкторы встроенных событий , и другие принимают специфичные для каждого конкретного типа событий свойства. Например, для событий мыши.

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

Несмотря на техническую возможность генерировать встроенные браузерные события типа или , пользоваться ей стоит с большой осторожностью. Весьма часто, когда разработчик хочет сгенерировать встроенное событие – это вызвано «кривой» архитектурой кода

Весьма часто, когда разработчик хочет сгенерировать встроенное событие – это вызвано «кривой» архитектурой кода.

Как правило, генерация встроенных событий полезна в следующих случаях:

  • Либо как явный и грубый хак, чтобы заставить работать сторонние библиотеки, в которых не предусмотрены другие средства взаимодействия.
  • Либо для автоматического тестирования, чтобы скриптом «нажать на кнопку» и посмотреть, произошло ли нужное действие.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector