Skip to content

Commit

Permalink
Add list of events that bubble to document/window, and window-reflect…
Browse files Browse the repository at this point in the history
…ing body event handlers (#38044)
  • Loading branch information
Josh-Cena authored Feb 15, 2025
1 parent d9e1eba commit 69a705c
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 2 deletions.
76 changes: 76 additions & 0 deletions files/en-us/web/api/document/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,82 @@ Listen to these events using `addEventListener()` or by assigning an event liste
- {{DOMxRef("Document/selectionchange_event", "selectionchange")}}
- : Fired when the current text selection on a document is changed.

### Bubbled events

Not all events that bubble can reach the `Document` object. Only the following do and can be listened for on the `Document` object:

- `abort`
- {{domxref("Element/auxclick_event", "auxclick")}}
- {{domxref("Element/beforeinput_event", "beforeinput")}}
- {{domxref("Element/beforematch_event", "beforematch")}}
- {{domxref("HTMLElement/beforetoggle_event", "beforetoggle")}}
- {{domxref("Element/blur_event", "blur")}}
- `cancel`
- {{domxref("HTMLMediaElement/canplay_event", "canplay")}}
- {{domxref("HTMLMediaElement/canplaythrough_event", "canplaythrough")}}
- {{domxref("HTMLElement/change_event", "change")}}
- {{domxref("Element/click_event", "click")}}
- {{domxref("HTMLDialogElement/close_event", "close")}}
- {{domxref("HTMLCanvasElement/contextlost_event", "contextlost")}}
- {{domxref("Element/contextmenu_event", "contextmenu")}}
- {{domxref("HTMLCanvasElement/contextrestored_event", "contextrestored")}}
- {{domxref("Element/copy_event", "copy")}}
- {{domxref("HTMLTrackElement/cuechange_event", "cuechange")}}
- {{domxref("Element/cut_event", "cut")}}
- {{domxref("Element/dblclick_event", "dblclick")}}
- {{domxref("HTMLElement/drag_event", "drag")}}
- {{domxref("HTMLElement/dragend_event", "dragend")}}
- {{domxref("HTMLElement/dragenter_event", "dragenter")}}
- {{domxref("HTMLElement/dragleave_event", "dragleave")}}
- {{domxref("HTMLElement/dragover_event", "dragover")}}
- {{domxref("HTMLElement/dragstart_event", "dragstart")}}
- {{domxref("HTMLElement/drop_event", "drop")}}
- {{domxref("HTMLMediaElement/durationchange_event", "durationchange")}}
- {{domxref("HTMLMediaElement/emptied_event", "emptied")}}
- {{domxref("HTMLMediaElement/ended_event", "ended")}}
- {{domxref("Element/error_event", "error")}}
- {{domxref("Element/focus_event", "focus")}}
- {{domxref("HTMLFormElement/formdata_event", "formdata")}}
- {{domxref("Element/input_event", "input")}}
- {{domxref("HTMLElement/invalid_event", "invalid")}}
- {{domxref("Element/keydown_event", "keydown")}}
- {{domxref("Element/keypress_event", "keypress")}}
- {{domxref("Element/keyup_event", "keyup")}}
- {{domxref("HTMLElement/load_event", "load")}}
- {{domxref("HTMLMediaElement/loadeddata_event", "loadeddata")}}
- {{domxref("HTMLMediaElement/loadedmetadata_event", "loadedmetadata")}}
- {{domxref("HTMLMediaElement/loadstart_event", "loadstart")}}
- {{domxref("Element/mousedown_event", "mousedown")}}
- {{domxref("Element/mouseenter_event", "mouseenter")}}
- {{domxref("Element/mouseleave_event", "mouseleave")}}
- {{domxref("Element/mousemove_event", "mousemove")}}
- {{domxref("Element/mouseout_event", "mouseout")}}
- {{domxref("Element/mouseover_event", "mouseover")}}
- {{domxref("Element/mouseup_event", "mouseup")}}
- {{domxref("Element/paste_event", "paste")}}
- {{domxref("HTMLMediaElement/pause_event", "pause")}}
- {{domxref("HTMLMediaElement/play_event", "play")}}
- {{domxref("HTMLMediaElement/playing_event", "playing")}}
- {{domxref("HTMLMediaElement/progress_event", "progress")}}
- {{domxref("HTMLMediaElement/ratechange_event", "ratechange")}}
- {{domxref("HTMLFormElement/reset_event", "reset")}}
- {{domxref("HTMLElement/resize_event", "resize")}}
- {{domxref("Element/scroll_event", "scroll")}}
- {{domxref("Element/scrollend_event", "scrollend")}}
- {{domxref("Element/securitypolicyviolation_event", "securitypolicyviolation")}}
- {{domxref("HTMLMediaElement/seeked_event", "seeked")}}
- {{domxref("HTMLMediaElement/seeking_event", "seeking")}}
- {{domxref("Element/select_event", "select")}}
- {{domxref("HTMLSlotElement/slotchange_event", "slotchange")}}
- {{domxref("HTMLMediaElement/stalled_event", "stalled")}}
- {{domxref("HTMLFormElement/submit_event", "submit")}}
- {{domxref("HTMLMediaElement/suspend_event", "suspend")}}
- {{domxref("HTMLMediaElement/timeupdate_event", "timeupdate")}}
- {{domxref("HTMLElement/toggle_event", "toggle")}}
- {{domxref("HTMLMediaElement/volumechange_event", "volumechange")}}
- {{domxref("HTMLMediaElement/waiting_event", "waiting")}}
- {{domxref("Element/wheel_event", "wheel")}}

## Specifications

{{Specifications}}
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/element/keydown_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Unlike the deprecated {{domxref("Element/keypress_event", "keypress")}} event, t

The `keydown` and [`keyup`](/en-US/docs/Web/API/Element/keyup_event) events provide a code indicating which key is pressed, while `keypress` indicates which character was entered. For example, a lowercase "a" will be reported as 65 by `keydown` and `keyup`, but as 97 by `keypress`. An uppercase "A" is reported as 65 by all events.

The event target of a key event is the currently focused element which is processing the keyboard activity. This includes: {{HTMLElement("input")}}, {{HTMLElement("textarea")}}, anything that is [`contentEditable`](/en-US/docs/Web/HTML/Global_attributes/contenteditable), and anything else that can be interacted with the keyboard, such as {{HTMLElement("a")}}, {{HTMLElement("button")}}, and {{HTMLElement("summary")}}. If no suitable element is in focus, the event target will be the {{HTMLElement("body")}} or the root. If not caught, the event [bubbles](/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling) up the [DOM tree](/en-US/docs/Web/API/Document_Object_Model/Using_the_Document_Object_Model#what_is_a_dom_tree) until reaching {{domxref("Document")}}.
The event target of a key event is the currently focused element which is processing the keyboard activity. This includes: {{HTMLElement("input")}}, {{HTMLElement("textarea")}}, anything that is [`contentEditable`](/en-US/docs/Web/HTML/Global_attributes/contenteditable), and anything else that can be interacted with the keyboard, such as {{HTMLElement("a")}}, {{HTMLElement("button")}}, and {{HTMLElement("summary")}}. If no suitable element is in focus, the event target will be the {{HTMLElement("body")}} or the root. The event [bubbles](/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling). It can reach {{domxref("Document")}} and {{domxref("Window")}}.

The event target might change between different key events. For example, the `keydown` target for pressing the <kbd>Tab</kbd> key would be different from the `keyup` target, because the focus has changed.

Expand Down
2 changes: 2 additions & 0 deletions files/en-us/web/api/element/keypress_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ The **`keypress`** event is fired when a [letter, number, punctuation, or symbol
> [!WARNING]
> Since this event has been deprecated, you should use [`beforeinput`](/en-US/docs/Web/API/Element/beforeinput_event) or [`keydown`](/en-US/docs/Web/API/Element/keydown_event) instead.
The event [bubbles](/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling). It can reach {{domxref("Document")}} and {{domxref("Window")}}.

## Syntax

Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property.
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/element/keyup_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The **`keyup`** event is fired when a key is released.

The [`keydown`](/en-US/docs/Web/API/Element/keydown_event) and `keyup` events provide a code indicating which key is pressed, while `keypress` indicates which character was entered. For example, a lowercase "a" will be reported as 65 by `keydown` and `keyup`, but as 97 by `keypress`. An uppercase "A" is reported as 65 by all events.

The event target of a key event is the currently focused element which is processing the keyboard activity. This includes: {{HTMLElement("input")}}, {{HTMLElement("textarea")}}, anything that is [`contentEditable`](/en-US/docs/Web/HTML/Global_attributes/contenteditable), and anything else that can be interacted with the keyboard, such as {{HTMLElement("a")}}, {{HTMLElement("button")}}, and {{HTMLElement("summary")}}. If no suitable element is in focus, the event target will be the {{HTMLElement("body")}} or the root. If not caught, the event [bubbles](/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling) up the [DOM tree](/en-US/docs/Web/API/Document_Object_Model/Using_the_Document_Object_Model#what_is_a_dom_tree) until reaching {{domxref("Document")}}.
The event target of a key event is the currently focused element which is processing the keyboard activity. This includes: {{HTMLElement("input")}}, {{HTMLElement("textarea")}}, anything that is [`contentEditable`](/en-US/docs/Web/HTML/Global_attributes/contenteditable), and anything else that can be interacted with the keyboard, such as {{HTMLElement("a")}}, {{HTMLElement("button")}}, and {{HTMLElement("summary")}}. If no suitable element is in focus, the event target will be the {{HTMLElement("body")}} or the root. The event [bubbles](/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling). It can reach {{domxref("Document")}} and {{domxref("Window")}}.

The event target might change between different key events. For example, the `keydown` target for pressing the <kbd>Tab</kbd> key would be different from the `keyup` target, because the focus has changed.

Expand Down
14 changes: 14 additions & 0 deletions files/en-us/web/api/htmlbodyelement/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ The following {{domxref("Window")}} `onXYZ` event handler properties are also av
- : Fired when the associated document is about to be printed or previewed for printing.
- {{domxref("window.beforeunload_event", "HTMLBodyElement.onbeforeunload")}}
- : Fired when the window, the document and its resources are about to be unloaded.
- {{domxref("window.blur_event", "HTMLBodyElement.onblur")}}
- : Fired when the window loses focus.
- {{domxref("window.error_event", "HTMLBodyElement.onerror")}}
- : Fired when an error occurs and bubbles up to the window.
- {{domxref("window.focus_event", "HTMLBodyElement.onfocus")}}
- : Fired when the window gains focus.
- {{domxref("window.gamepadconnected_event", "HTMLBodyElement.ongamepadconnected")}}
- : Fired when the browser detects that a gamepad has been connected or the first time a button/axis of the gamepad is used.
- {{domxref("window.gamepaddisconnected_event", "HTMLBodyElement.ongamepaddisconnected")}}
Expand All @@ -55,6 +61,8 @@ The following {{domxref("Window")}} `onXYZ` event handler properties are also av
- : Fired when the fragment identifier of the URL has changed (the part of the URL beginning with and following the `#` symbol).
- {{domxref("window.languagechange_event", "HTMLBodyElement.onlanguagechange")}}
- : Fired when the user's preferred language changes.
- {{domxref("window.load_event", "HTMLBodyElement.onload")}}
- : Fired when the document has finished loading.
- {{domxref("window.message_event", "HTMLBodyElement.onmessage")}}
- : Fired when the window receives a message, for example from a call to [`Window.postMessage()`](/en-US/docs/Web/API/Window/postMessage) from another browsing context.
- {{domxref("window.messageerror_event", "HTMLBodyElement.onmessageerror")}}
Expand All @@ -71,13 +79,19 @@ The following {{domxref("Window")}} `onXYZ` event handler properties are also av
- : Fired when the active history entry changes while the user navigates the session history.
- {{domxref("window.rejectionhandled_event", "HTMLBodyElement.onrejectionhandled")}}
- : Fired whenever a JavaScript {{jsxref("Promise")}} is rejected and the rejection has been handled.
- {{domxref("window.resize_event", "HTMLBodyElement.onresize")}}
- : Fired when the document view has been resized.
- {{domxref("window.scroll_event", "HTMLBodyElement.onscroll")}}
- : Fired when the document view or an element has been scrolled.
- {{domxref("window.storage_event", "HTMLBodyElement.onstorage")}}
- : Fired when a storage area (`localStorage`) has been modified in the context of another document.
- {{domxref("window.unhandledrejection_event", "HTMLBodyElement.onunhandledrejection")}}
- : Fired whenever a {{jsxref("Promise")}} is rejected but the rejection was not handled.
- {{domxref("window.unload_event", "HTMLBodyElement.onunload")}}
- : Fired when the document is being unloaded.

Note that while `onblur`, `onerror`, `onfocus`, `onload`, `onresize`, and `onscroll` are available on any element, their meanings on the `<body>` element are not the same as on other elements. They listen for events on the `window` object instead.

## Specifications

{{Specifications}}
Expand Down
118 changes: 118 additions & 0 deletions files/en-us/web/api/window/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,10 +410,128 @@ Listen to these events using [`addEventListener()`](/en-US/docs/Web/API/EventTar
- {{domxref("Window/vrdisplaypresentchange_event", "vrdisplaypresentchange")}} {{Deprecated_Inline}} {{Non-standard_Inline}}
- : Fired when the presenting state of a VR device changes — i.e. goes from presenting to not presenting, or vice versa.

### Bubbled events

Not all events that bubble can reach the `Window` object. Only the following do and can be listened for on the `Window` object:

- `abort`
- {{domxref("Element/auxclick_event", "auxclick")}}
- {{domxref("Element/beforeinput_event", "beforeinput")}}
- {{domxref("Element/beforematch_event", "beforematch")}}
- {{domxref("HTMLElement/beforetoggle_event", "beforetoggle")}}
- `cancel`
- {{domxref("HTMLMediaElement/canplay_event", "canplay")}}
- {{domxref("HTMLMediaElement/canplaythrough_event", "canplaythrough")}}
- {{domxref("HTMLElement/change_event", "change")}}
- {{domxref("Element/click_event", "click")}}
- {{domxref("HTMLDialogElement/close_event", "close")}}
- {{domxref("HTMLCanvasElement/contextlost_event", "contextlost")}}
- {{domxref("Element/contextmenu_event", "contextmenu")}}
- {{domxref("HTMLCanvasElement/contextrestored_event", "contextrestored")}}
- {{domxref("Element/copy_event", "copy")}}
- {{domxref("HTMLTrackElement/cuechange_event", "cuechange")}}
- {{domxref("Element/cut_event", "cut")}}
- {{domxref("Element/dblclick_event", "dblclick")}}
- {{domxref("HTMLElement/drag_event", "drag")}}
- {{domxref("HTMLElement/dragend_event", "dragend")}}
- {{domxref("HTMLElement/dragenter_event", "dragenter")}}
- {{domxref("HTMLElement/dragleave_event", "dragleave")}}
- {{domxref("HTMLElement/dragover_event", "dragover")}}
- {{domxref("HTMLElement/dragstart_event", "dragstart")}}
- {{domxref("HTMLElement/drop_event", "drop")}}
- {{domxref("HTMLMediaElement/durationchange_event", "durationchange")}}
- {{domxref("HTMLMediaElement/emptied_event", "emptied")}}
- {{domxref("HTMLMediaElement/ended_event", "ended")}}
- {{domxref("HTMLFormElement/formdata_event", "formdata")}}
- {{domxref("Element/input_event", "input")}}
- {{domxref("HTMLElement/invalid_event", "invalid")}}
- {{domxref("Element/keydown_event", "keydown")}}
- {{domxref("Element/keypress_event", "keypress")}}
- {{domxref("Element/keyup_event", "keyup")}}
- {{domxref("HTMLMediaElement/loadeddata_event", "loadeddata")}}
- {{domxref("HTMLMediaElement/loadedmetadata_event", "loadedmetadata")}}
- {{domxref("HTMLMediaElement/loadstart_event", "loadstart")}}
- {{domxref("Element/mousedown_event", "mousedown")}}
- {{domxref("Element/mouseenter_event", "mouseenter")}}
- {{domxref("Element/mouseleave_event", "mouseleave")}}
- {{domxref("Element/mousemove_event", "mousemove")}}
- {{domxref("Element/mouseout_event", "mouseout")}}
- {{domxref("Element/mouseover_event", "mouseover")}}
- {{domxref("Element/mouseup_event", "mouseup")}}
- {{domxref("Element/paste_event", "paste")}}
- {{domxref("HTMLMediaElement/pause_event", "pause")}}
- {{domxref("HTMLMediaElement/play_event", "play")}}
- {{domxref("HTMLMediaElement/playing_event", "playing")}}
- {{domxref("HTMLMediaElement/progress_event", "progress")}}
- {{domxref("HTMLMediaElement/ratechange_event", "ratechange")}}
- {{domxref("HTMLFormElement/reset_event", "reset")}}
- {{domxref("Element/scrollend_event", "scrollend")}}
- {{domxref("Element/securitypolicyviolation_event", "securitypolicyviolation")}}
- {{domxref("HTMLMediaElement/seeked_event", "seeked")}}
- {{domxref("HTMLMediaElement/seeking_event", "seeking")}}
- {{domxref("Element/select_event", "select")}}
- {{domxref("HTMLSlotElement/slotchange_event", "slotchange")}}
- {{domxref("HTMLMediaElement/stalled_event", "stalled")}}
- {{domxref("HTMLFormElement/submit_event", "submit")}}
- {{domxref("HTMLMediaElement/suspend_event", "suspend")}}
- {{domxref("HTMLMediaElement/timeupdate_event", "timeupdate")}}
- {{domxref("HTMLElement/toggle_event", "toggle")}}
- {{domxref("HTMLMediaElement/volumechange_event", "volumechange")}}
- {{domxref("HTMLMediaElement/waiting_event", "waiting")}}
- {{domxref("Element/wheel_event", "wheel")}}

## Interfaces

See [DOM Reference](/en-US/docs/Web/API/Document_Object_Model).

## Listening for events on Window

HTML elements have three ways to listen for events:

- Add an event listener to the element using the {{domxref("EventTarget.addEventListener")}} method.
- Assign an event handler to the element's `oneventname` property in JavaScript.
- Add an `on`-prefixed attribute to the element in the HTML.

To listen for events on `Window` objects, in general, you can only use the first two methods, because `Window` has no corresponding HTML element. However, there's a specific group of events whose listeners can be added to the {{HTMLElement("body")}} (or the deprecated {{HTMLElement("frameset")}}) element that's owned by the `Window`'s document, using the second or third methods. These events are:

- `afterprint`
- `beforeprint`
- `beforeunload`
- `blur`
- `error`
- `focus`
- `hashchange`
- `languagechange`
- `load`
- `message`
- `messageerror`
- `offline`
- `online`
- `pagehide`
- `pagereveal`
- `pageshow`
- `pageswap`
- `popstate`
- `rejectionhandled`
- `resize`
- `scroll`
- `storage`
- `unhandledrejection`
- `unload`

This means the following are strictly equivalent:

```js
window.onresize = (e) => console.log(e.currentTarget);
document.body.onresize = (e) => console.log(e.currentTarget);
```

```html
<body onresize="console.log(event.currentTarget)"></body>
```

In all three cases, you see the `Window` object logged as `currentTarget`.

## Specifications

{{Specifications}}
Expand Down

0 comments on commit 69a705c

Please sign in to comment.