- Почему обработчик события не вызывается?
- Асинхронность. Почему не работает обработчик события?
- 2 ответа 2
- Введение в браузерные события
- Обработчики событий
- Использование атрибута HTML
- Использование свойства DOM-объекта
- Доступ к элементу через this
- Частые ошибки
- addEventListener
- Объект события
- Объект-обработчик: handleEvent
- Итого
- Введение в события
- Серия удачных событий
- Простой пример
- События не только для веб-страниц
- Способы использования веб-событий
- Свойства обработчика событий
- Встроенные обработчики событий — не используйте их
Почему обработчик события не вызывается?
Не вызывается обработчик события, зарегистрированный в своем модуле в файле ../install/index.php
тут все ок, он зарегистрировался, я так уже с другими делал)
Теперь в файле ../lib/Eventhandler.php
В итоге выходит ошибка :
Я так понимаю, что в функцию передается объект Bitrix\Sale\Order а не Bitrix\Main\Event
Я уже подключил все что можно, и все равно не понимаю в чем дело.
На самом деле я только только начал писать модуль и возможно много чего не понимаю еще, но вроде все было логично до этого момента.
В документации показано что должен передаваться Bitrix\Main\Event, а по факту передается Bitrix\Sale\Order.
- Вопрос задан более года назад
- 1654 просмотра
Пришлось потупить немного.
Если зарегистрируешь так событие, твой вариант будет ок работать
P.S. не забудь удалить свое событие из базы и почистить кеш
P.P.S. в доках на счет объекта \Bitrix\Main\Event $event все верно написано, просто замес старого и нового апи получился)) Таже херня получится между AddEventHandler и $eventManager->addEventHandler
Если интересно, я дальше покопался в чем же разница, расскажу на примере AddEventHandler и $eventManager->addEventHandler (условимся что $eventManager = \Bitrix\Main\EventManager::getInstance())
1. в AddEventHandler вызывается $eventManager->addEventHandlerCompatible
2. как в $eventManager->addEventHandlerCompatible так и в $eventManager->addEventHandler вызывается $this->addEventHandlerInternal где разница только в последнем параметре, который называется $version и равен 1 и 2 соответственно
3. дальше метод send —> sendToEventHandler и видим такую картину
Вот таким нехитрым способом битриксоиды закостылили переход от старой версии к новой))
Источник
Асинхронность. Почему не работает обработчик события?
Господа программисты. Прошу вашей помощи. Разбираюсь с асинхронным программированием и иногда возникают некоторые сложности. Вот есть такой класс:
и есть форма, где по нажатию кнопки запускается метод класса в асинхронном режиме:
Не знаю почему, но приложение намертво зависает. Причём, если не использовать асинхронность, а сделать типа такого:
то всё работает. Что мне исправить, но не убирая асинхронности?
2 ответа 2
Насколько я понимаю, у вас присутствует взаимная блокировка. Вот что у вас происходит в главном потоке:
- Сначала вызывается button1_Click()
- Затем в этом методе создается новый поток для асинхронного выполнения getsquare()
- Далее сразу же вызывается EndInvoke() , тем самым блокируя главный поток до тех пор, пока не будет выполнен getsquare()
Теперь, что происходит в новом потоке:
- Запускается выполнение getsquare()
- Затем дергается событие, на которое был подписан делегат из метода button1_Click()
- Далее в этом делегате вызывается Invoke() сигнализируя диспетчеру потоков о том, что в главном потоке необходимо выполнить некоторое действие.
- Блокируется в освобождении главного потока.
Однако главный поток не будет освобожден никогда, поскольку заблокирован в EndInvoke() . Решение проблемы: использовать Callback.
Источник
Введение в браузерные события
Событие – это сигнал от браузера о том, что что-то произошло. Все DOM-узлы подают такие сигналы (хотя события бывают и не только в DOM).
Вот список самых часто используемых DOM-событий, пока просто для ознакомления:
События мыши:
- click – происходит, когда кликнули на элемент левой кнопкой мыши (на устройствах с сенсорными экранами оно происходит при касании).
- contextmenu – происходит, когда кликнули на элемент правой кнопкой мыши.
- mouseover / mouseout – когда мышь наводится на / покидает элемент.
- mousedown / mouseup – когда нажали / отжали кнопку мыши на элементе.
- mousemove – при движении мыши.
События на элементах управления:
- submit – пользователь отправил форму .
- focus – пользователь фокусируется на элементе, например нажимает на .
Клавиатурные события:
- keydown и keyup – когда пользователь нажимает / отпускает клавишу.
События документа:
- DOMContentLoaded – когда HTML загружен и обработан, DOM документа полностью построен и доступен.
CSS events:
- transitionend – когда CSS-анимация завершена.
Существует множество других событий. Мы подробно разберём их в последующих главах.
Обработчики событий
Событию можно назначить обработчик, то есть функцию, которая сработает, как только событие произошло.
Именно благодаря обработчикам JavaScript-код может реагировать на действия пользователя.
Есть несколько способов назначить событию обработчик. Сейчас мы их рассмотрим, начиная с самого простого.
Использование атрибута HTML
Обработчик может быть назначен прямо в разметке, в атрибуте, который называется on .
Например, чтобы назначить обработчик события click на элементе input , можно использовать атрибут onclick , вот так:
При клике мышкой на кнопке выполнится код, указанный в атрибуте onclick .
Обратите внимание, для содержимого атрибута onclick используются одинарные кавычки, так как сам атрибут находится в двойных. Если мы забудем об этом и поставим двойные кавычки внутри атрибута, вот так: onclick=»alert(«Click!»)» , код не будет работать.
Атрибут HTML-тега – не самое удобное место для написания большого количества кода, поэтому лучше создать отдельную JavaScript-функцию и вызвать её там.
Следующий пример по клику запускает функцию countRabbits() :
Как мы помним, атрибут HTML-тега не чувствителен к регистру, поэтому ONCLICK будет работать так же, как onClick и onCLICK … Но, как правило, атрибуты пишут в нижнем регистре: onclick .
Использование свойства DOM-объекта
Можно назначать обработчик, используя свойство DOM-элемента on .
К примеру, elem.onclick :
Если обработчик задан через атрибут, то браузер читает HTML-разметку, создаёт новую функцию из содержимого атрибута и записывает в свойство.
Этот способ, по сути, аналогичен предыдущему.
Обработчик всегда хранится в свойстве DOM-объекта, а атрибут – лишь один из способов его инициализации.
Эти два примера кода работают одинаково:
Так как у элемента DOM может быть только одно свойство с именем onclick , то назначить более одного обработчика так нельзя.
В примере ниже назначение через JavaScript перезапишет обработчик из атрибута:
Кстати, обработчиком можно назначить и уже существующую функцию:
Убрать обработчик можно назначением elem.onclick = null .
Доступ к элементу через this
Внутри обработчика события this ссылается на текущий элемент, то есть на тот, на котором, как говорят, «висит» (т.е. назначен) обработчик.
В коде ниже button выводит своё содержимое, используя this.innerHTML :
Частые ошибки
Если вы только начинаете работать с событиями, обратите внимание на следующие моменты.
Функция должна быть присвоена как sayThanks , а не sayThanks() .
Если добавить скобки, то sayThanks() – это уже вызов функции, результат которого (равный undefined , так как функция ничего не возвращает) будет присвоен onclick . Так что это не будет работать.
…А вот в разметке, в отличие от свойства, скобки нужны:
Это различие просто объяснить. При создании обработчика браузером из атрибута, он автоматически создаёт функцию с телом из значения атрибута: sayThanks() .
Так что разметка генерирует такое свойство:
Используйте именно функции, а не строки.
Назначение обработчика строкой elem.onclick = «alert(1)» также сработает. Это сделано из соображений совместимости, но делать так не рекомендуется.
Не используйте setAttribute для обработчиков.
Такой вызов работать не будет:
Регистр DOM-свойства имеет значение.
Используйте elem.onclick , а не elem.ONCLICK , потому что DOM-свойства чувствительны к регистру.
addEventListener
Фундаментальный недостаток описанных выше способов назначения обработчика –- невозможность повесить несколько обработчиков на одно событие.
Например, одна часть кода хочет при клике на кнопку делать её подсвеченной, а другая – выдавать сообщение.
Мы хотим назначить два обработчика для этого. Но новое DOM-свойство перезапишет предыдущее:
Разработчики стандартов достаточно давно это поняли и предложили альтернативный способ назначения обработчиков при помощи специальных методов addEventListener и removeEventListener . Они свободны от указанного недостатка.
Синтаксис добавления обработчика:
Для удаления обработчика следует использовать removeEventListener :
Для удаления нужно передать именно ту функцию-обработчик которая была назначена.
Вот так не сработает:
Обработчик не будет удалён, т.к. в removeEventListener передана не та же функция, а другая, с одинаковым кодом, но это не важно.
Вот так правильно:
Обратим внимание – если функцию обработчик не сохранить где-либо, мы не сможем её удалить. Нет метода, который позволяет получить из элемента обработчики событий, назначенные через addEventListener .
Метод addEventListener позволяет добавлять несколько обработчиков на одно событие одного элемента, например:
Как видно из примера выше, можно одновременно назначать обработчики и через DOM-свойство и через addEventListener . Однако, во избежание путаницы, рекомендуется выбрать один способ.
Существуют события, которые нельзя назначить через DOM-свойство, но можно через addEventListener .
Например, таково событие DOMContentLoaded , которое срабатывает, когда завершена загрузка и построение DOM документа.
Так что addEventListener более универсален. Хотя заметим, что таких событий меньшинство, это скорее исключение, чем правило.
Объект события
Чтобы хорошо обработать событие, могут понадобиться детали того, что произошло. Не просто «клик» или «нажатие клавиши», а также – какие координаты указателя мыши, какая клавиша нажата и так далее.
Когда происходит событие, браузер создаёт объект события, записывает в него детали и передаёт его в качестве аргумента функции-обработчику.
Пример ниже демонстрирует получение координат мыши из объекта события:
Некоторые свойства объекта event :
event.type Тип события, в данном случае «click» . event.currentTarget Элемент, на котором сработал обработчик. Значение – обычно такое же, как и у this , но если обработчик является функцией-стрелкой или при помощи bind привязан другой объект в качестве this , то мы можем получить элемент из event.currentTarget . event.clientX / event.clientY Координаты курсора в момент клика относительно окна, для событий мыши.
Есть также и ряд других свойств, в зависимости от типа событий, которые мы разберём в дальнейших главах.
При назначении обработчика в HTML, тоже можно использовать объект event , вот так:
Это возможно потому, что когда браузер из атрибута создаёт функцию-обработчик, то она выглядит так: function(event) < alert(event.type) >. То есть, её первый аргумент называется «event» , а тело взято из атрибута.
Объект-обработчик: handleEvent
Мы можем назначить обработчиком не только функцию, но и объект при помощи addEventListener . В этом случае, когда происходит событие, вызывается метод объекта handleEvent .
Как видим, если addEventListener получает объект в качестве обработчика, он вызывает object.handleEvent(event) , когда происходит событие.
Мы также можем использовать класс для этого:
Здесь один и тот же объект обрабатывает оба события. Обратите внимание, мы должны явно назначить оба обработчика через addEventListener . Тогда объект menu будет получать события mousedown и mouseup , но не другие (не назначенные) типы событий.
Метод handleEvent не обязательно должен выполнять всю работу сам. Он может вызывать другие методы, которые заточены под обработку конкретных типов событий, вот так:
Теперь обработка событий разделена по методам, что упрощает поддержку кода.
Итого
Есть три способа назначения обработчиков событий:
- Атрибут HTML: onclick=». » .
- DOM-свойство: elem.onclick = function .
- Специальные методы: elem.addEventListener(event, handler[, phase]) для добавления, removeEventListener для удаления.
HTML-атрибуты используются редко потому, что JavaScript в HTML-теге выглядит немного странно. К тому же много кода там не напишешь.
DOM-свойства вполне можно использовать, но мы не можем назначить больше одного обработчика на один тип события. Во многих случаях с этим ограничением можно мириться.
Последний способ самый гибкий, однако нужно писать больше всего кода. Есть несколько типов событий, которые работают только через него, к примеру transitionend и DOMContentLoaded . Также addEventListener поддерживает объекты в качестве обработчиков событий. В этом случае вызывается метод объекта handleEvent .
Не важно, как вы назначаете обработчик – он получает объект события первым аргументом. Этот объект содержит подробности о том, что произошло.
Мы изучим больше о событиях и их типах в следующих главах.
Источник
Введение в события
События — это действия или случаи, возникающие в программируемой вами системе, о которых система сообщает вам для того, чтобы вы могли с ними взаимодействовать. Например, если пользователь нажимает кнопку на веб-странице, вы можете ответить на это действие, отобразив информационное окно. В этой статье мы обсудим некоторые важные концепции, связанные с событиями, и посмотрим, как они работают в браузерах. Эта статья не является исчерпывающим источником по этой теме — здесь только то, что вам нужно знать на этом этапе.
| Предпосылки: | Базовая компьютерная грамотность, базовое понимание HTML и CSS, Первые шаги в JavaScript. |
|---|---|
| Задача: | Понять фундаментальную теорию событий, как они работают в браузерах и как события могут различаться в разных средах программирования. |
Серия удачных событий
При возникновении события система генерирует сигнал, а также предоставляет механизм, с помощью которого можно автоматически предпринимать какие-либо действия (например, выполнить определённый код), когда происходит событие. Например, в аэропорту, когда взлётно-посадочная полоса свободна для взлёта самолёта, сигнал передаётся пилоту, и в результате они приступают к взлёту.
В Web события запускаются внутри окна браузера и, как правило, прикрепляются к конкретному элементу, который в нем находится. Это может быть один элемент, набор элементов, документ HTML, загруженный на текущей вкладке, или все окно браузера. Существует множество различных видов событий, которые могут произойти, например:
- Пользователь кликает мышью или наводит курсор на определённый элемент.
- Пользователь нажимает клавишу на клавиатуре.
- Пользователь изменяет размер или закрывает окно браузера.
- Завершение загрузки веб-страницы.
- Отправка данных через формы.
- Воспроизведение видео, пауза или завершение воспроизведения.
- Произошла ошибка.
Подробнее о событиях можно посмотреть в Справочнике по событиям.
Каждое доступное событие имеет обработчик событий — блок кода (обычно это функция JavaScript, вводимая вами в качестве разработчика), который будет запускаться при срабатывании события. Когда такой блок кода определён на запуск в ответ на возникновение события, мы говорим, что мы регистрируем обработчик событий . Обратите внимание, что обработчики событий иногда называют слушателями событий (от англ. event listeners). Они в значительной степени взаимозаменяемы для наших целей, хотя, строго говоря, они работают вместе. Слушатель отслеживает событие, а обработчик — это код, который запускается в ответ на событие.
Примечание: Важно отметить, что веб-события не являются частью основного языка JavaScript. Они определены как часть JavaScript-API, встроенных в браузер.
Простой пример
Рассмотрим простой пример. Вы уже видели события и обработчики событий во многих примерах в этом курсе, но давайте повторим для закрепления информации. В этом примере у нас есть кнопка , при нажатии которой цвет фона изменяется случайным образом:
JavaScript выглядит так:
В этом коде мы сохраняем ссылку на кнопку внутри переменной btn типа const , используя функцию Document.querySelector() . Мы также определяем функцию, которая возвращает случайное число. Третья часть кода — обработчик события. Переменная btn указывает на элемент — для этого типа объекта существуют возникающие при определённом взаимодействии с ним события, а значит, возможно использование обработчиков событий. Мы отслеживаем момент возникновения события при щелчке мышью, связывая свойство обработчика события onclick с анонимной функцией, генерирующей случайный цвет RGB и устанавливающей его в качестве цвета фона элемента .
Этот код теперь будет запускаться всякий раз, когда возникает событие при нажатии на элемент — всякий раз, когда пользователь щёлкает по нему.
Пример вывода выглядит следующим образом:
События не только для веб-страниц
События, как понятие, относятся не только к JavaScript — большинство языков программирования имеют модель событий, способ работы которой часто отличается от модели в JavaScript. Фактически, даже модель событий в JavaScript для веб-страниц отличается от модели событий для просто JavaScript, поскольку используются они в разных средах.
Например, Node.js — очень популярная среда исполнения JavaScript, которая позволяет разработчикам использовать JavaScript для создания сетевых и серверных приложений. Модель событий Node.js основана на том, что существуют обработчики, отслеживающие события, и эмиттеры (передатчики), которые периодически генерируют события. В общем-то, это похоже на модель событий в JavaScript для веб-страниц, но код совсем другой. В этой модели используется функция on() для регистрации обработчиков событий, и функция once() для регистрации обработчика событий, который отключается после первого срабатывания. Хорошим примером использования являются протоколы событий HTTP connect event docs.
Вы также можете использовать JavaScript для создания кросс-браузерных расширений — улучшения функциональности браузера с помощью технологии WebExtensions. В отличии от модели веб-событий здесь свойства обработчиков событий пишутся в так называемом регистре CamelCase (например, onMessage , а не onmessage ) и должны сочетаться с функцией addListener . См. runtime.onMessage page для примера.
На данном этапе обучения вам не нужно особо разбираться в различных средах программирования, однако важно понимать, что принцип работы событий в них отличается.
Способы использования веб-событий
Существует множество различных способов добавления кода обработчика событий на веб-страницы так, чтобы он срабатывал при возникновении соответствующего события. В этом разделе мы рассмотрим различные механизмы и обсудим, какие из них следует использовать.
Свойства обработчика событий
В этом курсе вы уже сталкивались со свойствами, связываемыми с алгоритмом работы обработчика событий. Вернёмся к приведённому выше примеру:
В данной ситуации свойство onclick — это свойство обработчика события. В принципе это обычное свойство кнопки как элемента (наравне с btn.textContent или btn.style ), но оно относится к особому типу. Если вы установите его равным какому-нибудь коду, этот код будет запущен при возникновении события (при нажатии на кнопку).
Для получения того же результата, вы также можете присвоить свойству обработчика имя уже описанной функции (как мы видели в статье Создайте свою функцию):
Давайте теперь поэкспериментируем с другими свойствами обработчика событий.
Создайте локальную копию файла random-color-eventhandlerproperty.html и откройте её в своём браузере. Это всего лишь копия простого примера про случайные цвета, который мы уже разобрали в этой статье. Теперь попробуйте изменить btn.onclick на следующие значения и понаблюдайте за результатами:
- btn.onfocus и btn.onblur — Цвет изменится, когда кнопка будет сфокусирована или не сфокусирована (попробуйте нажать Tab, чтобы выбрать кнопку или убрать выбор). Эти свойства часто применяются для отображения информации о том, как заполнить поля формы, когда они сфокусированы, или отобразить сообщение об ошибке, если поле формы было заполнено с неправильным значением.
- btn.ondblclick — Цвет будет изменяться только при двойном щелчке.
- window.onkeypress , window.onkeydown , window.onkeyup — Цвет будет меняться при нажатии клавиши на клавиатуре, причём keypress ссылается на обычное нажатие (нажатие кнопки и последующее её отпускание как одно целое), в то время как keydown и keyup разделяют действия на нажатие клавиши и отпускание, и ссылаются на них соответственно. Обратите внимание, что это не работает, если вы попытаетесь зарегистрировать этот обработчик событий на самой кнопке — его нужно зарегистрировать на объекте window, который представляет все окно браузера.
- btn.onmouseover и btn.onmouseout — Цвет будет меняться при наведении указателя мыши на кнопку или когда указатель будет отводиться от кнопки соответственно.
Некоторые события очень общие и доступны практически в любом месте (например, обработчик onclick может быть зарегистрирован практически для любого элемента), тогда как некоторые из них более конкретны и полезны только в определённых ситуациях (например, имеет смысл использовать onplay только для определённых элементов, таких как ).
Встроенные обработчики событий — не используйте их
Самый ранний из введённых в сеть Web методов регистрации обработчиков событий базируется на HTML атрибутах (встроенные обработчики событий):
Примечание: вы можете найти полный исходник кода из этого примера на GitHub (также взгляните на его выполнение).
Значение атрибута — это буквально код JavaScript, который вы хотите запустить при возникновении события. В приведённом выше примере вызывается функция, определённая внутри элемента
Источник