How to add click event to an element?
I would like to add a click event in plain JavaScript (without using jQuery) to an element like this, so I don’t have an id but a class:
4 Answers 4
If you don’t have an id and don’t have any selector library and you want it to work in older browsers, then it takes a bit more work. If you can put an id on it, it’s quite simple. If not, it takes more code:
Since getElementsByClassName is not universally available in older browsers, you would need a shim to implement it when not present. Or, you could get all the links in your document with:
and then cycle through that list until you find the one you want (perhaps checking the class name).
If you can put an ID on the link:
Then, it just takes this code:
If you’re going to do this regularly, the adding an event listener is a little more extensible than using the onclick property, but if you don’t have any framework, then you need a function for adding an event listener that handles older versions of IE.
Выразительный JavaScript: Обработка событий
Некоторые программы работают с вводом пользователя, мышью и клавиатурой. Время возникновения такого ввода и последовательность данных нельзя предсказать заранее. Это требует иного подхода к контролю над порядком выполнения программы, чем уже привычный нам.
Обработчики событий
Представьте интерфейс, в котором единственным способом узнать, нажали ли на кнопку клавиатуры, было бы считывание текущего состояния кнопки. Чтобы реагировать на нажатия, вам пришлось бы постоянно считывать состояния кнопок, чтобы вы могли поймать это состояние, пока кнопка не отжалась. Было бы опасно проводить другие подсчёты, отнимающие процессорное время, так как можно было бы пропустить момент нажатия.
Таким образом ввод обрабатывался на примитивных устройствах. Шагом вперёд было бы, если железо или операционка замечали бы нажатие кнопки и передавали бы его в очередь. Затем программа периодически могла бы проверять очередь на новые события и реагировать на то, что находится в очереди.
Разумеется, она должна помнить о проверке, и делать это достаточно часто, потому что наличие длительного промежутка времени между нажатием кнопки и тем, когда программа замечает и реагирует на это, ведёт к восприятию этой программы как медленно работающей. Такой подход называется опросом. Большинство программистов по возможности избегают его. Такой подход используется достаточно редко.
Вариант получше – некая промежуточная система, которая позволяет коду реагировать на события в момент их возникновения. Браузеры позволяют это делать путём регистрации функций как обработчиков заданных событий.
Функция addEventListener регистрирует свой второй аргумент как функцию, которая вызывается, когда описанное в первом аргументе событие случается.
События и узлы DOM
Каждый обработчик событий браузера зарегистрирован в контексте. Когда вы вызываете addEventListener, вы вызываете её как метод целого окна, потому что в браузере глобальная область видимости – это объект window. У каждого элемента DOM есть свой метод addEventListener, позволяющий слушать события от этого элемента.
Пример назначает обработчик на DOM-узел кнопки. Нажатия на кнопку запускают обработчик, а нажатия на другие части документа – не запускают.
Присвоение узлу атрибута onclick работает похоже. Но у узла есть только один атрибут onclick, значит таким способом вы можете зарегистрировать только один обработчик. Метод addEventListener позволяет добавлять любое количество обработчиков, так что вы не замените случайно уже назначенный ранее обработчик.
Метод removeEventListener, вызванный с такими же аргументами, как addEventListener, удаляет обработчик.
Чтобы это провернуть, мы даём функции имя (в данном случае, once), чтобы её можно было передать и в addEventListener, и в removeEventListener.
Объекты событий
В примерах мы проигнорировали тот факт, что функциям-обработчикам передаётся аргумент – объект события. В нём хранится дополнительная информация о событии. К примеру, если надо узнать, какая кнопка мыши была нажата, мы можем обратиться к свойству which этого объекта.
Хранящаяся в объекте информация – разная для каждого типа событий. Мы обсудим эти типы позже. Свойство объекта type всегда содержит строку, описывающую событие (например, «click» или «mousedown»).
Распространение (propagation)
События, зарегистрированные на узлах, имеющих дочерние узлы, получат и некоторые события, случившиеся с их детьми. Если кликнуть на кнопку внутри параграфа, обработчики событий параграфа получат событие click.
Если и у параграфа и у кнопки есть обработчики, то первым запустится более конкретный – то есть, обработчик кнопки. Событие как бы распространяется наружу, от узла, где оно случилось, до его родительского и далее до корня документа. После отработки всех обработчиков всех промежуточных узлов, очередь среагировать на событие доходит и до самого окна.
В любой момент обработчик может вызвать метод stopPropagation объекта события, чтобы «высшие» узлы не получили его. Это может быть полезным, когда у вас есть кнопка внутри другого кликабельного элемента, и вы не хотите, чтобы клики по кнопке активировали поведение внешнего элемента.
Следующий пример регистрирует обработчики «mousedown» как на кнопке, так и на окружающем параграфе. При щелчке правой кнопкой обработчик кнопки вызывает stopPropagation, который предотвращает запуск обработчика параграфа. При клике другой кнопкой запускаются оба обработчика.
У большинства объектов событий есть свойство target, ссылающееся на узел, который запустил обработку. Его можно использовать для проверки того, что вы не обрабатываете что-то, пришедшее с ненужного вам узла.
Также возможно использовать свойство target, чтобы распространить обработку конкретного типа события. К примеру, если у вас есть узел, содержащий длинный список кнопок, было бы удобнее зарегистрировать один обработчик событий для узла, и в нём выяснять, нажали ли на кнопку – вместо того, чтобы регистрировать обработчики каждой кнопки по отдельности.
Действия по умолчанию
У многих событий есть действия по умолчанию. При клике на ссылку вы перейдёте по ней. При нажатии на стрелку вниз браузер прокрутит страницу вниз. По правому клику мыши вы увидите контекстное меню. И так далее.
Для большинства типов событий обработчики событий вызываются до того, как сработает действие по умолчанию. Если обработчик не хочет, чтобы это действие происходило (часто потому, что он уже обработал его), он может вызвать метод preventDefault объекта события.
Это можно использовать для создания своих горячих клавиш или контекстного меню. Также это можно использовать для слома привычного пользователю интерфейса. К примеру, вот ссылка, по которой нельзя пройти.
Не делайте так – если у вас нет очень серьёзной причины! Пользователям вашей страницы будет очень неудобно, когда они столкнутся с неожиданными результатами своих действий. В зависимости от браузера, некоторые события перехватить нельзя. В Chrome нельзя обрабатывать горячие клавиши закрытия текущей закладки (Ctrl-W or Command-W).
События от кнопок клавиатуры
При нажатии кнопки на клавиатуре браузер запускает событие «keydown». Когда она отпускается, происходит событие «keyup».
Несмотря на название, «keydown» происходит не только тогда, когда на кнопку нажимают. Если нажать и удерживать кнопку, событие будет происходить каждый раз по приходу повторного сигнала от клавиши (key repeat). Если вам, к примеру, надо увеличивать ускорение игрового персонажа, когда нажата кнопка со стрелкой, и уменьшать его, когда она отпущена – надо быть осторожным, чтобы не увеличивать ускорение каждый раз при повторе сигнала от кнопки, иначе скорость возрастёт очень сильно.
В примере упомянуто свойство keyCode объекта события. Так вы можете узнать, какая именно кнопка нажата или отпущена. К сожалению, не всегда очевидно, как преобразовать числовые коды в нужную кнопку.
Для цифр и букв код будет кодом символа Unicode, связанного с прописным символом, изображённым на кнопке. Метод строки charCodeAt даёт нам этот код.
У других кнопок коды менее предсказуемы. Лучший способ их выяснить – экспериментальный. Зарегистрировать обработчик, который записывает коды клавиш, и нажать нужную кнопку.
Кнопки-модификаторы типа Shift, Ctrl, Alt, и Meta (Command на Mac) создают события, как и нормальные кнопки. Но при разборе комбинаций клавиш можно выяснить, были ли нажаты модификаторы, через свойства shiftKey, ctrlKey, altKey, и metaKey событий клавиатуры и мыши.
События «keydown» и «keyup» дают информацию о физическом нажатии кнопок. А если вам нужно узнать, какой текст вводит пользователь? Создавать его из нажатий кнопок – неудобно. Для этого существует событие «keypress», происходящее сразу после «keydown» (и повторяющееся вместе с «keydown», если клавишу продолжают удерживать), но только для тех кнопок, которые выдают символы. Свойство объекта события charCode содержит код, который можно интерпретировать как код Unicode. Мы можем использовать функцию String.fromCharCode для превращения кода в строку из одного символа.
Источником события нажатия клавиши узел становится в зависимости от того, где находился фокус ввода во время нажатия. Обычные узлы не могут получить фокус ввода (если только вы не задали им атрибут tabindex), а такие, как ссылки, кнопки и поля форм – могут. Мы вернёся к полям ввода в главе 18. Когда ни у чего нет фокуса, в качестве целевого узла событий работает «document.body».
Щелчки мышью
Нажатие кнопки мыши тоже запускает несколько событий. События «mousedown» и «mouseup» похожи на «keydown» и «keyup», и запускаются, когда кнопка нажата и когда отпущена. События происходят у тех узлов DOM, над которыми находился курсор мыши.
После события «mouseup» на узле, на который пришлись и нажатие, и отпускание кнопки, запускается событие “click”. Например, если я нажал кнопку над одним параграфом, потом передвинул мышь на другой параграф и отпустил кнопку, событие “click” случится у элемента, который содержал в себе оба эти параграфа.
Если два щелчка происходят достаточно быстро друг за другом, запускается событие «dblclick» (double-click), сразу после второго запуска “click”.
Для получения точных координат места, где произошло событие мыши, обратитесь к свойствам pageX и pageY – они содержат координаты в пикселях относительно верхнего левого угла документа.
В примере создана примитивная программа для рисования. Каждый раз по клику на документе он добавляет точку под вашим курсором. В главе 19 будет представлена менее примитивная программа для рисования.
Свойства clientX и clientY похожи на pageX и pageY, но дают координаты относительно части документа, которая видна сейчас (если документ был прокручен). Это удобно при сравнении координат мыши с координатами, которые возвращает getBoundingClientRect – его возврат тоже связан с относительными координатами видимой части документа.
Движение мыши
Каждый раз при сдвиге курсора мыши запускается событие «mousemove». Его можно использовать для отслеживания позиции мыши. Обычно это нужно при создании некоей функциональности, связанной с перетаскиванием объектов мышью.
К примеру, следующая программа отображает полоску и устанавливает обработку событий так, что движение влево и вправо уменьшает или увеличивает её ширину.
Обратите внимание – обработчик «mousemove» зарегистрирован у всего окна. Даже если мышь уходит за пределы полоски, нам надо обновлять её размер и прекращать это, когда кнопку отпускают.
Когда курсор попадает на узел и уходит с него, происходят события «mouseover» или «mouseout». Их можно использовать, кроме прочего, для создания эффектов проведения мыши, показывая или меняя стиль чего-либо, когда курсор находится над этим элементом.
К сожалению, создание такого эффекта не ограничивается запуском его при событии «mouseover» и завершением при событии «mouseout». При движении мыши от узла к его дочерним узлам на родительском узле происходит событие «mouseout», хотя мышь, вообще говоря, его и не покидала. Что ещё хуже, эти события распространяются как и все другие, поэтому вы всё равно получаете «mouseout» при уходе курсора с одного их дочерних узлов того узла, где вы зарегистрировали обработчик.
Для обхода проблемы можно использовать свойство relatedTarget объекта событий. Он сообщает, на каком узле была до этого мышь при возникновении события «mouseover», и на какой элемент она переходит при событии «mouseout». Нам надо менять эффект, только когда relatedTarget находится вне нашего целевого узла. Только в этом случае событие на самом деле представляет собой переход на наш узел (или уход с узла).
Функция isInside перебирает всех предков узла, пока не доходит до верха документа (и тогда узел равен null), или же не находит заданного ей родителя.
Должен добавить, что такой эффект достижим гораздо проще через псевдоселектор CSS под названием :hover, как показано ниже. Но когда при наведении вам надо делать что-то более сложное, чем изменение стиля узла, придётся использовать трюк с событиями «mouseover» и «mouseout».
События прокрутки
Когда элемент прокручивается, запускается событие «scroll». Это используется во многих случаях, например чтобы узнать, на что сейчас пользователь смотрит (чтобы останавливать анимацию, не попавшую на экран, или отправлять секретные шпионские донесения в ваш злодейский штаб), или визуально демонстрировать прогресс (подсвечивая часть содержания или показывая номер страницы).
В примере в правом верхнем углу документа создаётся индикатор процесса, который заполняется по мере прокрутки элемента вниз.
Позиция элемента fixed означает почти то же, что absolute, но ещё и предотвращает прокручивание элемента вместе с остальным документом. Смысл в том, чтобы оставить наш индикатор в углу. Внутри него находится другой элемент, который изменяет размер, отражая текущий прогресс. Мы используем проценты вместо px для задания ширины, чтобы размер элемента изменялся относительно размера всего индикатора.
Глобальная переменная innerHeight даёт высоту окна, которую надо вычесть из полной высоты прокручиваемого элемента – при достижении конца элемента прокрутка заканчивается. (Также в дополнение к innerHeight есть переменная innerWidth). Поделив текущую позицию прокрутки pageYOffset на максимальную позицию прокрутки, и умножив на 100, мы получили процент для индикатора.
Вызов preventDefault не предотвращает прокрутку. Обработчик события вызывается уже после того, как прокрутка случилась.
События, связанные с фокусом
При получении элементом фокуса браузер запускает событие “focus”. Когда он теряет фокус, запускается событие “blur”.
В отличие от предыдущих событий, эти два не распространяются. Обработчик родительского узла не уведомляется о получении или утрате фокуса дочерним элементом.
Следующий пример демонстрирует текст подсказки для того текстового поля, у которого в данный момент фокус.
Объект window получает события focus и blur, когда пользователь выделяет или убирает фокус с закладки браузера или окна браузера, в котором показан документ.
Событие загрузки
Когда заканчивается загрузка страницы, на объектах window и body запускается событие “load”. Это часто используется для планирования инициализирующих действий, которым необходим полностью построенный документ. Вспомните, что содержимое тегов <script> запускается сразу, как только тег встречается. Иногда это слишком рано – например, когда скрипту нужно что-то сделать с теми частями документа, которые находятся после тега <script>.
У элементов типа картинок или тегов скрипта, которые загружают внешний файл, тоже есть событие “load”, которое показывает, что файл загружен. Как и события фокуса, события загрузки не распространяются.
Когда страница закрывается или с неё уходят (например, по ссылке), запускается событие «beforeunload». Основная цель – защитить пользователя от случайной потери данных при закрытии документа. Предотвращение закрытия страницы не производится, как вы могли подумать, при помощи preventDefault. Вместо этого используется возврат строки из обработчика. Строка будет использована в диалоге, который спрашивает пользователя, хочет ли он остаться на странице или покинуть её. Этот механизм гарантирует, что пользователь может покинуть страницу, даже если на ней работает зловредный скрипт, который бы хотел не отпускать пользователя, а вместо этого показывал бы ему мошенническую рекламу по снижению веса.
График выполнения скрипта
Несколько вещей могут привести к старту скрипта. Чтение тега <script> — одна из них. Запуск события – ещё одна. В главе 13 обсуждается функция requestAnimationFrame, которая планирует запуск функции перед следующей перерисовкой страницы. Это ещё один способ запустить скрипт.
Важно понять, что хотя события и запускаются в любой момент, два разных скрипта одновременно работать не могут. Если скрипт работает, обработчики событий и запланированные другим способом куски кода будут ждать своей очереди. Поэтому документ подвисает, когда скрипт работает слишком долго. Браузер не обрабатывает щелчки и другие события внутри документа потому, что он не может запустить обработчики событий, пока работает текущий скрипт.
В некоторых программных окружениях можно запускать несколько потоков одновременно. Можно сделать программу быстрее, если выполнять несколько вещей одновременно. Но когда несколько действующих лиц трогают одни и те же части системы в одно и то же время, продумывать программу становится на порядок сложнее.
То, что программы JavaScript делают по одной вещи за раз, облегчает нашу жизнь. Если вам очень надо сделать в фоне что-то тяжёлое, не подвешивая при этом страницу, браузеры предоставляют штуку под названием «сетевые рабочие» (web worker) – изолированное окружение JavaScript, работающее вместе с главной программой над документом, которое может общаться с ней только посредством сообщений.
Предположим, у нас есть следующий код в файле code/squareworker.js:
Представьте, что возведение в квадрат – очень тяжёлое, долго работающее вычисление, которое нам надо запустить фоновым потоком. Такой код порождает «рабочего», отправляет ему несколько сообщений, и выводит результаты.
Функция postMessage отправляет сообщение, которое запускает событие “message” у принимающей стороны. Скрипт, создавший рабочего, отправляет и получает сообщения через объект Worker, тогда как рабочий общается со скриптом, создавшим его, отправляя и получая сообщения через его собственное глобальное окружение – которое является отдельным окружением, не связанным с оригинальным скриптом.
Установка таймеров
Функция setTimeout схожа с requestAnimationFrame. Она планирует запуск другой функции в будущем. Но вместо вызова функции при следующей перерисовке страницы, она ждёт заданное в миллисекундах время. Эта страница через две секунды превращается из синей в жёлтую:
Иногда вам надо отменить запланированную функцию. Это можно сделать, сохранив значение, возвращаемое setTimeout, и затем вызвав с ним clearTimeout.
Функция cancelAnimationFrame работает так же, как clearTimeout – вызов её со значением, возвращённым requestAnimationFrame, отменит этот кадр (если он уже не был вызван).
Похожий набор функций, setInterval и clearInterval используется для установки таймеров, которые будут повторяться каждые X миллисекунд.
Устранение помех (debouncing)
У некоторых событий есть возможность выполняться быстро и много раз подряд (например, «mousemove» и «scroll»). При обработке таких событий надо быть осторожным и не делать ничего «тяжёлого», или ваш обработчик займёт столько времени на выполнение, что взаимодействие с документом будет медленным и прерывистым.
Если в таком обработчике надо сделать что-то нетривиальное, можно использовать setTimeout, чтобы гарантировать, что вы делаете это не слишком часто. Это обычно называют «устранением помех» в событии. К этому существует несколько слегка различающихся подходов.
В первом примере надо сделать что-то, когда пользователь печатает, но не надо делать это сразу после запуска каждого события нажатия на клавиши. Когда они быстро печатают, нам надо подождать, когда возникнет пауза. Вместо немедленного выполнения действия в обработчике, мы устанавливаем таймаут. Также мы очищаем предыдущий таймаут, если он был, так что если события близко одно от другого (ближе, чем задержка таймера), предыдущее событие будет отменено.
Если задать undefined для clearTimeout, или вызвать его с таймаутом, который уже произошёл, то ничего не произойдёт. Таким образом, не надо осторожничать при его вызове, и мы просто поступаем так для каждого события.
Можно использовать немного другой подход, если нам надо разделить ответы минимальными промежутками времени, но при этом запускать их в то время, когда происходят события, а не после. К примеру, надо реагировать на события «mousemove», показывая текущие координаты мыши, но только каждые 250 миллисекунд.
Обработчики событий позволяют обнаруживать и реагировать на события, над которыми мы не властны. Для их регистрации используется метод addEventListener.
У событий есть определяющий их тип («keydown», «focus», и так далее). Большинство событий вызываются конкретными узлами DOM, и затем распространяются на их предков, позволяя связанными с ними обработчикам обрабатывать их.
При вызове обработчика ему передаётся объект события с дополнительной информацией о событии. У объекта также есть методы, позволяющие остановить дальнейшее распространение (stopPropagation) и предотвратить обработку события браузером по умолчанию (preventDefault).
Нажатия на клавиши запускают события «keydown», «keypress» и «keyup». Нажатия на кнопки мыши запускают события «mousedown», «mouseup» и «click». Движения мыши запускают события «mousemove», и возможно «mouseenter» и «mouseout».
Прокрутку можно обнаружить через событие “scroll”, а изменения фокуса через события «focus» и «blur». Когда заканчивается загрузка документа, у объекта window запускается событие “load”.
В одно и то же время может работать один участок программы. Поэтому обработчики событий и другие запланированные скрипты будут ждать окончания работы текущих.
Упражнения
Цензура клавиатуры
В промежутке с 1928 по 2013 год турецкие законы запрещали использование букв Q, W и X в официальных документах. Это являлось частью общей инициативы подавления курдской культуры – эти буквы используются в языке курдов, но не у турков.
В качестве упражнения на тему странного использования технологий, я прошу вас запрограммировать поле для ввода текста так, чтобы эти буквы нельзя было туда вписать. Насчет копирования и вставки и других подобных возможных обходов правила не беспокойтесь.
След мыши
В ранние дни JavaScript, когда было время кричащих домашних страниц с обилием анимированных картинок, люди использовали язык очень вдохновляющими способами. Одним из них был «след мыши» — серия картинок, которые следовали за курсором при его движении по странице.
Я хочу, что бы вы в упражнении сделали такой след. Используйте <div> с абсолютным позиционированием, фиксированным размером и цветом фона. Создайте кучку элементов и при движении мыши показывайте их следом за курсором.
К этому можно подойти многими способами. Можно сделать очень простое или очень сложное решение, как угодно. Простое – хранить фиксированное количество элементов и проходить по ним в цикле, двигая каждый следующий на текущее место курсора, каждый раз когда случается событие «mousemove».
Закладки
Интерфейс закладок встречается часто. Он позволяет вам выбирать панель интерфейса, выбирая одну из нескольких торчащих закладок над элементом.
В упражнении вам нужно сделать простой интерфейс закладок. Напишите функцию asTabs, которая принимает узел DOM, и создаёт закладочный интерфейс, показывая дочерние элементы этого узла. Ей нужно вставлять список элементов <button> вверху узла, по одному на каждый дочерний элемент, содержащих текст, полученный из атрибута data-tabname. Все, кроме одного из дочерних элементов, должны быть спрятаны (при помощи значения none свойства стиля display), а текущий видимый узел можно выбирать нажатием кнопки.
Когда оно заработает, расширьте функционал, чтобы у текущей активной кнопки был свой стиль.
click
Если у пользователя есть мышка, то он точно будет кликать курсором по странице.
Время чтения: меньше 5 мин
- Кратко
- Как пишется
- Как понять
- На практике
- Николай Лопин советует
Обновлено 27 июля 2022
Кратко
Событие клика на HTML-элементе. Когда пользователь кликает мышкой по странице, браузер определяет, на каком элементе произошёл клик и создаёт событие click .
На события можно подписаться и выполнять JavaScript-код, когда событие произошло.
Как пишется
Подписаться на все клики на странице:
Подписаться только на клики по кнопке (она должна быть на странице):
Как понять
Подробнее о механизме событий читайте в статье «События».
В функцию-обработчик так же передаётся объект события, который содержит дополнительную информацию о клике. Самые полезные свойства:
- detail — количество кликов, которые произвёл пользователь. 1 — для одиночного клика, 2 — для двойного и так далее.
- view — возвращает объект window , в котором произошло событие.
Чтобы получить доступ к объекту события, функция-обработчик должна принимать на вход параметр:
Пример, использующий эти свойства:
На практике
Николай Лопин советует
С кликами есть тонкость. Если пользователь нажал кнопку мыши, увёл курсор из элемента и потом кнопку отпустил, то события click не произойдёт.
Можно обработать клики по любым HTML элементам: <div> , <p> , <button> — браузеры это умеют.
Некоторые мобильные браузеры (например, Safari Mobile) создают события click только на интерактивных элементах — <button> , <a> , <img> , <input> и так далее.
JavaScript – Введение в события. Обработчик события
Событие – это определённый сигнал от браузера. Он сообщает нам о том, что что-то произошло.
Например: щелчок мыши, нажатие клавиши на клавиатуре, изменение размера области просмотра, завершение загрузки документа и т.д.
При этом сигнал всегда связан с объектом . Подавать сигналы могут различные объекты: window , document , DOM-элементы и т.д.
Список некоторых событий и их название:
- DOMContentLoaded – завершение загрузки DOM;
- click – клик (нажатие левой кнопки мыши, на устройствах с сенсорным управлением возникает при касании);
- keydown – нажатие клавиши на клавиатуре;
- resize – изменение размеров документа;
- change – окончание изменения значения в поле ввода.
Обработчик события
Зачем нам события? Они нам нужны для того, чтобы мы могли реагировать на них , или другими словами выполнять определённые действия, когда они произойдут.
В JavaScript это выполняется посредством привязывания некоторой функции к событию. После этого эта функция будет вызываться всякий раз, когда это событие на указанном элементе будет возникать. Эту функцию в JavaScript принято называть обработчиком события .
Следует отметить, что на странице постоянно возникает огромное количество событий, независимо от того назначили ли мы им обработчик или нет. Наша задача – это заставить наш сайт или приложение реагировать только на те события, которые нам небезразличны.
Способы задания событию обработчика
Назначить обработчик событию можно разными способами:
- через HTML-атрибут on{событие} (не является хорошей практикой);
- посредством свойства DOM-элемента on{событие} ;
- используя специальный метод addEventListener .
Инициализация обработчика через атрибут
Этот способ позволяет прописать обработчик напрямую в разметке. Выполняется это посредством указания JavaScript кода в атрибуте on{событие} . Вместо {событие} необходимо написать имя (тип) события (например: click ).
Пример, в котором назначим HTML-элементу button обработчик события click , используя атрибут:
Если код, который нужно поместить в атрибут достаточно большой, то в этом случае его лучше оформить в виде функции, а в атрибут поместить её вызов.
В этом примере мы указали в качестве обработчика функцию sum .
При этом задавать обработчик напрямую в разметке не является хорошей практикой, т.к. это приведёт к смешиванию JavaScript и HTML кода.
Добавление обработчика через свойство DOM объекта
Второй способ назначить обработчик — это использовать свойство on{событие} .
Например, привяжем обработчик события click к элементу (для этого события свойство будет onclick ):
В приведённом выше примере обработчик представляет собой анонимную функцию, которая будет выполняться всякий раз, когда это событие на указанном элементе будет происходить.
Другой вариант – это назначить уже существующую функцию.
Внутри обработчика можно обратиться к текущему элементу, т.е. к тому для которого в данный момент был вызван этот обработчик. Осуществляется это с помощью ключевого слова this .
Кстати, когда обработчик задаётся через атрибут, то браузер самостоятельно при чтении такого HTML создаёт из значения этого атрибута функцию и присваивает её одноименному свойству этого элемента.
Т.е., по сути, задание свойства через атрибут – это просто способ инициализации обработчика. Т.к. сам обработчик в этом случае тоже хранится в свойстве DOM-объекта.
Но установка обработчика через свойство имеет недостаток. С помощью него нельзя назначить одному событию несколько обработчиков. Если в коде создадим новый обработчик, то он перезапишет существующий:
Кстати, также не получится назначить несколько обработчиков, один через атрибут, а другой через свойство. Последний перепишет предыдущий.
Подписка на событие через addEventListener
Ещё один способ назначить событию обработчик — это использовать метод addEventListener .
- event — имя события (например, click );
- handler — функция, которая будет вызвана при возникновении этого события;;
- options (не обязательный) — объект, в котором можно задать дополнительные параметры.
В options можно задать:
- once — если true , то обработчик будет вызван всего один раз;
- capture — задаёт фазу, на которой нужно вызвать обработчик события (по умолчанию — на этапе всплытия); если нужно на этапе погружения (перехвата) — то этому ключу следует установить значение true ;
- passive — определяет следует ли вызывать preventDefault() ; если установить true — то обработчик никогда не вызовет этот метод.
Кроме этого, options можно установить true или false , в этом случае он будет просто определять фазу (всплытие или погружение).
В этом примере addEventListener прикреплен к объекту document . Когда событие click возникнет на этом элементе, будет вызвана функция changeBgColor .
Если мы откроем документ, содержащий этот код в браузере, то сначала увидим пустую страницу.
Однако при клике фон страницы изменится с белого на #3f51b5 .
Иногда возникают ситуации, когда нужно удалить обработчик . Это можно выполнить, используя removeEventListener :
Этот метод принимает аргументы тех же типов, что addEventListener .
При этом для того, чтобы удалить обработчик нам нужно указать точно такие же аргументы , которые мы использовали при его назначении.
Если обработчик — анонимная функция, то её удалить нельзя.
Как добавить несколько обработчиков к событию?
Метод addEventListener в отличие от предыдущих способов позволяет назначить одному событию несколько обработчиков:
Как правильно прикрепить обработчики к элементам?
Для прикрепления обработчиков к элементам, необходимо чтобы эти элементы на странице были доступны. Определить, когда они будут доступны с момента загрузки документам можно с помощью события DOMContentLoaded . Данное событие возникает на document когда DOM полностью построено:
Задачи
1. Скрыть элемент по нажатию кнопки с классом spoiler-trigger
Написать JavaScript код, который при нажатии на кнопку spoiler-trigger будет скрывать элемент, расположенный сразу за ней. При этом на странице таких кнопок может быть несколько.
Решение
2. Создать выпадающее меню
Имеется следующая разметка (стили добавлять не нужно, они имеются в примере):
Необходимо написать скрипт, который будет при нажатии на кнопку ( .dropdown__trigger ) переключался класс show у элемента .dropdown :
Решение