# touch event

[browser](../..) ⟩ [event](..) ⟩ [type]() ⟩ touch

{% hint style="success" %}
* "[touchstart](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchstart_event)" - finger (may be another finger) touches the screen.&#x20;
* "[touchmove](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchmove_event)" - finger moved while touching.&#x20;
* "[touchend](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchend_event)" - finger leaves the screen (other fingers may still be touching).
* "[touchcancel](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchcancel_event)" - a touch point has been disrupted in some way.
{% endhint %}

{% tabs %}
{% tab title="🧨 雷區" %}
{% hint style="danger" %}
If you <mark style="color:yellow;">**tap**</mark> the screen, you’ll get

* <mark style="color:purple;">**touch events**</mark>："[touchstart](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchstart_event)", "[touchend](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchend_event)", <mark style="color:yellow;">**then**</mark>
* [**mouse events**](mouse)："mousedown", "mouseup", "click":exclamation:
{% endhint %}

{% hint style="warning" %}
if you tap the screen with 2 fingers, it may tigger events like the following：

```javascript
// touch events
touchstart: [(311, 125), (213, 136)]    // 2 fingers simultaneously
touchend  : []                          // fingers leave
// then mouse events
mousedown : (262, 131)    // ⭐️ average point of 2 fingers
mouseup   : (262, 131)
click     : (262, 131)
```

or the following：

```javascript
// touch events first
touchstart: [(295, 138)]                // first finger comes in
touchstart: [(295, 138), (197, 149)]    // second finger comes in
touchend  : [(295, 138)]                // second finger leaves
touchend  : []                          // first finger leaves
// then mouse events
mousedown : (246, 144)    // ⭐️ average point of 2 fingers
mouseup   : (246, 144)
click     : (246, 144)
```
{% endhint %}

{% hint style="warning" %}
if you touch the screen&#x20;

* with 1 finger (and hold)
* and then with a second finger
* release second finger
* release first finger

it might tigger events like the following：&#x20;

```javascript
// only touch events
touchstart: [(226, 129)]    // first finger comes in
touchmove : [(225, 128)]    // first finger may move around
touchmove : [(225, 129)]    // ...
touchmove : [(224, 129)]    // ...
touchstart: [(224, 129), (372, 108)]    // second finger comes in
touchend  : [(224, 129)]    // second finger leaves
touchend  : []              // first finger leaves
// ⭐️ without any mouse events❗️
```
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}
* <mark style="color:yellow;">**touch event properties**</mark>
  * [.touches](touch/.touches "mention")
  * [.targettouches](touch/.targettouches "mention")
* <mark style="color:yellow;">**extensions**</mark>
  * [touchlist+ext](touch/touchlist+ext "mention")
{% endtab %}

{% tab title="💈範例" %}
* replit ⟩ [tap screen](https://replit.com/@pegasusroe/tap-screen-events#index.js) ,  require ⟩ [Array extension](../../../js/val/builtin/arr/ext), [TouchList extension](touch/touchlist+ext)

```javascript
const { log } = console
const { max } = Math;

// ⭐️ import
import { } from './js/ext/TouchList_ext.js';      // TouchList extension
import { } from './js/ext/Array_ext.js';          // Array extension
// --------------------------------------------------------------------

const touchEvents = ['touchstart', 'touchmove', 'touchend'];
const mouseEvents = ['mousedown', 'mouseup', 'click'];
const eventTypes = [...touchEvents, ...mouseEvents];
const padLength = eventTypes.maxIn(x => x.length);    // 👔 Array extension

// ⭐️ general handler
function update(event) {

    let points;
    
    if (mouseEvents.includes(event.type)) {
        // mouse events
        const {pageX, pageY} = event;
        points = `(${pageX}, ${pageY})`;
    } else {
        // touch events
        points = `${event.touches}`;    // 👔 TouchList extension
    }

    log(`${event.type.padEnd(padLength, ' ')}: ${points}`);
    
}

// ⭐️ listen to mouse/touch events
eventTypes.forEach(type => 
    document.body.addEventListener(type, update)
);
```
{% endtab %}

{% tab title="👥 相關" %}
* [mouse](mouse "mention")
* [boxes](../../dom/type/element/boxes "mention")
* [capturing](../propagation/capturing "mention") - use <mark style="color:yellow;">`{passive: false}`</mark> to prevent touch screen default actions.
{% endtab %}

{% tab title="📗 參考" %}
* [ ] Eloquent JS ⟩ [Ch. 15: Event Handling](https://eloquentjavascript.net/15_event.html) ⟩ [Touch Events](https://eloquentjavascript.net/15_event.html#i_jF9QgltzXD) ⭐️&#x20;
{% endtab %}

{% tab title="📘 手冊" %}
* [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) ⟩ [UIEvent](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent) ⟩ [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent)
* [Touch events](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events)
* [Using Touch Events](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Using_Touch_Events)
* [Touch](https://developer.mozilla.org/en-US/docs/Web/API/Touch) ⟩&#x20;
  * (.[pageX](https://developer.mozilla.org/en-US/docs/Web/API/Touch/pageX), .pageY) - relative to page (document)
  * (.clientX, .clientY) - relative to [viewport](../../dom/type/window/viewport).
{% endtab %}

{% tab title="🗣 討論" %}
* [How to prevent default handling of touch events?](https://stackoverflow.com/a/49590237/5409815) ⭐️&#x20;
{% endtab %}
{% endtabs %}
