> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/browser/event/handler/register.md).

# 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 %}
