Как вызвать событие javascript

JavaScript — Создание кастомных событий

В JavaScript можно создавать собственные события. Осуществляется это с помощью конструктора Event или CustomEvent .

Отличаются данные конструкторы тем, что в последнем ( CustomEvent ) можно указывать дополнительные данные ( detail ) для передачи их в событие.

const event = new Event(type [, options]);
  • type – имя события;
  • options — объект, в котором можно определить некоторые важные свойства, относящиеся к событию.

В options можно настроить:

  • bubbles – определяет, должно ли событие всплывать (true/false);
  • cancelable – указывает, можно ли отменить действие по умолчанию (true/false);
  • composed – определяет, должно ли событие всплывать наружу за пределы теневого DOM (true/false).

Все эти параметры в options по умолчанию имеют значения false .

Например, создадим пользовательское событие start :

const event = new Event('start');

После того как событие создано его нужно вызвать. Осуществляется это посредством метода dispatchEvent .

Синтаксис метода dispatchEvent :

$element – объект, для которого необходимо вызвать событие event $element.dispatchEvent(event);

Например, вызовем событие start для document :

// создаём событие const event = new Event('start'); // вызываем событие document.dispatchEvent(event);

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

document.addEventListener('start', e => { console.log('Обработка события start на document!'); });

Конструктор CustomEvent

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

По сути, CustomEvent отличается от Event только тем, что в нём во втором аргументе имеется дополнительное поле detail . Оно предназначено для передачи в событие любых данных.

Например, создадим кастомное событие start , которое будет добавлять к нему пользовательские данные:

   

Добавим обработчик события changeColor в котором пользовательские данные будем получать, используя e.detail:

box.addEventListener('changeColor', (e) => function () { console.log(E.detail.color); });

Добавить к объекту события пользовательских данных можно с помощью CustomEvent .

const event = new CustomEvent(event, CustomEventInit);

Добавление данных осуществляется через дополнительное свойство detail .

const anotherEvent = new CustomEvent('start', { detail: { color: 'white' } })

Используя CustomEvent в прослушивателе событий вы можете запросить данные для объекта события, используя event.detail (вы не можете использовать другое свойство):

document.addEventListener('start', event => { console.log('started!') console.log(event.detail) });

Источник

Генерация пользовательских событий

Можно не только назначать обработчики, но и генерировать события из JavaScript-кода.

Пользовательские события могут быть использованы при создании графических компонентов. Например, корневой элемент нашего меню, реализованного при помощи JavaScript, может генерировать события, относящиеся к этому меню: open (меню раскрыто), select (выбран пункт меню) и т.п. А другой код может слушать эти события и узнавать, что происходит с меню.

Читайте также:  Java lang object tostring method

Можно генерировать не только совершенно новые, придуманные нами события, но и встроенные, такие как click , mousedown и другие. Это бывает полезно для автоматического тестирования.

Конструктор Event

Встроенные классы для событий формируют иерархию аналогично классам для DOM-элементов. Её корнем является встроенный класс Event.

Событие встроенного класса Event можно создать так:

