---
title: '事件'
---

## 介紹

Yew 與 [`web-sys`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/) crate 集成，並使用該 crate 中的事件。下面的[表格](#event-types)列出了在 `html!` 巨集中接受的所有 `web-sys` 事件。

您仍然可以為下表中未列出的事件新增 [`Callback`](../function-components/callbacks.mdx)，請參閱[手動事件監聽器](#manual-event-listener)。

## 事件類型

:::tip
所有的事件類型都在 `yew::events` 下重新匯出。
使用 `yew::events` 中的類型比手動將 `web-sys` 作為依賴項包含在您的 crate 中更容易確保版本相容性，
因為您不會使用與 Yew 指定的版本衝突的版本。
:::

事件監聽器的名稱是在 `html` 巨集中新增事件 `Callback` 時預期的名稱：

```rust
use yew::prelude::*;

html! {
    <button onclick={Callback::from(|_| ())}>
    //      ^^^^^^^ event listener name
        { "Click me!" }
    </button>
};
```

事件名稱是監聽器名稱去掉 "on" 前綴，因此 `onclick` 事件監聽器監聽 `click` 事件。查看本頁末的[完整事件清單](#available-events)及其類型。

## 事件捕獲 {#event-bubbling}

Yew 調度的事件遵循虛擬 DOM 層次結構，向上冒泡到監聽器。目前，僅支援監聽器的冒泡階段。請注意，虛擬 DOM 層次結構通常（但並非總是）與實際 DOM 層次結構相同。在處理[傳送門](../../advanced-topics/portals)和其他更高級技術時，這一區別很重要。對於良好實現的元件，直覺應該是事件從子元件冒泡到父元件。這樣，您在 `html!` 中所寫的層次結構就是事件處理程序觀察到的層次結構。

如果您不想要事件冒泡，可以透過呼叫

```rust
yew::set_event_bubbling(false);
```

在啟動應用程式*之前*。這會加快事件處理速度，但某些元件可能會因未收到預期的事件而中斷。請謹慎使用！

## 事件委託

可能會讓人驚訝的是，事件監聽器並不是直接註冊在它們被渲染的元素上。相反，事件是從 Yew 應用的子樹根節點委託的。不過，事件仍然以其原生形式傳遞，並且不會創建任何合成形式。這可能會導致 HTML 監聽器中預期的事件與 Yew 中出現的事件之間的不符。

- [`Event::current_target`] 指向 Yew 子樹根節點，而不是新增監聽器的元素。如果您想存取底層的 `HtmlElement`，請使用 [`NodeRef`](../function-components/node-refs.mdx)。
- [`Event::event_phase`] 總是 [`Event::CAPTURING_PHASE`]。在內部，事件將表現得像是在冒泡階段，事件傳播將被重播，並且事件會[向上冒泡](#event-bubbling)，即虛擬DOM 中較高的事件監聽器將在較低的事件監聽器之後觸發。目前，Yew 不支援捕獲監聽器。

這也意味著由 Yew 註冊的事件通常會在其他事件監聽器之前觸發。

[`event::current_target`]: https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html#method.current_target
[`event::event_phase`]: https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html#method.event_phase
[`event::capturing_phase`]: https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html#associatedconstant.CAPTURING_PHASE

## 具備類型的事件目標

:::caution
在本節中，**target ([`Event.target`](https://developer.mozilla.org/en-US/docs/Web/API/Event/target))** 總是指的是事件從其派發的元素。

這**不一定**總是指 `Callback` 所放置的元素。
:::

在事件 `Callback` 中，您可能想要取得該事件的目標。例如，`change` 事件沒有提供任何訊息，但用於通知某些內容已更改。

在 Yew 中，以正確的類型獲取目標元素可以透過幾種方式完成，我們將在這裡逐一介紹。呼叫事件上的[`web_sys::Event::target`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html#method.target) 傳回一個可選的[ `web_sys::EventTarget`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.EventTarget.html) 類型，當您想知道輸入元素的值時，這可能看起來不太有用。

在下面的所有方法中，我們將解決相同的問題，以便清楚地了解方法的不同之處，而不是手邊的問題。

**問題：**

我們在 `<input>` 元素上有一個 `onchange` `Callback`，每次呼叫時，我們希望向元件發送一個[更新](components#update) `Msg`。

我們的 `Msg` 列舉如下：

```rust
pub enum Msg {
 InputValue(String),
}
```

### 使用 `JsCast`

[`wasm-bindgen`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/index.html) crate 有一個有用的trait：[`JsCast`](https://rustwasm.github .io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html)，它允許我們在類型之間直接轉換，只要它實現了`JsCast` 就行。我們可以謹慎地轉換，這涉及運行時檢查和處理 `Option` 和 `Result` 的邏輯，或者我們也可以冒險直接強行轉換。

多說無益，看代碼：

```toml title="Cargo.toml"
[dependencies]
# 需要 wasm-bindgen 用於呼叫 JsCast
wasm-bindgen = "0.2"
```

```rust
//highlight-next-line
use wasm_bindgen::JsCast;
use web_sys::{EventTarget, HtmlInputElement};
use yew::prelude::*;

#[function_component]
fn MyComponent() -> Html {
    let input_value_handle = use_state(String::default);
    let input_value = (*input_value_handle).clone();

    let on_cautious_change = {
        let input_value_handle = input_value_handle.clone();

        Callback::from(move |e: Event| {
            // 當事件被建立時，目標是未定義的，只有在派發時才會新增目標。
            let target: Option<EventTarget> = e.target();
            // 事件可能會冒泡，因此此偵聽器可能會捕獲不是 HtmlInputElement 類型的子元素的事件。
            //highlight-next-line
            let input = target.and_then(|t| t.dyn_into::<HtmlInputElement>().ok());

            if let Some(input) = input {
                input_value_handle.set(input.value());
            }
        })
    };

    let on_dangerous_change = Callback::from(move |e: Event| {
        let target: EventTarget = e
            .target()
            .expect("Event should have a target when dispatched");
        // 你必須了解 target 是 HtmlInputElement，否則呼叫 value 將是未定義行為（UB）。
        // 在這裡，我們確信這是輸入元素，因此我們可以在不檢查的情況下將其轉換為適當的類型。
        //highlight-next-line
        input_value_handle.set(target.unchecked_into::<HtmlInputElement>().value());
    });

    html! {
        <>
            <label for="cautious-input">
                { "My cautious input:" }
                <input onchange={on_cautious_change}
                    id="cautious-input"
                    type="text"
                    value={input_value.clone()}
                />
            </label>
            <label for="dangerous-input">
                { "My dangerous input:" }
                <input onchange={on_dangerous_change}
                    id="dangerous-input"
                    type="text"
                    value={input_value}
                />
            </label>
        </>
    }
}
```

`JsCast` 提供的方法是 [`dyn_into`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.dyn_into)
和 [`unchecked_into`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.unchecked_into)。
如你所見，它們允許我們從 `EventTarget` 轉換為 [`HtmlInputElement`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.HtmlInputElement.html)。
`dyn_into` 方法是謹慎的，因為它會在運行時檢查類型是否實際為 `HtmlInputElement`，如果不是則返回
`Err(JsValue)`。 [`JsValue`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html)
是一個通用類型，將原來的物件回傳給你，以便再次嘗試轉換為別的類型。

這會兒你可能會想，什麼時候可以使用危險版本？在上面的情況下，它是安全的<sup>1</sup>，因為我們將 `Callback` 設定在一個沒有子元素的元素上，所以目標只能是同一個元素。

_<sup>1</sup> 只要牽涉到 JS 領域，就是安全的。 _

### 使用 `TargetCast`

**強烈建議先閱讀 [使用 JsCast](#using-jscast)！ **

:::note
`TargetCast` 的設計目的是讓新用戶了解 `JsCast` 的行為，但範圍更小，僅涉及事件及其目標。

選用 `TargetCast` 或 `JsCast` 純粹是個人偏好，實際您會發現 `TargetCast` 的實作和 `JsCast` 的功能很相似。
:::

`TargetCast` trait 是在 `JsCast` 基礎之上建構的，專門用於從事件中取得類型化的事件目標。

`TargetCast` 是 Yew 的一部分，因此無需添加依賴項即可在事件上使用 trait 方法，但它的工作方式與 `JsCast` 非常相似。

```rust
use web_sys::HtmlInputElement;
use yew::prelude::*;

#[function_component]
fn MyComponent() -> Html {
    let input_value_handle = use_state(String::default);
    let input_value = (*input_value_handle).clone();

    let on_cautious_change = {
        let input_value_handle = input_value_handle.clone();

        Callback::from(move |e: Event| {
            let input = e.target_dyn_into::<HtmlInputElement>();

            if let Some(input) = input {
                input_value_handle.set(input.value());
            }
        })
    };

    let on_dangerous_change = Callback::from(move |e: Event| {
        // 你必須清楚 target 是 HtmlInputElement，否則呼叫 value 將是未定義行為（UB）。
        //highlight-next-line
        input_value_handle.set(e.target_unchecked_into::<HtmlInputElement>().value());
    });

    html! {
        <>
            <label for="cautious-input">
                { "My cautious input:" }
                <input onchange={on_cautious_change}
                    id="cautious-input"
                    type="text"
                    value={input_value.clone()}
                />
            </label>
            <label for="dangerous-input">
                { "My dangerous input:" }
                <input onchange={on_dangerous_change}
                    id="dangerous-input"
                    type="text"
                    value={input_value}
                />
            </label>
        </>
    }
}
```

如果您已經了解了 `JsCast`，或者了解了這個 trait，您可能會發現 `TargetCast::target_dyn_into` 與 `JsCast::dyn_into` 相似，但專門用於事件的目標。 `TargetCast::target_unchecked_into` 與 `JsCast::unchecked_into` 類似，因此上面關於 `JsCast` 的所有警告都適用於 `TargetCast`。

### 使用 `NodeRef`

[`NodeRef`](../function-components/node-refs.mdx) 可以取代查詢給定給 `Callback` 的事件。

```rust
use web_sys::HtmlInputElement;
use yew::prelude::*;

#[function_component]
fn MyComponent() -> Html {
    //highlight-next-line
    let input_node_ref = use_node_ref();

    let input_value_handle = use_state(String::default);
    let input_value = (*input_value_handle).clone();

    let onchange = {
        let input_node_ref = input_node_ref.clone();

        Callback::from(move |_| {
            //highlight-next-line
            let input = input_node_ref.cast::<HtmlInputElement>();

            if let Some(input) = input {
                input_value_handle.set(input.value());
            }
        })
    };

    html! {
        <>
            <label for="my-input">
                { "My input:" }
                //highlight-next-line
                <input ref={input_node_ref}
                    {onchange}
                    id="my-input"
                    type="text"
                    value={input_value}
                />
            </label>
        </>
    }
}
```

透過 `NodeRef`，你可以忽略事件並使用 `NodeRef::cast` 方法取得一個`Option<HtmlInputElement>` - 這是可選的，因為在設定 `NodeRef` 之前呼叫 `cast`，或者當類型不符時將會回傳 `None`。

你可能會看到，透過使用 `NodeRef`，我們不必將 `String` 傳回狀態，因為我們總是存取 `input_node_ref` - 因此我們可以這樣做：

```rust
use web_sys::HtmlInputElement;
use yew::prelude::*;

#[function_component]
fn MyComponent() -> Html {
    let input_node_ref = use_node_ref();

    //highlight-start
    let onchange = {
        let input_node_ref = input_node_ref.clone();

        Callback::from(move |_| {
            if let Some(input) = input_node_ref.cast::<HtmlInputElement>() {
                let value = input.value();
                // 對 value 做點什麼
            }
        })
    };
    //highlight-end

    html! {
        <>
            <label for="my-input">
                { "My input:" }
                <input ref={input_node_ref}
                    {onchange}
                    id="my-input"
                    type="text"
                />
            </label>
        </>
    }
}
```

您選擇哪種方法取決於您的元件和您的偏好，沒有所謂的*推薦*方法。

## 手動事件監聽器

您可能想要監聽 Yew 的 `html` 巨集不支援的事件，請查看[這裡列出的支援的事件](#event-types)。

為了手動為某個元素新增事件監聽器，我們需要藉助 [`NodeRef`](../function-components/node-refs.mdx)，以便在 `use_effect_with` 中使用 [`web-sys`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/index.html) 和 [wasm-bindgen](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/index.html) API 新增監聽器。

以下範例將展示如何為虛構的 `custard` 事件新增監聽器。所有不受 yew 支援的事件或自訂事件都可以表示為
[`web_sys::Event`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html)。如果您需要存取自訂/不受支援事件的特定方法或字段，可以使用
[`JsCast`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html) 的方法將其轉換為所需的類型。

### 使用 `Closure`（冗長版本）

直接使用 `web-sys` 和 `wasm-bindgen` 的介面可能有點痛苦…所以要有點心理準備（[感謝 `gloo`，有了更簡潔的方法](#using-gloo-concise)）。

```rust
use wasm_bindgen::{prelude::Closure, JsCast};
use web_sys::HtmlElement;
use yew::prelude::*;

#[function_component]
fn MyComponent() -> Html {
    let div_node_ref = use_node_ref();

    use_effect_with(
        div_node_ref.clone(),
        {
            let div_node_ref = div_node_ref.clone();

            move |_| {
                let mut custard_listener = None;

                if let Some(element) = div_node_ref.cast::<HtmlElement>() {
                    // 建立您通常會建立的 Callback
                    let oncustard = Callback::from(move |_: Event| {
                        // 對 custard 做點什麼..
                    });

                    // 從 Box<dyn Fn> 創建一個 Closure - 這必須是 'static
                    let listener =
                        Closure::<dyn Fn(Event)>::wrap(
                            Box::new(move |e: Event| oncustard.emit(e))
                        );

                    element
                        .add_event_listener_with_callback(
                            "custard",
                            listener.as_ref().unchecked_ref()
                        )
                        .unwrap();

                    custard_listener = Some(listener);
                }

                move || drop(custard_listener)
            }
        }
    );

    html! {
        <div ref={div_node_ref} id="my-div"></div>
    }
}
```

有關 `Closure` 的更多信息，請參見 [wasm-bindgen 指南](https://wasm-bindgen.github.io/wasm-bindgen/examples/closures.html)。

### 使用 `gloo`（簡潔版本）

更方便的方法是使用 `gloo`，更具體地說是 [`gloo_events`](https://docs.rs/gloo-events/0.1.1/gloo_events/index.html)，
它是 `web-sys`、`wasm-bindgen` 的高層抽象實作。

`gloo_events` 提供了 `EventListener` 類型，可以用來建立和儲存事件監聽器。

```toml title="Cargo.toml"
[dependencies]
gloo-events = "0.1"
```

```rust
use web_sys::HtmlElement;
use yew::prelude::*;

use gloo::events::EventListener;

#[function_component]
fn MyComponent() -> Html {
    let div_node_ref = use_node_ref();

    use_effect_with(
        div_node_ref.clone(),
        {
            let div_node_ref = div_node_ref.clone();

            move |_| {
                let mut custard_listener = None;

                if let Some(element) = div_node_ref.cast::<HtmlElement>() {
                    // 建立您通常會建立的 Callback
                    let oncustard = Callback::from(move |_: Event| {
                        // 對 custard 做點什麼..
                    });

                    // 從 Box<dyn Fn> 創建一個 Closure - 這必須是 'static
                    let listener = EventListener::new(
                        &element,
                        "custard",
                        move |e| oncustard.emit(e.clone())
                    );

                    custard_listener = Some(listener);
                }

                move || drop(custard_listener)
            }
        }
    );

    html! {
        <div ref={div_node_ref} id="my-div"></div>
    }
}
```

有關 `EventListener` 的更多信息，請參見 [gloo_events docs.rs](https://docs.rs/gloo-events/0.1.1/gloo_events/struct.EventListener.html)。

## 可用事件的完整清單 {#available-events}

| 偵聽器名稱                  | `web_sys` 事件類型                                                                    |
| --------------------------- | ------------------------------------------------------------------------------------- |
| `onabort`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onauxclick`                | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onblur`                    | [FocusEvent](https://docs.rs/web-sys/latest/web_sys/struct.FocusEvent.html)           |
| `oncancel`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `oncanplay`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `oncanplaythrough`          | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onchange`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onclick`                   | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onclose`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `oncontextmenu`             | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `oncuechange`               | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `ondblclick`                | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `ondrag`                    | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondragend`                 | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondragenter`               | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondragexit`                | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondragleave`               | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondragover`                | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondragstart`               | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondrop`                    | [DragEvent](https://docs.rs/web-sys/latest/web_sys/struct.DragEvent.html)             |
| `ondurationchange`          | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onemptied`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onended`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onerror`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onfocus`                   | [FocusEvent](https://docs.rs/web-sys/latest/web_sys/struct.FocusEvent.html)           |
| `onfocusin`                 | [FocusEvent](https://docs.rs/web-sys/latest/web_sys/struct.FocusEvent.html)           |
| `onfocusout`                | [FocusEvent](https://docs.rs/web-sys/latest/web_sys/struct.FocusEvent.html)           |
| `onformdata`                | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `oninput`                   | [InputEvent](https://docs.rs/web-sys/latest/web_sys/struct.InputEvent.html)           |
| `oninvalid`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onkeydown`                 | [KeyboardEvent](https://docs.rs/web-sys/latest/web_sys/struct.KeyboardEvent.html)     |
| `onkeypress`                | [KeyboardEvent](https://docs.rs/web-sys/latest/web_sys/struct.KeyboardEvent.html)     |
| `onkeyup`                   | [KeyboardEvent](https://docs.rs/web-sys/latest/web_sys/struct.KeyboardEvent.html)     |
| `onload`                    | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onloadeddata`              | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onloadedmetadata`          | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onloadstart`               | [ProgressEvent](https://docs.rs/web-sys/latest/web_sys/struct.ProgressEvent.html)     |
| `onmousedown`               | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onmouseenter`              | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onmouseleave`              | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onmousemove`               | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onmouseout`                | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onmouseover`               | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onmouseup`                 | [MouseEvent](https://docs.rs/web-sys/latest/web_sys/struct.MouseEvent.html)           |
| `onpause`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onplay`                    | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onplaying`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onprogress`                | [ProgressEvent](https://docs.rs/web-sys/latest/web_sys/struct.ProgressEvent.html)     |
| `onratechange`              | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onreset`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onresize`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onscroll`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onsecuritypolicyviolation` | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onseeked`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onseeking`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onselect`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onslotchange`              | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onstalled`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onsubmit`                  | [SubmitEvent](https://docs.rs/web-sys/latest/web_sys/struct.SubmitEvent.html)         |
| `onsuspend`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `ontimeupdate`              | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `ontoggle`                  | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onvolumechange`            | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onwaiting`                 | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onwheel`                   | [WheelEvent](https://docs.rs/web-sys/latest/web_sys/struct.WheelEvent.html)           |
| `oncopy`                    | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `oncut`                     | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onpaste`                   | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onanimationcancel`         | [AnimationEvent](https://docs.rs/web-sys/latest/web_sys/struct.AnimationEvent.html)   |
| `onanimationend`            | [AnimationEvent](https://docs.rs/web-sys/latest/web_sys/struct.AnimationEvent.html)   |
| `onanimationiteration`      | [AnimationEvent](https://docs.rs/web-sys/latest/web_sys/struct.AnimationEvent.html)   |
| `onanimationstart`          | [AnimationEvent](https://docs.rs/web-sys/latest/web_sys/struct.AnimationEvent.html)   |
| `ongotpointercapture`       | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onloadend`                 | [ProgressEvent](https://docs.rs/web-sys/latest/web_sys/struct.ProgressEvent.html)     |
| `onlostpointercapture`      | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointercancel`           | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerdown`             | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerenter`            | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerleave`            | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerlockchange`       | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onpointerlockerror`        | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onpointermove`             | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerout`              | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerover`             | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onpointerup`               | [PointerEvent](https://docs.rs/web-sys/latest/web_sys/struct.PointerEvent.html)       |
| `onselectionchange`         | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onselectstart`             | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `onshow`                    | [Event](https://docs.rs/web-sys/latest/web_sys/struct.Event.html)                     |
| `ontouchcancel`             | [TouchEvent](https://docs.rs/web-sys/latest/web_sys/struct.TouchEvent.html)           |
| `ontouchend`                | [TouchEvent](https://docs.rs/web-sys/latest/web_sys/struct.TouchEvent.html)           |
| `ontouchmove`               | [TouchEvent](https://docs.rs/web-sys/latest/web_sys/struct.TouchEvent.html)           |
| `ontouchstart`              | [TouchEvent](https://docs.rs/web-sys/latest/web_sys/struct.TouchEvent.html)           |
| `ontransitioncancel`        | [TransitionEvent](https://docs.rs/web-sys/latest/web_sys/struct.TransitionEvent.html) |
| `ontransitionend`           | [TransitionEvent](https://docs.rs/web-sys/latest/web_sys/struct.TransitionEvent.html) |
| `ontransitionrun`           | [TransitionEvent](https://docs.rs/web-sys/latest/web_sys/struct.TransitionEvent.html) |
| `ontransitionstart`         | [TransitionEvent](https://docs.rs/web-sys/latest/web_sys/struct.TransitionEvent.html) |
