Lompat ke konten
dokumentasi.id
Commit 83fc07e
v2
Star3,5 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

6

Penanganan Perangkat Touch

TouchHandler adalah lapisan kecil di src/js/waves.js yang menahan efek mousedown selama dan sesudah interaksi sentuh. Lapisan ini hanya menyala ketika browser melaporkan dukungan sentuh: isTouchAvailable dihitung sekali dari 'ontouchstart' in window. src/js/waves.js:38

Pada perangkat tersebut, Waves.init memasang listener di document.body seperti tabel berikut. src/js/waves.js:480-486

EventHandlerSyarat pemasangan
touchstartshowEffectisTouchAvailable
touchcancelTouchHandler.registerEventisTouchAvailable
touchendTouchHandler.registerEventisTouchAvailable
mousedownshowEffectselalu dipasang

Anatomi TouchHandler

Objek ini hanya memiliki satu field dan dua method. Komentar di atas deklarasinya menyebut tujuannya secara langsung: "Disable mousedown event for 500ms during and after touch". src/js/waves.js:321-359

MemberBentukPerilaku
touchesinteger, mulai 0Penghitung sentuh yang sedang berjalan. Dipilih integer, bukan boolean, agar tidak perlu clearTimeout saat sentuhan baru datang dalam 500 ms.
allowEvent(e)functionMengembalikan false untuk mousedown dan mousemove bila touches bukan nol, selain itu true.
registerEvent(e)functionMenambah touches pada touchstart, dan menjadwalkan pengurangan pada touchend atau touchcancel.

registerEvent menaikkan penghitung tanpa syarat waktu pada touchstart, sedangkan touchend dan touchcancel menurunkan penghitung lewat setTimeout(..., 500). Penurunan dijaga if (TouchHandler.touches) agar tidak menjadi negatif. src/js/waves.js:342-357

Gerbang allowEvent

allowEvent memakai satu ekspresi reguler untuk membatasi cakupannya: hanya event yang cocok dengan /^(mousedown|mousemove)$/ yang bisa ditolak. Event lain, termasuk touchstart itu sendiri, selalu lolos. src/js/waves.js:332-341

Penolakan itu dipakai paling awal di getWavesEffectElement. Bila TouchHandler.allowEvent(e) mengembalikan false, fungsi langsung mengembalikan null, sehingga showEffect berhenti sebelum mencari elemen .waves-effect dan tidak ada ripple baru. src/js/waves.js:366-370

graph LR
    TS["touchstart"] --> INC["TouchHandler.touches += 1"]
    INC --> MOUSE{"mousedown atau mousemove"}
    MOUSE -->|touches terisi| BLOCK["allowEvent: false"]
    MOUSE -->|touches kosong| PASS["allowEvent: true"]
    BLOCK --> NULL["getWavesEffectElement: null"]
    PASS --> FIND["cari elemen .waves-effect"]
    style INC fill:#f59e0b,color:#000
    style BLOCK fill:#dc2626,color:#fff
    style NULL fill:#dc2626,color:#fff
    style PASS fill:#2d7d46,color:#fff
%% fig: Gerbang allowEvent pada TouchHandler
%% desc: touchstart menaikkan penghitung touches, lalu setiap mousedown dan mousemove diperiksa gerbang allowEvent sebelum elemen dicari.
Fig. 1: Gerbang allowEvent pada TouchHandlertouchstart menaikkan penghitung touches, lalu setiap mousedown dan mousemove diperiksa gerbang allowEvent sebelum elemen dicari.

⚠️ Kenaikan touches terjadi di dalam showEffect, bukan di listener touchstart milik document.body. registerEvent(e) hanya dipanggil setelah elemen .waves-effect ditemukan dan tidak berstatus disabled, getAttribute('disabled'), atau kelas disabled. Sentuhan di luar elemen tersebut tidak menaikkan penghitung, jadi tidak ada yang menahan mousedown sesudahnya. src/js/waves.js:399-406

Opsi delay

Effect.delay bernilai 200 secara default, dengan komentar "check for scroll before showing effect". Nilainya bisa diganti lewat Waves.init({ delay: ... }) karena init menyalin opsi delay ke Effect.delay. src/js/waves.js:107-108 src/js/waves.js:476-478

