Menunjuk sesuatu di web dulunya mudah. Anda memiliki mouse, Anda menggerakkannya, terkadang Anda menekan tombol, dan selesai. Semua yang bukan mouse di-emulasi sebagai mouse, dan developer tahu persis apa yang harus diandalkan.
Namun, sederhana bukan berarti baik. Seiring waktu, semakin penting agar tidak semua perangkat (atau berpura-pura menjadi) mouse: Anda dapat memiliki pena yang sensitif terhadap tekanan dan kemiringan, untuk kebebasan berkreasi yang luar biasa; Anda dapat menggunakan jari, sehingga yang Anda butuhkan hanyalah perangkat dan tangan Anda; dan, mengapa tidak menggunakan lebih dari satu jari saat melakukannya?
Kami telah memiliki peristiwa sentuh selama beberapa waktu untuk membantu kami, tetapi API tersebut sepenuhnya terpisah khusus untuk sentuh, sehingga Anda harus membuat kode dua model peristiwa terpisah jika ingin mendukung mouse dan sentuh. Chrome 55 dilengkapi dengan standar yang lebih baru yang menyatukan kedua model: peristiwa pointer.
Satu model peristiwa
Peristiwa pointer menyatukan model input pointer untuk browser, yang menggabungkan sentuhan, pena, dan mouse ke dalam satu kumpulan peristiwa. Contoh:
document.addEventListener('pointermove',
ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
ev => console.log('The pointer is now over foo.'));
Berikut adalah daftar semua peristiwa yang tersedia, yang akan terlihat cukup familier jika Anda sudah terbiasa dengan peristiwa mouse:
pointerover
|
Pointer telah memasuki kotak pembatas elemen.
Hal ini terjadi segera untuk perangkat yang mendukung pengarahan kursor, atau sebelum
peristiwa pointerdown untuk perangkat yang tidak mendukungnya.
|
pointerenter
|
Serupa dengan pointerover , tetapi tidak mengapung dan menangani
turunan secara berbeda.
Detail tentang spesifikasi.
|
pointerdown
|
Pointer telah memasuki status tombol aktif, dengan tombol ditekan atau kontak dibuat, bergantung pada semantik perangkat input. |
pointermove
|
Posisi pointer telah berubah. |
pointerup
|
Pointer telah keluar dari status tombol aktif. |
pointercancel
|
Terjadi sesuatu yang berarti pointer tidak akan memunculkan peristiwa lagi. Artinya, Anda harus membatalkan tindakan yang sedang berlangsung dan kembali ke status input netral. |
pointerout
|
Pointer telah keluar dari kotak pembatas elemen atau layar. Juga setelah
pointerup , jika perangkat tidak mendukung pengarahan kursor.
|
pointerleave
|
Serupa dengan pointerout , tetapi tidak mengapung dan menangani
turunan secara berbeda.
Detail tentang spesifikasi.
|
gotpointercapture
|
Elemen telah menerima rekaman pointer. |
lostpointercapture
|
Pointer yang direkam telah dilepaskan. |
Berbagai jenis input
Umumnya, Peristiwa Pointer memungkinkan Anda menulis kode dengan cara yang tidak bergantung pada input,
tanpa perlu mendaftarkan pengendali peristiwa terpisah untuk perangkat input yang berbeda.
Tentu saja, Anda tetap harus memperhatikan perbedaan antara jenis input, seperti apakah
konsep pengarahan kursor berlaku. Jika ingin membedakan jenis perangkat input yang berbeda – mungkin untuk menyediakan
kode/fungsi terpisah untuk input yang berbeda – Anda dapat melakukannya dari
dalam pengendali peristiwa yang sama menggunakan properti pointerType
dari
antarmuka
PointerEvent
. Misalnya, jika Anda membuat kode panel navigasi samping, Anda dapat
memiliki logika berikut pada peristiwa pointermove
:
switch(ev.pointerType) {
case 'mouse':
// Do nothing.
break;
case 'touch':
// Allow drag gesture.
break;
case 'pen':
// Also allow drag gesture.
break;
default:
// Getting an empty string means the browser doesn't know
// what device type it is. Let's assume mouse and do nothing.
break;
}
Tindakan default
Di browser yang mendukung sentuh, gestur tertentu digunakan untuk men-scroll, memperbesar, atau memuat ulang halaman.
Dalam kasus peristiwa sentuh, Anda akan tetap menerima peristiwa saat tindakan default ini
berlangsung – misalnya, touchmove
akan tetap diaktifkan saat pengguna men-scroll.
Dengan peristiwa pointer, setiap kali tindakan default seperti scroll atau zoom dipicu,
Anda akan mendapatkan peristiwa pointercancel
, untuk memberi tahu Anda bahwa browser telah mengambil
kontrol pointer. Contoh:
document.addEventListener('pointercancel',
ev => console.log('Go home, the browser is in charge now.'));
Kecepatan bawaan: Model ini memungkinkan performa yang lebih baik secara default, dibandingkan dengan peristiwa sentuh, yang mengharuskan Anda menggunakan pemroses peristiwa pasif untuk mencapai tingkat responsivitas yang sama.
Anda dapat menghentikan browser agar tidak mengambil kontrol dengan properti CSS
touch-action
. Menetapkan ke none
pada elemen akan menonaktifkan semua
tindakan yang ditentukan browser yang dimulai di elemen tersebut. Namun, ada sejumlah
nilai lain untuk kontrol yang lebih terperinci, seperti pan-x
, untuk memungkinkan browser
bereaksi terhadap gerakan pada sumbu x, tetapi tidak pada sumbu y. Chrome 55
mendukung nilai berikut:
auto
|
Default; browser dapat melakukan tindakan default apa pun. |
none
|
Browser tidak diizinkan untuk melakukan tindakan default apa pun. |
pan-x
|
Browser hanya diizinkan untuk melakukan tindakan default scroll horizontal. |
pan-y
|
Browser hanya diizinkan untuk melakukan tindakan default scroll vertikal. |
pan-left
|
Browser hanya diizinkan untuk melakukan tindakan default scroll horizontal, dan hanya untuk menggeser halaman ke kiri. |
pan-right
|
Browser hanya diizinkan untuk melakukan tindakan default scroll horizontal, dan hanya untuk menggeser halaman ke kanan. |
pan-up
|
Browser hanya diizinkan untuk melakukan tindakan default scroll vertikal, dan hanya untuk menggeser halaman ke atas. |
pan-down
|
Browser hanya diizinkan untuk melakukan tindakan default scroll vertikal, dan hanya untuk menggeser halaman ke bawah. |
manipulation
|
Browser hanya diizinkan untuk melakukan tindakan scroll dan zoom. |
Rekaman pointer
Pernahkah Anda menghabiskan waktu satu jam yang melelahkan untuk men-debug peristiwa mouseup
yang rusak, hingga Anda menyadari bahwa hal itu karena pengguna melepaskan tombol di luar target klik Anda? Tidak? Oke, mungkin hanya saya.
Namun, hingga saat ini belum ada cara yang benar-benar baik untuk mengatasi masalah ini. Tentu saja,
Anda dapat menyiapkan pengendali mouseup
pada dokumen, dan menyimpan beberapa status di
aplikasi untuk melacak berbagai hal. Namun, ini bukan solusi yang paling bersih, terutama jika Anda mem-build komponen web dan mencoba menjaga semuanya tetap rapi dan
terisolasi.
Dengan peristiwa pointer, Anda akan mendapatkan solusi yang jauh lebih baik: Anda dapat menangkap pointer,
sehingga Anda pasti mendapatkan peristiwa pointerup
tersebut (atau teman-teman lainnya
yang sulit dipahami).
const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
console.log('Button down, capturing!');
// Every pointer has an ID, which you can read from the event.
foo.setPointerCapture(ev.pointerId);
});
foo.addEventListener('pointerup',
ev => console.log('Button up. Every time!'));
Dukungan browser
Pada saat penulisan, Peristiwa Pointer didukung di Internet Explorer 11, Microsoft Edge, Chrome, dan Opera, serta didukung sebagian di Firefox. Anda dapat menemukan daftar terbaru di caniuse.com.
Anda dapat menggunakan polyfill Peristiwa Pointer untuk mengisi kesenjangan. Atau, memeriksa dukungan browser saat runtime sangat mudah:
if (window.PointerEvent) {
// Yay, we can use pointer events!
} else {
// Back to mouse and touch events, I guess.
}
Peristiwa pointer adalah kandidat yang bagus untuk progressive enhancement: cukup
ubah metode inisialisasi untuk melakukan pemeriksaan di atas, tambahkan pengendali peristiwa
pointer di blok if
, dan pindahkan pengendali peristiwa mouse/sentuh ke
blok else
.
Jadi, silakan coba dan beri tahu kami pendapat Anda.