Javascript метод eventtarget.addeventlistener()
Содержание:
- addEventListener() Метод
- Event Bubbling or Event Capturing?
- Кнопка мыши: which/button.
- JavaScript
- Parameter Values
- Погружение
- Координаты мыши: clientX(Y)/pageX(Y)
- Обработчик события как атрибут элемента
- More Examples
- Parameter Values
- Отличия IE8-
- Событие: pointercancel
- Пенополистирол
- Usage notes
- Объект «событие» (event)
- Подписка на событие через код JavaScript с помощью свойства
- Итого
addEventListener() Метод
Пример
Добавьте прослушиватель событий, который срабатывает при нажатии пользователем кнопки:
document.getElementById(«myBtn»).addEventListener(«click», displayDate);
Метод addEventListener () присоединяет обработчик событий к указанному элементу.
Метод addEventListener () прикрепляет обработчик событий к элементу без перезаписи существующих обработчиков событий.
Можно добавить несколько обработчиков событий в один элемент.
Можно добавить несколько обработчиков событий одного типа в один элемент, т.е. два события «Click».
Прослушиватели событий можно добавлять к любому объекту DOM, а не только к элементам HTML. т.е. объект Window.
Метод addEventListener () упрощает управление реакцией события на восходящую маршрутизацию.
При использовании метода addEventListener (), JavaScript отделяется от HTML разметки, для лучшей читаемости и позволяет добавлять прослушиватели событий, даже если вы не контролируете разметку HTML.
Прослушиватель событий можно легко удалить с помощью метода RemoveEventListener ().
Event Bubbling or Event Capturing?
There are two ways of event propagation in the HTML DOM, bubbling and capturing.
Event propagation is a way of defining the element order when an event occurs.
If you have a <p> element inside a <div> element, and the user clicks on the <p> element, which element’s
«click» event should be handled first?
In bubbling the inner most element’s event is handled first and then the outer:
the <p> element’s click event is handled first, then the <div> element’s click event.
In capturing the outer most element’s event is handled first and then the inner:
the <div> element’s click event will be handled first, then the <p> element’s click event.
With the addEventListener() method you can specify the propagation type by using the «useCapture» parameter:
addEventListener(event, function, useCapture);
The default value is false, which will use the bubbling propagation, when the value is set to true, the event uses the capturing propagation.
Example
document.getElementById(«myP»).addEventListener(«click», myFunction, true);
document.getElementById(«myDiv»).addEventListener(«click», myFunction, true);
После получения события обычно интересно узнать, какая кнопка была нажата. Если, конечно, это не событие , с которым все и так понятно
Для этого в объекте есть два свойства: и , которые содержат числовые значения, соответствующие нажатой кнопке. К сожалению, тут есть некоторые несовместимости.
Internet Explorer | Firefox, Safari Win и Opera | Konqueror | ||
ЛЕВАЯ КНОПКА | event.which | undefined | 1 | 1 |
event.button | 1 | 1 | ||
СРЕДНЯЯ КНОПКА | event.which | undefined | 2 | 2 |
event.button | 4 | 1 | 4 | |
ПРАВАЯ КНОПКА | event.which | undefined | 3 | 3 |
event.button | 2 | 2 | 2 |
Свойство было изначально изобретено Netscape, а использовалось в Internet Explorer.
Через некоторое время браузеры стали использовать оба и все перепуталось.
В стандарте W3C прописано свойство , которое ведет себя, как в Firefox, т.е:
- 0 — левая кнопка
- 1 — средняя кнопка
- 2 — правая кнопка
Подход создателей браузера Internet Explorer, вообще говоря, более универсальный, так как является 3-битовым числом, каждый бит которого отвечает за кнопку мыши.
Так, (первый бит) установлен в 1, если нажата левая кнопка, (второй бит) установлен в 1, если нажата правая кнопка, и (третий бит) — если нажата средняя.
В результате мы не можем отловить, когда, например, нажаты левая и правая кнопки, а когда только левая или только правая. К сожалению, это можно сделать только в IE.
Удобнее всего — взять за основу свойство , которое одинаково поддерживают почти все браузеры.
Остается лишь составить из для Internet Explorer:
if (!e.which && e.button) { if (e.button & 1) e.which = 1 else if (e.button & 4) e.which = 2 else if (e.button & 2) e.which = 3 }
Вот универсальный тестовый стенд по определению клавиш. Выбирайте любую мышь и жмите кнопу из любого браузера — ниже появятся названия событий и значения .
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()
Parameter Values
Parameter | Description |
---|---|
event | Required. A String that specifies the name of the event.Note: Do not use the «on» prefix. For example, use «click» instead of «onclick».For a list of all HTML DOM events, look at our complete HTML DOM Event Object Reference. |
function | Required. Specifies the function to run when the event occurs. When the event occurs, an event object is passed to the function as the first parameter. The type of the event object depends on the specified event. For example, the «click» event belongs to the MouseEvent object. |
useCapture |
Optional. A Boolean value that specifies whether the event should be executed in the capturing or in the bubbling phase. Possible values:
|
Погружение
Существует ещё одна фаза из жизненного цикла события – «погружение» (иногда её называют «перехват»). Она очень редко используется в реальном коде, однако тоже может быть полезной.
Стандарт DOM Events описывает 3 фазы прохода события:
- Фаза погружения (capturing phase) – событие сначала идёт сверху вниз.
- Фаза цели (target phase) – событие достигло целевого(исходного) элемента.
- Фаза всплытия (bubbling stage) – событие начинает всплывать.
Картинка из спецификации демонстрирует, как это работает при клике по ячейке , расположенной внутри таблицы:
То есть при клике на событие путешествует по цепочке родителей сначала вниз к элементу (погружается), затем оно достигает целевой элемент (фаза цели), а потом идёт наверх (всплытие), вызывая по пути обработчики.
Ранее мы говорили только о всплытии, потому что другие стадии, как правило, не используются и проходят незаметно для нас.
Обработчики, добавленные через -свойство или через HTML-атрибуты, или через с двумя аргументами, ничего не знают о фазе погружения, а работают только на 2-ой и 3-ей фазах.
Чтобы поймать событие на стадии погружения, нужно использовать третий аргумент вот так:
Существуют два варианта значений опции :
- Если аргумент (по умолчанию), то событие будет поймано при всплытии.
- Если аргумент , то событие будет перехвачено при погружении.
Обратите внимание, что хоть и формально существует 3 фазы, 2-ую фазу («фазу цели»: событие достигло элемента) нельзя обработать отдельно, при её достижении вызываются все обработчики: и на всплытие, и на погружение. Давайте посмотрим и всплытие и погружение в действии:
Давайте посмотрим и всплытие и погружение в действии:
Здесь обработчики навешиваются на каждый элемент в документе, чтобы увидеть в каком порядке они вызываются по мере прохода события.
Если вы кликните по , то последовательность следующая:
- → → → (фаза погружения, первый обработчик)
- (фаза цели, срабатывают обработчики, установленные и на погружение и на всплытие, так что выведется два раза)
- → → → (фаза всплытия, второй обработчик)
Существует свойство , содержащее номер фазы, на которой событие было поймано. Но оно используется редко, мы обычно и так знаем об этом в обработчике.
Чтобы убрать обработчик , нужна та же фаза
Если мы добавили обработчик вот так , то мы должны передать то же значение аргумента в , когда снимаем обработчик.
На каждой фазе разные обработчики на одном элементе срабатывают в порядке назначения
Если у нас несколько обработчиков одного события, назначенных на один элемент, в рамках одной фазы, то их порядок срабатывания – тот же, в котором они установлены:
Координаты мыши: clientX(Y)/pageX(Y)
При обработке событий, связанных с мышью, нужен кроссбраузерный способ получения координат курсора из события в обработчике.
Координаты курсора мыши относительно окна находятся в стандартных свойствах . Они одинаково поддерживается всеми браузерами.
Если у вас есть окно 500×500, и мышь находится в центре, то и будут оба равны 250. Если вы затем проскроллируете документ вниз, налево или вверх, не двигая курсор — значения не изменятся, так как отсчитываются относительно окна, а не документа.
Как правило, при обработке события нужна позиция мыши относительно документа, учитывающая прокрутку. Стандарт W3C предоставляет для этого свойство .
Если у вас есть окно 500×500, и мышь находится в центре, то и будут оба равны 250. Если вы затем проскроллируете на 250 пикселей вниз, станет равным 750.
Таким образом содержат координаты, на каком месте документа произошло событие, учитывая все прокрутки.
Свойства поддерживаются всеми браузерами, кроме Internet Explorer.
В IE их можно получить из , прибавив к ним .
Обычно оно находится в <body>: , но это не всегда так. Например, при выборе Strict DTD оно высчитывается для <html>: . Кроме того, тэга <body> может просто не быть в документе.
Поэтому мы сначала возьмем (если есть), затем проверим . Если нет ни того, ни того, то 0.
var html = document.documentElement var body = document.body e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0)
Кроме того, в IE может быть немного сдвинут с позиции 0,0. Значение сдвига находится в , и его также необходимо учесть.
Этот код позволяет надежно получить для IE, в котором его изначально нет:
if (e.pageX == null && e.clientX != null ) { var html = document.documentElement var body = document.body e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0) e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0) }
Этот обработчик обновляет координаты мыши относительно документа.
function mouseShowHandler(e){ e = e || window.event if (e.pageX == null && e.clientX != null ) { var html = document.documentElement var body = document.body e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0) e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0) } document.getElementById('mouseX').value = e.pageX document.getElementById('mouseY').value = e.pageY }
Координата X:
Координата Y:
Обработчик события как атрибут элемента
Это самый старый способ назначения обработчиков события и наименее используемый на данный момент. Для того чтобы его добавить, необходимо к имени события добавить приставку «on» и записать примерно такой код:
Обработчик события как атрибут
JavaScript
<button onclick=’alert(«Событие произошло!»)’>Нажми меня</button>
1 | <button onclick=’alert(«Событие произошло!»)’>Нажмименя<button> |
Нажми меня
Можно вызвать функцию, в которую можно передать один или несколько аргументов:
Обработчик события как атрибут элемента
JavaScript
<script>
function change(element, color){
element.style.backgroundColor = color;
}
</script>
<p onclick=»change(this, ‘red’)»>Кликни здесь, и этот абзац станет красным.
Но только один раз.</p>
<p onclick=»change(this, ‘lime’)»>Кликни здесь, и этот абзац станет зеленым.
Но только один раз.</p>
1 2 3 4 5 6 7 8 9 |
<script> functionchange(element,color){ element.style.backgroundColor=color; } <ponclick=»change(this, ‘red’)»>Кликниздесь,иэтотабзацстанеткрасным. Нотолькоодинраз.<p> <ponclick=»change(this, ‘lime’)»>Кликниздесь,иэтотабзацстанетзеленым. Нотолькоодинраз.<p> |
Пример этого кода:
Кликни здесь, и этот абзац станет красным. Но только один раз.
Кликни здесь, и этот абзац станет зеленым. Но только один раз.
Недостатком этого способа является то, что, если добавлять обработчики событий нужно к большому количеству элементов, то, во-первых, легко допустить ошибку в каком-нибудь из них, а во-вторых, при изменении кода сделать это придется долго. И опять-таки можно допустить ошибку.
Использовать этот способ нужно в учебных целях поначалу, а также тогда, когда это самый простой способ или нужно очень быстро добавить обработчик события к 1 элементу.
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);}
Parameter Values
Parameter | Description |
---|---|
event | Required. A String that specifies the name of the event.Note: Do not use the «on» prefix. For example, use «click» instead of «onclick».For a list of all HTML DOM events, look at our complete HTML DOM Event Object Reference. |
function | Required. Specifies the function to run when the event occurs. When the event occurs, an event object is passed to the function as the first parameter. The type of the event object depends on the specified event. For example, the «click» event belongs to the MouseEvent object. |
useCapture |
Optional. A Boolean value that specifies whether the event should be executed in the capturing or in the bubbling phase. Possible values:
|
Отличия IE8-
Чтобы было проще ориентироваться, я собрал отличия IE8-, которые имеют отношение ко всплытию, в одну секцию.
Их знание понадобится, если вы решите писать на чистом JS, без фреймворков и вам понадобится поддержка IE8-.
Нет свойства
Обратим внимание, что при назначении обработчика через у нас есть , поэтому , как правило, не нужно, а вот при назначении через обработчик не получает , так что текущий элемент, если нужен, можно будет взять лишь из замыкания.
Вместо в IE8- используется
Если мы пишем обработчик, который будет поддерживать и IE8- и современные браузеры, то можно начать его так:
Для остановки всплытия используется код .
Кросс-браузерно остановить всплытие можно так:
Далее в учебнике мы будем использовать стандартные свойства и вызовы, поскольку добавление этих строк, обеспечивающих совместимость – достаточно простая и очевидная задача. Кроме того, никто не мешает подключить полифил.
Ещё раз хотелось бы заметить – эти отличия нужно знать при написании JS-кода с поддержкой IE8- без фреймворков. Почти все JS-фреймворки обеспечивают кросс-браузерную поддержку , и .
Событие: pointercancel
Событие происходит, когда текущее действие с указателем по какой-то причине прерывается, и события указателя больше не генерируются.
К таким причинам можно отнести:
- Указывающее устройство было физически выключено.
- Изменилась ориентация устройства (перевернули планшет).
- Браузер решил сам обработать действие, считая его жестом мыши, масштабированием и т.п.
Мы продемонстрируем на практическом примере, чтобы увидеть, как это влияет на нас.
Допустим, мы реализуем перетаскивание («drag-and-drop») для нашего мяча, как в начале статьи Drag’n’Drop с событиями мыши.
Вот последовательность действий пользователя и соответствующие события:
- Пользователь нажимает на изображении, чтобы начать перетаскивание
- Затем он перемещает указатель, двигая изображение
- И тут происходит сюрприз! Браузер имеет встроенную поддержку «Drag’n’Drop» для изображений, которая запускает и перехватывает процесс перетаскивания, генерируя при этом событие .
- Теперь браузер сам обрабатывает перетаскивание изображения. У пользователя есть возможность перетащить изображение мяча даже за пределы браузера, в свою почтовую программу или файловый менеджер.
- Событий для нас больше не генерируется.
Таким образом, браузер «перехватывает» действие: в начале переноса drag-and-drop запускается событие , и после этого события больше не генерируются.
Вот демо drag’n’drop с записью событий указателя (только , и ) в :
Мы бы хотели реализовать перетаскивание самостоятельно, поэтому давайте скажем браузеру не перехватывать его.
Предотвращайте действие браузера по умолчанию, чтобы избежать .
Нужно сделать две вещи:
- Предотвратить запуск встроенного drag’n’drop
- Мы можем сделать это, задав , как описано в статье Drag’n’Drop с событиями мыши.
- Это работает для событий мыши.
- Для устройств с сенсорным экраном существуют другие действия браузера, связанные с касаниями, кроме drag’n’drop. Чтобы с ними не возникало проблем:
- Мы можем предотвратить их, добавив в CSS свойство .
- Затем наш код начнёт корректно работать на устройствах с сенсорным экраном
После того, как мы это сделаем, события будут работать как и ожидается, браузер не будет перехватывать процесс и не будет вызывать событие .
В данном демо произведены нужные действия:
Как вы можете видеть, событие больше не срабатывает.
Теперь мы можем добавить код для перемещения мяча и наш drag’n’drop будет работать и для мыши и для устройств с сенсорным экраном.
Пенополистирол
Также ставший традиционным полимерный материал, называемый, из-за жёсткости, «скорлупой». Утеплитель представляет собой две полусферы с выемками под размер изолируемых элементов трубопровода.
Достоинства материала:
- невысокая стоимость;
- небольшое значение теплоотдачи;
- влагостойкость – пенополистирол не впитывает жидкость;
- лёгкость;
- простота монтажа;
- возможность совмещения с металлами и полимерными материалами.
Основной недостаток – недопустимость использования на чрезмерно горячих трубах.
Usage notes
The event listener callback
The event listener can be specified as either a callback function or an object that implements , whose method serves as the callback function.
The callback function itself has the same parameters and return value as the method; that is, the callback accepts a single parameter: an object based on describing the event that has occurred, and it returns nothing.
For example, an event handler callback that can be used to handle both and might look like this:
function eventHandler(event) { if (event.type == 'fullscreenchange') { /* handle a full screen toggle */ } else /* fullscreenerror */ { /* handle a full screen toggle error */ } }
Safely detecting option support
In older versions of the DOM specification, the third parameter of was a Boolean value indicating whether or not to use capture. Over time, it became clear that more options were needed. Rather than adding more parameters to the function (complicating things enormously when dealing with optional values), the third parameter was changed to an object that can contain various properties defining the values of options to configure the process of removing the event listener.
Because older browsers (as well as some not-too-old browsers) still assume the third parameter is a Boolean, you need to build your code to handle this scenario intelligently. You can do this by using feature detection for each of the options you’re interested in.
For example, if you want to check for the option:
let passiveSupported = false; try { const options = { get passive() { // This function will be called when the browser // attempts to access the passive property. passiveSupported = true; return false; } }; window.addEventListener("test", null, options); window.removeEventListener("test", null, options); } catch(err) { passiveSupported = false; }
This creates an object with a getter function for the property; the getter sets a flag, , to if it gets called. That means that if the browser checks the value of the property on the object, will be set to ; otherwise, it will remain . We then call to set up a fake event handler, specifying those options, so that the options will be checked if the browser recognizes an object as the third parameter. Then, we call to clean up after ourselves. (Note that is ignored on event listeners that aren’t called.)
You can check whether any option is supported this way. Just add a getter for that option using code similar to what is shown above.
Then, when you want to create an actual event listener that uses the options in question, you can do something like this:
someElement.addEventListener("mouseup", handleMouseUp, passiveSupported ? { passive: true } : false);
Here we’re adding a listener for the event on the element . For the third parameter, if is , we’re specifying an object with set to ; otherwise, we know that we need to pass a Boolean, and we pass as the value of the parameter.
If you’d prefer, you can use a third-party library like Modernizr or Detect It to do this test for you.
You can learn more from the article about from the Web Incubator Community Group.
Объект «событие» (event)
Объект событие всегда передается обработчику и содержит массу полезной информации о том где и какое событие произошло.
Способов передачи этого объекта обработчику существует ровно два, и они зависят от способа его установки и от браузера.
В браузерах, работающих по рекомендациям W3C, объект события всегда передается в обработчик первым параметром.
Например:
function doSomething(event) { // event - будет содержать объект события } element.onclick = doSomething;
При вызове обработчика объект события будет передан ему первым аргументом.
Можно назначить и вот так:
element.onclick = function(event) { // event - объект события }
Интересный побочный эффект — в возможности использования переменной при назначении обработчика в HTML:
<input type="button" onclick="alert(event)" value="Жми сюда не ошибешься"/>
Это работает благодаря тому, что браузер автоматически создает функцию-обработчик с данным телом, в которой первый аргумент .
В Internet Explorer существует глобальный объект , который хранит в себе информацию о последнем событии. А первого аргумента обработчика просто нет.
То есть, все должно работать так:
// обработчик без аргументов function doSomething() { // window.event - объект события } element.onclick = doSomething;
Обратите внимание, что доступ к при назначении обработчика в HTML (см. пример выше) по-прежнему будет работать
Такой вот надежный и простой кросс-браузерный доступ к объекту события.
Можно кросс-браузерно получить объект события, использовав такой приём:
function doSomething(event) { event = event || window.event // Теперь event - объект события во всех браузерах. } element.onclick = doSomething
Как мы уже говорили раньше, при описании обработчика события в HTML-разметке для получения события можно использовать переменную с названием .
<input type="button" onclick="alert(event.type)" value="Нажми меня"/>
Этот код в действии:
Это совершенно кросс-браузерный способ, так как по стандарту — название первого аргумента функции-обработчика, которую автоматом создаст браузер; ну а в IE значение будет взято из глобального объекта .
Подписка на событие через код JavaScript с помощью свойства
Этот способ подписки на событие осуществляется через код JavaScript с помощью задания элементу свойства . Основной принцип данного метода заключается в следующем:
- Найти элемент (объект) в DOM-дереве, на событие которого Вы хотите подписаться.
- Добавить найденному объекту свойство, которое должно иметь следующий вид:
, где — это имя определённого события.После этого необходимо данному свойству присвоить обработчик, т.е. безымянную или некоторую указанную функцию, которая будет выполняться при наступлении этого события.
Например, подписаться на событие элемента, имеющего . При наступлении этого события () выполнить его обработку с помощью безымянной функции:
<button id="myBtn" value="Демонстрация события click"> <script> //в качестве обработчика события будем использовать безымянную функцию: document.getElementById("myID").onclick = function { alert("Событие click"); } </script>
Например, добавить к кнопке, имеющей событие , при наступлении которого выполняется указанная функция:
//Найти элемент на событие, которого Вы хотите подписаться var myButton = document.getElementById("myButton"); //добавить к объекту свойство, имеющее имя on //при наступлении события click выполняется функция myFunction myButton.onclick = myFunction; //функция myFunction function myFunction() { //код функции //... }
Если событие задаётся через атрибут, то браузер, читая код HTML, создаёт соответствующее свойство автоматически. Т.е. браузер работает с событиями только с помощью соответствующих свойств объекта (элемента).
Если Вы подпишитесь на событие различными способами, т.е. через атрибут и с помощью свойства, то браузер в этом случае будет использовать только вариант реализации события, выполненный с помощью свойства.
Подписываться на события лучше только с помощью соответствующих свойств объекта (элемента), использовать атрибуты для этих целей не рекомендуется.
Итого
При наступлении события – самый глубоко вложенный элемент, на котором оно произошло, помечается как «целевой» ().
- Затем событие сначала двигается вниз от корня документа к , по пути вызывая обработчики, поставленные через , где – это сокращение для .
- Далее обработчики вызываются на целевом элементе.
- Далее событие двигается от вверх к корню документа, по пути вызывая обработчики, поставленные через и без третьего аргумента или с третьим аргументом равным .
Каждый обработчик имеет доступ к свойствам события :
- – самый глубокий элемент, на котором произошло событие.
- (=) – элемент, на котором в данный момент сработал обработчик (тот, на котором «висит» конкретный обработчик)
- – на какой фазе он сработал (погружение=1, фаза цели=2, всплытие=3).
Любой обработчик может остановить событие вызовом , но делать это не рекомендуется, так как в дальнейшем это событие может понадобиться, иногда для самых неожиданных вещей.
В современной разработке стадия погружения используется очень редко, обычно события обрабатываются во время всплытия. И в этом есть логика.
В реальном мире, когда происходит чрезвычайная ситуация, местные службы реагируют первыми. Они знают лучше всех местность, в которой это произошло, и другие детали. Вышестоящие инстанции подключаются уже после этого и при необходимости.
Тоже самое справедливо для обработчиков событий. Код, который «навесил» обработчик на конкретный элемент, знает максимум деталей об элементе и его предназначении. Например, обработчик на определённом скорее всего подходит только для этого конкретного , он знает все о нём, поэтому он должен отработать первым. Далее имеет смысл передать обработку события родителю – он тоже понимает, что происходит, но уже менее детально, далее – выше, и так далее, до самого объекта , обработчик на котором реализовывает самую общую функциональность уровня документа.
Всплытие и погружение являются основой для «делегирования событий» – очень мощного приёма обработки событий. Его мы изучим в следующей главе.