Opsi itu juga muncul di tipe init pada src/typings/waves.d.ts, lihat API Publik dan Tipings TypeScript. src/typings/waves.d.ts:3

Cabang delay hanya dipakai ketika e.type === 'touchstart' dan Effect.delay bernilai bukan nol. mousedown tidak pernah ditunda oleh opsi ini. src/js/waves.js:408-451

Kejadian pada elemenAksi di kodeHasil
touchstart dengan Effect.delaysetTimeout menyimpan timer, isinya Effect.show(e, element)Efek belum tampil selama Effect.delay
timer habistimer diisi null, Effect.show(e, element) berjalanRipple muncul
touchmove (pengguna menggulir)clearTimeout(timer) lalu hideEffect(moveEvent)Efek dibatalkan, tidak ada ripple
touchend atau touchcancelhideEffect menampilkan efek lebih dulu bila timer masih hidup, lalu Effect.hideSentuhan singkat tetap memberi efek

Di akhir tiap jalur, removeListeners melepas kembali listener touchmove, touchend, dan touchcancel yang dipasang pada elemen. Fungsi itu dideklarasikan setelah pemasangan listener, tetapi baru dipanggil dari callback sehingga deklarasi var sudah terisi saat dipakai. src/js/waves.js:408-451

Bila Effect.delay bernilai nol atau falsy, jalur lain yang berjalan: Effect.show(e, element) dipanggil langsung, lalu touchend dan touchcancel diarahkan ke Effect.hide selama isTouchAvailable. Effect.hide sendiri melepas kedua listener sentuh itu setelah ripple terakhir dihapus. src/js/waves.js:452-463 src/js/waves.js:192-195

stateDiagram-v2
    [*] --> Idle
    Idle --> Touching: "touchstart pada elemen .waves-effect"
    Touching --> Pending: "Effect.delay bukan nol, setTimeout"
    Touching --> RippleVisible: "Effect.delay nol, Effect.show langsung"
    Pending --> RippleVisible: "timer habis, Effect.show"
    Pending --> Scrolling: "touchmove, clearTimeout"
    Scrolling --> Idle: "hideEffect lalu removeListeners"
    RippleVisible --> Idle: "touchend atau touchcancel, Effect.hide"
    Touching --> Cooldown: "touchend atau touchcancel, registerEvent"
    Pending --> Cooldown: "touchend atau touchcancel, registerEvent"
    RippleVisible --> Cooldown: "touchend atau touchcancel, registerEvent"
    Cooldown --> Idle: "500 ms, touches -= 1"
    style Pending fill:#f59e0b,color:#000
    style Scrolling fill:#dc2626,color:#fff
    style RippleVisible fill:#2d7d46,color:#fff
    style Cooldown fill:#8b5cf6,color:#fff
%% fig: Siklus sentuh dari touchstart sampai touches kembali nol
%% desc: Cabang delay menunda Effect.show, menggulir lewat touchmove membatalkannya, dan touchend atau touchcancel menahan mousedown selama 500 ms.
Fig. 2: Siklus sentuh dari touchstart sampai touches kembali nolCabang delay menunda Effect.show, menggulir lewat touchmove membatalkannya, dan touchend atau touchcancel menahan mousedown selama 500 ms.

Pembatalan lewat touchmove inilah yang membuat delay berguna: gulir halaman tidak memicu efek, sedangkan ketukan singkat tetap menampilkannya lewat hideEffect. src/js/waves.js:433-441

⚠️ Nama delay dipakai ulang sebagai variabel lokal di removeRipple dengan nilai 350 - diff dan 150 untuk mousemove. Variabel itu tidak ada hubungannya dengan Effect.delay. src/js/waves.js:273-283

Titik sentuh dan ripple

Effect.show memilih koordinat dari e.touches[0].pageY dan e.touches[0].pageX bila event membawa daftar touches, lalu memakai e.pageY dan e.pageX untuk event mouse. Perhitungan pusat ripple selengkapnya ada di Siklus Hidup Ripple. src/js/waves.js:129-132

Pencarian elemen .waves-effect dan penyaringan status disabled berada di Alur Efek Klik dari Event ke Elemen; halaman ini hanya membahas bagaimana sentuhan menahan event mouse.