# register handler

[JS](/web/js.md) ⟩ [browser](/web/browser.md) ⟩ [event](/web/browser/event.md) ⟩ [handler](/web/browser/event/handler.md) ⟩ register

{% hint style="success" %}

* register an event (<mark style="color:yellow;">**function**</mark>) handler：

```javascript
// 1. by setting the "on" property
window.onload = function(){ ... };

// 2. by calling addEventListener()
elem.addEventListener("click", handler, opts);
```

* register an event [**object handler**](/web/browser/event/handler/register/object-handler.md)：

```javascript
elem.addEventListener('click', {
    handleEvent(event) { ... }    // ⭐️ required method
});
```

{% endhint %}

{% tabs %}
{% tab title="🧨 雷區" %}
{% hint style="danger" %} <mark style="color:red;">**Don’t**</mark>**&#x20;**<mark style="color:yellow;">**use**</mark> <mark style="color:blue;">`setAttribute`</mark> to assign handlers. <mark style="color:yellow;">**Attributes are always**</mark>**&#x20;**<mark style="color:red;">**strings**</mark>, function becomes a string:exclamation:

```javascript
// a click on will generate errors.
elem.setAttribute('onclick', () => { ... });
```

{% endhint %}

{% hint style="danger" %}
For some events, handlers only work with <mark style="color:blue;">addEventListener</mark>.

```javascript
document.onDOMContentLoaded = handler;  // ❌ won't work❗️ 
document.addEventListener("DOMContentLoaded", handler) // ✅ 
```

{% endhint %}
{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="success" %}

* The <mark style="color:yellow;">**third argument**</mark> to [addEventListener()](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) is a <mark style="color:yellow;">**boolean**</mark> value or <mark style="color:orange;">**object**</mark>. If you pass <mark style="color:purple;">**true**</mark>, then the handler is registered as a [capturing handler](/web/browser/event/handler/register/capturing-handler.md).

```javascript
elem.addEventListener("click", handler, { 
    capture: true,    // ⭐️ registered as a "capturing" handler.
    once   : true,    // ⭐️ automatically removed after triggered once.
    passive: true     // ⭐️ can't cancel default actions.
});
```

{% endhint %}

{% hint style="danger" %} <mark style="color:red;">**Don’t use**</mark> [`setAttribute()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute) **to&#x20;**<mark style="color:yellow;">**register handlers**</mark>**,** it won’t work:

```javascript
// ⭐️ attributes are ALWAYS strings❗️ 
// function will be converted to a string automatically.
document.body.setAttribute('onclick', function() { alert(1) });
```

{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}

* registering a&#x20;
  * [capturing handler](/web/browser/event/handler/register/capturing-handler.md)
  * [object handler](/web/browser/event/handler/register/object-handler.md) - event handler can be an [<mark style="color:yellow;">**object**</mark>](/web/js/val/obj.md). ⭐️
* [remove handler](/web/browser/event/handler/remove.md)
  {% endtab %}

{% tab title="💈範例" %}

* registering with [addEventListener()](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)

```javascript
let button = document.querySelector("#mybutton"); 

// ⭐ registering with `addEventListener()`
button.addEventListener("click", () => { 
    console.log("Thanks again!"); 
});

// ⭐ registering a "capturing" event handler
document.addEventListener("click", handleClick, true);

// ⭐ explicitly specifies the options
document.addEventListener("click", handleClick, { 
    capture: true,    // ⭐ capturing handler
    once   : true,    // ⭐ automatically removed after triggered once
    passive: true     // ⭐ can't cancel default actions
});
```

* registering handlers on event target's "on" properties (onclick, onchange, ...):

{% hint style="warning" %}
缺點：

* 針對特定的 event target + event type (如：windown.onload)，一次只能設定一個 event handler。
* 如果前面已經有設定一個 event handler，後面設定的 event handler 會蓋掉前面的。
  {% endhint %}

```javascript
// ⭐ registering `window.onload`
// invoked when `document` is loaded
window.onload = function() {

    // Look up a <form> element
    let form = document.querySelector("form#shipping");

    // ⭐ registering `form.onsubmit`
    // invoked before the form is submitted.
    form.onsubmit = function(event) { 
        // assume: `isFormValid()` defined elsewhere.
        // if inputs not valid, prevent form submission.
        if (!isFormValid(this)) event.preventDefault();
    };
};
```

{% endtab %}

{% tab title="📗 參考" %}

* [ ] JavaScript The Definitive Guide (15.2 Events)
* [ ] javascript.info ⟩ [Introduction to browser events](https://javascript.info/introduction-browser-events#possible-mistakes)
  {% endtab %}

{% tab title="📘 手冊" %}

* [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) ⟩
  * [addEventListener()](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
  * [removeEventListener()](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener)
    {% endtab %}

{% tab title="👥 相關" %}

* [event propagation](/web/browser/event/propagation.md)
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/web/browser/event/handler/register.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
