# EventTarget

The `EventTarget` interface represents an object that receives events and runs the listeners registered for them. Every event target implements its three methods: `addEventListener()`, `removeEventListener()`, and `dispatchEvent()`. For more information, refer to [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) on MDN Web Docs.

In a function, `globalThis` is an event target. The global [addEventListener](/en/documentation/devtools/runtime/api-reference/add-eventlistener/) registers the `fetch` handler on it, and a listener for a custom event type runs when `globalThis.dispatchEvent()` dispatches that type. Create your own event targets to build objects that dispatch and listen for custom events while a function handles a request. Add and remove listeners at run time to control which handlers react to an event.

In a browser, the most common event targets are [elements](https://developer.mozilla.org/en-US/docs/Web/API/Element) and their children, [Document](https://developer.mozilla.org/en-US/docs/Web/API/Document), and `Window`. Objects such as `XMLHttpRequest`, `AudioNode`, and `AudioContext` are event targets too. Elements, documents, and windows also accept [event handlers](https://developer.mozilla.org/en-US/docs/Web/Events/Event_handlers) through `onevent` properties and attributes. A function has no `document` object: a reference to it throws `ReferenceError: document is not defined`.

> **Note**
>
> Under `azion dev`, `CustomEvent` is not defined, `globalThis` is not an `EventTarget`, and `globalThis.dispatchEvent` is not a function. Event targets you construct behave the same in both environments.

---

## Constructor

```javascript
new EventTarget()
```

[EventTarget()](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget) creates an event target with no listeners. A class that extends `EventTarget` inherits the three methods: an instance of `class Bus extends EventTarget {}` runs the listeners added to it.

---

## Methods

| Method                                                                                                                              | Description                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`target.addEventListener(type, listener, options)`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) | Registers `listener` for events of `type`. With `{ once: true }` as `options`, the listener runs on the first dispatch only.                     |
| [`target.removeEventListener(type, listener)`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener)    | Removes the listener registered with the same `type` and `listener`. Later dispatches of `type` do not run it.                                   |
| [`target.dispatchEvent(event)`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent)                         | Dispatches `event` to the listeners registered for its type. Returns `false` when `event` is cancelable and a listener calls `preventDefault()`. |

`dispatchEvent()` takes an `Event`, such as `new Event('ping', { cancelable: true })`, or a `CustomEvent`. A listener reads the `detail` value of a `CustomEvent` from `event.detail`.

---

## Example

This handler registers a listener on an event target, dispatches the event, removes the listener, and dispatches the event again. It returns the number of times the listener ran and the event types it received:

```javascript
export default {
  async fetch(request, env, ctx) {
    const target = new EventTarget();
    const seen = [];
    const handler = (event) => seen.push(event.type);
    target.addEventListener('ping', handler);
    target.dispatchEvent(new Event('ping'));
    target.removeEventListener('ping', handler);
    target.dispatchEvent(new Event('ping'));
    return Response.json({ calls: seen.length, seen });
  },
};
```

The function returns these values. The listener runs once, because the second dispatch comes after `removeEventListener()`:

```json
{
 "calls": 1,
 "seen": [
  "ping"
 ]
}
```

---

## Related resources

- [addEventListener](/en/documentation/devtools/runtime/api-reference/add-eventlistener.md): How a function registers its `fetch` handler on the global event target.
- [FetchEvent](/en/documentation/devtools/runtime/api-reference/fetch-event.md): The event that the runtime dispatches for each incoming request.
- [Handlers](/en/documentation/devtools/runtime/api-reference/handlers.md): The handler shapes a function can export to answer a request.
- [Web APIs](/en/documentation/devtools/runtime/api-reference/javascript.md): The other Web APIs that Azion Runtime supports.
