Javascript — способы подписки на события
Содержание:
- Опция «passive» для обработчика
- Обработчики событий
- Элементы, связанные с событием
- Координаты мыши: clientX(Y)/pageX(Y)
- Мульти-тач
- Событие: pointercancel
- Краткая история
- JS Tutorial
- addEventListener
- event.preventDefault()
- Может ли onclick быть атрибутом!?
- Parameter Values
- Погружение
- JavaScript
- Parameter Values
- Кнопка мыши: which/button.
- Итого
Опция «passive» для обработчика
Необязательная опция для сигнализирует браузеру, что обработчик не собирается выполнять .
Почему это может быть полезно?
Есть некоторые события, как на мобильных устройствах (когда пользователь перемещает палец по экрану), которое по умолчанию начинает прокрутку, но мы можем отменить это действие, используя в обработчике.
Поэтому, когда браузер обнаружит такое событие, он должен для начала запустить все обработчики и после, если не вызывается нигде, он может начать прокрутку. Это может вызвать ненужные задержки в пользовательском интерфейсе.
Опция сообщает браузеру, что обработчик не собирается отменять прокрутку. Тогда браузер начинает её немедленно, обеспечивая максимально плавный интерфейс, параллельно обрабатывая событие.
Для некоторых браузеров (Firefox, Chrome) опция по умолчанию включена в для таких событий, как и .
Обработчики событий
Последнее обновление: 1.11.2015
Встроенные обработчики
В прошлой теме были рассмотрены встроенные обработчики (inline event handler), которые определяются в коде элемента с
помощью атрибутов:
<div id="rect" onclick="handler(event)"></div>
Хотя этот подход прекрасно работает, но он имеет кучу недостатков:
-
Код html смешивается с кодом JavaScript, в связи с чем становится труднее разрабатывать, отлаживать и поддерживать приложение
-
Обработчики событий можно задать только для уже созданных на веб-странице элементов. Динамически создаваемые элементы в этом случае
лишаются возможности обработки событий -
К элементу для одного события может быть прикреплен только один обработчик
-
Нельзя удалить обработчик без изменения кода
Свойства обработчиков событий
Проблемы, которые возникают при использовании встроенных обработчиков, были призваны решить свойства обработчиков. Подобно тому, как у html-элементов
есть атрибуты для обработчиков, так и в коде javascript у элементов DOM мы можем получить свойства обработчиков, которые соответствуют атрибутам:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <style> #rect{ width:50px; height:50px; background-color:blue; } </style> </head> <body> <div id="rect"></div> <script> function handler(e){ alert(e.type); } document.getElementById("rect").onclick = handler; </script> </body> </html>
В итоге нам достаточно взять свойство и присвоить ему функцию, используемую в качестве обработчика. За счет
этого код html отделяется от кода javascript.
Стоит также отметить, что в обработчик события браузер автоматически передает объект Event, хранящий всю информацию о событии. Поэтому
также мы можем получить этот объект в функции обработчика в качестве параметра.
Слушатели событий
Несмотря на то, что свойства обработчиков решают ряд проблем, которые связаны с использованием атрибутов, в то же время это также
не оптимальный подход. Еще один способ установки обработчиков событий представляет использование слушателей.
Для работы со слушателями событий в JavaScript есть объект EventTarget, который определяет методы
addEventListener() (для добавления слушателя) и removeEventListener()
для удаления слушателя. И поскольку html-элементы DOM тоже являются объектами EventTarget, то они также имеют эти методы. Фактически слушатели представляют те же функции обработчиков.
Метод принимает два параметра: название события без префикса on и функцию обработчика этого события. Например:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <style> #rect{ width:50px; height:50px; background-color:blue; } </style> </head> <body> <div id="rect"></div> <script> var rect = document.getElementById("rect"); rect.addEventListener("click", function (e) { alert(e.type); }); </script> </body> </html>
То есть в данном случае опять же обрабатывается событие click. И также можно было бы в качестве второго параметра название функции:
function handler(e){ alert(e.type); } var rect = document.getElementById("rect"); rect.addEventListener("click", handler);
Удаление слушателя аналогично добавлению:
rect.removeEventListener("click", handler);
Преимуществом использования слушателей является и то, что мы можем установить для одного события несколько функций:
var clicks = 0; function handlerOne(e){ alert(e.type); } function handlerTwo(e){ clicks++; var newNode = document.createElement("p"); newNode.textContent = "произошло нажатие " + clicks; document.body.appendChild(newNode); } var rect = document.getElementById("rect"); // прикрепляем первый обработчик rect.addEventListener("click", handlerOne); // прикрепляем второй обработчик rect.addEventListener("click", handlerTwo);
НазадВперед
Элементы, связанные с событием
Чаще всего нужно узнать, на каком элементе сработало событие.
Например, мы поймали на внешнем ‘е и хотим знать, на каком из внутренних элементов оно на самом деле произошло.
В Internet Explorer у объекта для этого есть свойство , в остальных браузерах, работающих по рекомендациям W3C, для этого используется .
Вот пример использования этого свойства. Обработчик стоит только на внешнем диве, но благодаря выводит по клику класс исходного элемента.
1
2
3
Ссылка
<div class="d1" onclick="*!*t=event.target||event.srcElement; alert(t.className)*/!*" > <span class="number">1</span> <div class="d2"> <span class="number">2</span> <div class="d3"> <span class="number">3</span> </div> <a class="d2a" href="javascript:void(0)">Ссылка</a> </div> </div>
Javascript-обработчик в примере висит только на внешнем диве и выглядит примерно так:
function(event) { // получить объект событие. // вместо event лучше писать window.event event = event || window.event // кросс-браузерно получить target var t = event.target || event.srcElement alert(t.className) }
Для событий и предусмотрен способ получить как элемент на который курсор мыши перешел, так и элемент, с которого он перешел.
Эти свойства — в W3C, и в Internet Explorer.
// Обработчик для mouseover function mouseoverHandler(event) { event = event || window.event var relatedTarget = event.relatedTarget || event.fromElement // для mouseover // relatedTarget - элемент, *!*с которого*/!* пришел курсор мыши } // Обработчик для mouseout function mouseoutHandler(event) { event = event || window.event var relTarg = event.relatedTarget || event.toElement // для mouseout // relatedTarget - элемент, *!*на который*/!* перешел курсор мыши }
Свойство дополняет . В нем всегда находится информация о втором элементе, участвовавшем в событии.
Поэтому его можно получить для IE, взяв то свойство из , которое не равно :
if (!e.relatedTarget && e.fromElement) { e.relatedTarget = (e.fromElement==e.target) ? e.toElement : e.fromElement }
При всплытии — событие по очереди вызвает обработчики на элементе-триггере и дальше, вверх по документу.
По мере всплытия, текущим элементом каждый раз становится новый. Иначе говоря. текущий элемент — это тот, к которому в данный момент «доплыло» событие.
Стандартный способ получить текущий элемент — использовать переменную .
Например, при клике на внутренний , код в этом примере последовательно отмечает элементы, на которых регистрируется всплывающее событие:
1
2
3
<div class="d1" onclick="highlightMe(this)">1 <div class="d2" onclick="highlightMe(this)">2 <div class="d3" onclick="highlightMe(this)">3</div> </div> </div>
Координаты мыши: 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:
Мульти-тач
Одной из функций, которую абсолютно не поддерживают события мыши, является мульти-тач: возможность касаться сразу нескольких мест на телефоне или планшете или выполнять специальные жесты.
События указателя позволяют обрабатывать мульти-тач с помощью свойств и .
Вот что происходит, когда пользователь касается сенсорного экрана в одном месте, а затем в другом:
- При касании первым пальцем:
- При касании втором и последующими пальцами (при остающемся первом):
Обратите внимание: присваивается не на всё устройство, а для каждого касающегося пальца. Если коснуться экрана 5 пальцами одновременно, получим 5 событий , каждое со своими координатами и индивидуальным
События, связанные с первым пальцем, всегда содержат свойство .
Мы можем отслеживать несколько касающихся экрана пальцев, используя их . Когда пользовтаель перемещает, а затем убирает палец, получаем события и с тем же , что и при событии .
Вот небольшое демо, выводящее события и :
Обратите внимание: чтобы увидеть разницу в , вам нужно использовать устройство с сенсорным экраном, такое как телефон или планшет. Для устройств без поддержки мульти-тач, таких как мышь, всегда будет один и тот же со свойством , для всех событий указателя
Событие: 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 будет работать и для мыши и для устройств с сенсорным экраном.
Краткая история
Сделаем небольшой обзор, чтобы вы поняли общую картину и место событий указателя среди других типов событий.
-
Давным-давно, в прошлом, существовали только события мыши
Затем получили широкое распространение сенсорные устройства, в частности телефоны и планшеты. Чтобы скрипты корректно работали, они генерировали (и до сих пор генерируют) события мыши. Например, касание сенсорного экрана генерирует событие . Таким образом, сенсорные устройства позволяли работать с существующими веб-страницами.
Но сенсорные устройства во многих аспектах мощнее, чем мышь. Например, они позволяют касаться экрана сразу в нескольких местах («мульти-тач»). Однако, события мыши не имеют необходимых свойств для обработки таких прикосновений.
-
Поэтому появились события касания (Touch events), такие как , , , которые имеют специфичные для касаний свойства (мы не будем здесь рассматривать их подробно, потому что события указателя ещё лучше).
Но и этих событий оказалось недостаточно, так как существует много других устройств, таких как перо, у которых есть свои особенности. Кроме того, универсальный код, который отслеживал бы и события касаний и события мыши, неудобно писать.
-
Для решения этих задач был внедрён стандарт Pointer Events («События Указателя»). Он предоставляет единый набор событий для всех типов указывающих устройств.
К настоящему времени спецификация Pointer Events Level 2 поддерживается всеми основными браузерами, а Pointer Events Level 3 находится в разработке и почти полностью совместима с Pointer Events Level 2.
Если вы не разрабатываете под старые браузеры, такие как Internet Explorer 10, Safari 12, или более ранние версии, больше нет необходимости использовать события мыши или касаний – можно переходить сразу на события указателя.
При этом ваш код будет корретно работать и с сенсорными устройствами и с мышью. Впрочем, у событий указателя есть важные особенности, которые нужно знать, чтобы их правильно использовать, без лишних сюрпризов. Мы отметим их в этой статье.
JS Tutorial
JS HOMEJS IntroductionJS Where ToJS OutputJS StatementsJS SyntaxJS CommentsJS VariablesJS OperatorsJS ArithmeticJS AssignmentJS Data TypesJS FunctionsJS ObjectsJS EventsJS StringsJS String MethodsJS NumbersJS Number MethodsJS ArraysJS Array MethodsJS Array SortJS Array IterationJS DatesJS Date FormatsJS Date Get MethodsJS Date Set MethodsJS MathJS RandomJS BooleansJS ComparisonsJS ConditionsJS SwitchJS Loop ForJS Loop WhileJS BreakJS Type ConversionJS BitwiseJS RegExpJS ErrorsJS ScopeJS HoistingJS Strict ModeJS this KeywordJS LetJS ConstJS Arrow FunctionJS ClassesJS DebuggingJS Style GuideJS Best PracticesJS MistakesJS PerformanceJS Reserved WordsJS VersionsJS 2009 (ES5)JS 2015 (ES6)JS 2016JS 2017JS JSON
addEventListener
Фундаментальный недостаток описанных выше способов назначения обработчика –- невозможность повесить несколько обработчиков на одно событие.
Например, одна часть кода хочет при клике на кнопку делать её подсвеченной, а другая – выдавать сообщение.
Мы хотим назначить два обработчика для этого. Но новое DOM-свойство перезапишет предыдущее:
Разработчики стандартов достаточно давно это поняли и предложили альтернативный способ назначения обработчиков при помощи специальных методов и . Они свободны от указанного недостатка.
Синтаксис добавления обработчика:
- Имя события, например .
- Ссылка на функцию-обработчик.
- Дополнительный объект со свойствами:
- : если , тогда обработчик будет автоматически удалён после выполнения.
- : фаза, на которой должен сработать обработчик, подробнее об этом будет рассказано в главе Всплытие и погружение. Так исторически сложилось, что может быть , это то же самое, что .
- : если , то указывает, что обработчик никогда не вызовет , подробнее об этом будет рассказано в главе Действия браузера по умолчанию.
Для удаления обработчика следует использовать :
Удаление требует именно ту же функцию
Для удаления нужно передать именно ту функцию-обработчик которая была назначена.
Вот так не сработает:
Обработчик не будет удалён, т.к
в передана не та же функция, а другая, с одинаковым кодом, но это не важно
Вот так правильно:
Обратим внимание – если функцию обработчик не сохранить где-либо, мы не сможем её удалить. Нет метода, который позволяет получить из элемента обработчики событий, назначенные через
Метод позволяет добавлять несколько обработчиков на одно событие одного элемента, например:
Как видно из примера выше, можно одновременно назначать обработчики и через DOM-свойство и через . Однако, во избежание путаницы, рекомендуется выбрать один способ.
Обработчики некоторых событий можно назначать только через
Существуют события, которые нельзя назначить через DOM-свойство, но можно через .
Например, таково событие , которое срабатывает, когда завершена загрузка и построение DOM документа.
Так что более универсален. Хотя заметим, что таких событий меньшинство, это скорее исключение, чем правило.
event.preventDefault()
Для новых, пользовательских событий браузерных действий, конечно, нет, но код, который генерирует такое событие, может предусматривать какие-то свои действия после события.
Вызов является возможностью для обработчика события сообщить в сгенерировавший событие код, что эти действия надо отменить.
Тогда вызов возвратит . И код, сгенерировавший событие, узнает, что продолжать не нужно.
Посмотрим практический пример – прячущегося кролика (могло бы быть скрывающееся меню или что-то ещё).
Ниже вы можете видеть кролика и функцию , которая при вызове генерирует на нём событие , уведомляя всех интересующихся, что кролик собирается спрятаться.
Любой обработчик может узнать об этом, подписавшись на событие через и, при желании, отменить действие по умолчанию через . Тогда кролик не исчезнет:
Обратите внимание: событие должно содержать флаг. Иначе, вызов будет проигнорирован
Может ли onclick быть атрибутом!?
onclick <button оnclick=»alert(‘Данный Onclick повесим прямо на тег…’)»>Onclick прямо в теге!</button>
Вопрос заключается откуда вы смотрите! Если вы смотрите из HTML — то onclick — это атрибут, но если вы смотрите из javascript — то onclick — это событие!
Вас может еще заинтересовать список тем : #JS | #JS_EVENTS | #CLICK | Последняя дата редактирования : 2020-11-28 14:19
//dwweb.ru/comments_1_5/include/img/hand_no_foto.png
no
no
01/08/2020 10:52 Darya …Пожаловаться
?
По умолчанию, текст при блокировке:
Комментарий заблокирован администратором сайта
Для изменения текста блокировки введите новый текст ниже:
Заблокировать
А можно сделать клик без onclick?
Ответить
02/08/2020 12:22 Марат…Пожаловаться
?
По умолчанию, текст при блокировке:
Комментарий заблокирован администратором сайта
Для изменения текста блокировки введите новый текст ниже:
Заблокировать
Никогда не задавался такой целью, сделать «клик без onclick»!Как мне кажется, «onclick» и придумали, чтобы отследить нажатие по элементу.
Ответить
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-ую фазу («фазу цели»: событие достигло элемента) нельзя обработать отдельно, при её достижении вызываются все обработчики: и на всплытие, и на погружение. Давайте посмотрим и всплытие и погружение в действии:
Давайте посмотрим и всплытие и погружение в действии:
Здесь обработчики навешиваются на каждый элемент в документе, чтобы увидеть в каком порядке они вызываются по мере прохода события.
Если вы кликните по , то последовательность следующая:
- → → → (фаза погружения, первый обработчик)
- (фаза цели, срабатывают обработчики, установленные и на погружение и на всплытие, так что выведется два раза)
- → → → (фаза всплытия, второй обработчик)
Существует свойство , содержащее номер фазы, на которой событие было поймано. Но оно используется редко, мы обычно и так знаем об этом в обработчике.
Чтобы убрать обработчик , нужна та же фаза
Если мы добавили обработчик вот так , то мы должны передать то же значение аргумента в , когда снимаем обработчик.
На каждой фазе разные обработчики на одном элементе срабатывают в порядке назначения
Если у нас несколько обработчиков одного события, назначенных на один элемент, в рамках одной фазы, то их порядок срабатывания – тот же, в котором они установлены:
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:
|
После получения события обычно интересно узнать, какая кнопка была нажата. Если, конечно, это не событие , с которым все и так понятно
Для этого в объекте есть два свойства: и , которые содержат числовые значения, соответствующие нажатой кнопке. К сожалению, тут есть некоторые несовместимости.
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 }
Вот универсальный тестовый стенд по определению клавиш. Выбирайте любую мышь и жмите кнопу из любого браузера — ниже появятся названия событий и значения .
Итого
При наступлении события – самый глубоко вложенный элемент, на котором оно произошло, помечается как «целевой» ().
- Затем событие сначала двигается вниз от корня документа к , по пути вызывая обработчики, поставленные через , где – это сокращение для .
- Далее обработчики вызываются на целевом элементе.
- Далее событие двигается от вверх к корню документа, по пути вызывая обработчики, поставленные через и без третьего аргумента или с третьим аргументом равным .
Каждый обработчик имеет доступ к свойствам события :
- – самый глубокий элемент, на котором произошло событие.
- (=) – элемент, на котором в данный момент сработал обработчик (тот, на котором «висит» конкретный обработчик)
- – на какой фазе он сработал (погружение=1, фаза цели=2, всплытие=3).
Любой обработчик может остановить событие вызовом , но делать это не рекомендуется, так как в дальнейшем это событие может понадобиться, иногда для самых неожиданных вещей.
В современной разработке стадия погружения используется очень редко, обычно события обрабатываются во время всплытия. И в этом есть логика.
В реальном мире, когда происходит чрезвычайная ситуация, местные службы реагируют первыми. Они знают лучше всех местность, в которой это произошло, и другие детали. Вышестоящие инстанции подключаются уже после этого и при необходимости.
Тоже самое справедливо для обработчиков событий. Код, который «навесил» обработчик на конкретный элемент, знает максимум деталей об элементе и его предназначении. Например, обработчик на определённом скорее всего подходит только для этого конкретного , он знает все о нём, поэтому он должен отработать первым. Далее имеет смысл передать обработку события родителю – он тоже понимает, что происходит, но уже менее детально, далее – выше, и так далее, до самого объекта , обработчик на котором реализовывает самую общую функциональность уровня документа.
Всплытие и погружение являются основой для «делегирования событий» – очень мощного приёма обработки событий. Его мы изучим в следующей главе.