let event = new Event(type[, options]);
  • type – тип события, строка, например «click» или же любой придуманный нами – «my-event» .
  • options – объект с тремя необязательными свойствами:
    • bubbles: true/false – если true , тогда событие всплывает.
    • cancelable: true/false – если true , тогда можно отменить действие по умолчанию. Позже мы разберём, что это значит для пользовательских событий.
    • composed: true/false – если true , тогда событие будет всплывать наружу за пределы Shadow DOM. Позже мы разберём это в разделе Веб-компоненты.

    По умолчанию все три свойства установлены в false: .

    Метод dispatchEvent

    После того, как объект события создан, мы должны запустить его на элементе, вызвав метод elem.dispatchEvent(event) .

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

    В примере ниже событие click инициируется JavaScript-кодом так, как будто кликнули по кнопке:

      

    Можно легко отличить «настоящее» событие от сгенерированного кодом.

    Свойство event.isTrusted принимает значение true для событий, порождаемых реальными действиями пользователя, и false для генерируемых кодом.

    Пример всплытия

    Мы можем создать всплывающее событие с именем «hello» и поймать его на document .

    Всё, что нужно сделать – это установить флаг bubbles в true :

     

    1. Мы должны использовать addEventListener для наших собственных событий, т.к. on -свойства существуют только для встроенных событий, то есть document.onhello не сработает.
    2. Мы обязаны передать флаг bubbles:true , иначе наше событие не будет всплывать.

    Механизм всплытия идентичен как для встроенного события ( click ), так и для пользовательского события ( hello ). Также одинакова работа фаз всплытия и погружения.

    MouseEvent, KeyboardEvent и другие

    Для некоторых конкретных типов событий есть свои специфические конструкторы. Вот небольшой список конструкторов для различных событий пользовательского интерфейса, которые можно найти в спецификации UI Event:

    • UIEvent
    • FocusEvent
    • MouseEvent
    • WheelEvent
    • KeyboardEvent

    Стоит использовать их вместо new Event , если мы хотим создавать такие события. К примеру, new MouseEvent(«click») .

    Специфический конструктор позволяет указать стандартные свойства для данного типа события.

    Например, clientX/clientY для события мыши:

    let event = new MouseEvent("click", < bubbles: true, cancelable: true, clientX: 100, clientY: 100 >); alert(event.clientX); // 100

    Обратите внимание: этого нельзя было бы сделать с обычным конструктором Event .

    let event = new Event("click", < bubbles: true, // только свойства bubbles и cancelable cancelable: true, // работают в конструкторе Event clientX: 100, clientY: 100 >); alert(event.clientX); // undefined, неизвестное свойство проигнорировано!

    Впрочем, использование конкретного конструктора не является обязательным, можно обойтись Event , а свойства записать в объект отдельно, после создания, вот так: event.clientX=100 . Здесь это скорее вопрос удобства и желания следовать правилам. События, которые генерирует браузер, всегда имеют правильный тип.

    Полный список свойств по типам событий вы найдёте в спецификации, например, MouseEvent.

    Пользовательские события

    Для генерации событий совершенно новых типов, таких как «hello» , следует использовать конструктор new CustomEvent . Технически CustomEvent абсолютно идентичен Event за исключением одной небольшой детали.

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

     

    Свойство detail может содержать любые данные. Надо сказать, что никто не мешает и в обычное new Event записать любые свойства. Но CustomEvent предоставляет специальное поле detail во избежание конфликтов с другими свойствами события.

    Кроме того, класс события описывает, что это за событие, и если оно не браузерное, а пользовательское, то лучше использовать CustomEvent , чтобы явно об этом сказать.

    event.preventDefault()

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

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

    Вызов event.preventDefault() является возможностью для обработчика события сообщить в сгенерировавший событие код, что эти действия надо отменить.

    Тогда вызов elem.dispatchEvent(event) возвратит false . И код, сгенерировавший событие, узнает, что продолжать не нужно.

    Посмотрим практический пример – прячущегося кролика (могло бы быть скрывающееся меню или что-то ещё).

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

    Любой обработчик может узнать об этом, подписавшись на событие hide через rabbit.addEventListener(‘hide’. ) и, при желании, отменить действие по умолчанию через event.preventDefault() . Тогда кролик не исчезнет:

    o<>

    Обратите внимание: событие должно содержать флаг cancelable: true . Иначе, вызов event.preventDefault() будет проигнорирован.

    Вложенные события обрабатываются синхронно

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

    Исключением является ситуация, когда событие инициировано из обработчика другого события.

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

    В примере ниже событие menu-open обрабатывается синхронно во время обработки onclick :

     

    Порядок вывода: 1 → вложенное событие → 2.

    Обратите внимание, что вложенное событие menu-open успевает всплыть и запустить обработчик на document . Обработка вложенного события полностью завершается до того, как управление возвращается во внешний код ( onclick ).

    Это справедливо не только для dispatchEvent , но и для других ситуаций. JavaScript в обработчике события может вызвать другие методы, которые приведут к другим событиям – они тоже обрабатываются синхронно.

    Если нам это не подходит, то мы можем либо поместить dispatchEvent (или любой другой код, инициирующий события) в конец обработчика onclick , либо, если это неудобно, можно обернуть генерацию события в setTimeout с нулевой задержкой:

     

    Теперь dispatchEvent запускается асинхронно после исполнения текущего кода, включая mouse.onclick , поэтому обработчики полностью независимы.

    Новый порядок вывода: 1 → 2 → вложенное событие.

    Итого

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

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

    • bubbles: true чтобы событие всплывало.
    • cancelable: true если мы хотим, чтобы event.preventDefault() работал.

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

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

    Несмотря на техническую возможность генерировать встроенные браузерные события типа click или keydown , пользоваться ей стоит с большой осторожностью.

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

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

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

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

    Источник

Оцените статью