Bersama lagi untuk pertama kalinya
Pengantar
Selama hampir tiga puluh tahun, pengalaman komputasi desktop telah berpusat pada keyboard dan mouse atau trackpad sebagai perangkat input pengguna utama kami. Namun, selama satu dekade terakhir, smartphone dan tablet telah menghadirkan paradigma interaksi baru: sentuhan. Dengan diperkenalkannya komputer Windows 8 yang mendukung sentuhan, dan kini dengan dirilisnya Chromebook Pixel berkemampuan sentuh, sentuhan kini menjadi bagian dari pengalaman desktop yang diharapkan. Salah satu tantangan terbesarnya adalah membuat pengalaman yang tidak hanya berfungsi di perangkat sentuh dan perangkat mouse, tetapi juga di perangkat ini tempat pengguna akan menggunakan kedua metode input - terkadang secara bersamaan.
Artikel ini akan membantu Anda memahami cara kemampuan sentuh di-build ke dalam browser, cara mengintegrasikan mekanisme antarmuka baru ini ke dalam aplikasi yang ada, dan cara sentuh dapat berfungsi dengan baik dengan input mouse.
Kondisi Sentuhan di Platform Web
iPhone adalah platform populer pertama yang memiliki API sentuh khusus yang terintegrasi dengan browser web. Beberapa vendor browser lain telah membuat antarmuka API serupa yang dibuat agar kompatibel dengan implementasi iOS, yang kini dijelaskan oleh spesifikasi "Peristiwa Sentuh versi 1". Peristiwa sentuh didukung oleh Chrome dan Firefox di desktop, serta oleh Safari di iOS dan Chrome serta browser Android di Android, serta browser seluler lainnya seperti browser BlackBerry.
Kolega saya, Boris Smus, menulis tutorial HTML5Rocks yang bagus tentang Peristiwa sentuh yang masih merupakan cara yang baik untuk memulai jika Anda belum pernah melihat Peristiwa sentuh sebelumnya. Bahkan, jika Anda belum pernah menangani peristiwa sentuh sebelumnya, baca artikel tersebut sekarang, sebelum melanjutkan. Silakan, saya akan menunggu.
Selesai? Setelah Anda memiliki dasar dasar dalam peristiwa sentuh, tantangan dalam menulis interaksi yang diaktifkan dengan sentuhan adalah bahwa interaksi sentuh bisa sedikit berbeda dengan peristiwa mouse (dan trackpad pengemulasi mouse dan trackball) - dan meskipun antarmuka sentuh biasanya mencoba meniru mouse, emulasi tersebut tidak sempurna atau lengkap; Anda benar-benar perlu bekerja melalui kedua gaya interaksi, dan mungkin harus mendukung setiap antarmuka secara terpisah.
Hal terpenting: Pengguna Mungkin Memiliki Sentuhan dan Mouse
Banyak developer telah membuat situs yang secara statis mendeteksi apakah lingkungan mendukung peristiwa sentuh, lalu membuat asumsi bahwa mereka hanya perlu mendukung peristiwa sentuh (dan bukan mouse). Hal ini sekarang menjadi asumsi yang salah - sebagai gantinya, hanya karena ada peristiwa sentuh, bukan berarti pengguna utamanya menggunakan perangkat input sentuh tersebut. Perangkat seperti Chromebook Pixel dan beberapa laptop Windows 8 kini mendukung metode input Mouse dan Sentuh, dan banyak lagi dalam waktu dekat. Di perangkat ini, pengguna dapat menggunakan mouse dan layar sentuh secara alami untuk berinteraksi dengan aplikasi, sehingga "mendukung sentuh" tidak sama dengan "tidak memerlukan dukungan mouse". Anda tidak boleh menganggap masalah ini sebagai "Saya harus menulis dua gaya interaksi yang berbeda dan beralih di antara keduanya", Anda perlu memikirkan bagaimana kedua interaksi tersebut akan bekerja sama dan juga secara independen. Di Chromebook Pixel saya, saya sering menggunakan trackpad, tetapi saya juga mengambil gambar ke atas dan menyentuh layar - di aplikasi atau halaman yang sama, saya melakukan apa pun yang terasa paling alami pada saat itu. Di sisi lain, beberapa pengguna laptop layar sentuh jarang atau bahkan tidak pernah menggunakan layar sentuh sama sekali - sehingga kehadiran input sentuh tidak boleh menonaktifkan atau menghambat kontrol mouse.
Sayangnya, sulit untuk mengetahui apakah lingkungan browser pengguna mendukung input sentuh atau tidak; idealnya, browser di komputer desktop akan selalu menunjukkan dukungan untuk peristiwa sentuh sehingga layar sentuh dapat dipasang kapan saja (misalnya, jika layar sentuh yang dipasang melalui KVM tersedia). Karena semua alasan ini, sebaiknya aplikasi Anda tidak beralih antara sentuhan dan mouse - cukup dukung keduanya!
Mendukung Mouse dan Sentuh Bersama
#1 - Mengklik dan Mengetuk - Urutan "Alami"
Masalah pertama adalah antarmuka sentuh biasanya mencoba mengemulasi klik mouse - jelas, karena antarmuka sentuh harus berfungsi pada aplikasi yang sebelumnya hanya berinteraksi dengan peristiwa mouse. Anda dapat menggunakannya sebagai pintasan - karena peristiwa "klik" akan terus diaktifkan, baik pengguna mengklik dengan mouse atau mengetuk jarinya di layar. Namun, ada beberapa masalah dengan pintasan ini.
Pertama, Anda harus berhati-hati saat mendesain interaksi sentuh yang lebih canggih: saat pengguna menggunakan mouse, mouse akan merespons melalui peristiwa klik, tetapi saat pengguna menyentuh layar, peristiwa sentuh dan klik akan terjadi. Untuk satu klik, urutan peristiwanya adalah:
- touchstart
- touchmove
- touchend
- mouseover
- mousemove
- mousedown
- mouseup
- click
Ini, tentu saja, berarti bahwa jika Anda memproses peristiwa sentuh seperti touchstart, Anda perlu memastikan bahwa Anda juga tidak memproses peristiwa mousedown dan/atau klik yang sesuai. Jika Anda dapat membatalkan peristiwa sentuh (memanggil preventDefault() di dalam pengendali peristiwa), tidak ada peristiwa mouse yang akan dihasilkan untuk sentuh. Salah satu aturan pengendali sentuh yang paling penting adalah:
Namun, hal ini juga mencegah perilaku browser default lainnya (seperti men-scroll) - meskipun biasanya Anda menangani peristiwa sentuh sepenuhnya di pengendali, dan Anda AKAN MENG-NONAKTIFKAN tindakan default. Secara umum, Anda dapat menangani dan membatalkan semua peristiwa sentuh, atau menghindari memiliki pengendali untuk peristiwa tersebut.
Kedua, ketika pengguna mengetuk elemen di laman web pada perangkat seluler, halaman yang belum dirancang untuk interaksi seluler memiliki penundaan setidaknya 300 milidetik antara peristiwa touchstart dan pemrosesan peristiwa mouse (mousedown). Hal ini dapat dilakukan menggunakan Chrome. Anda dapat mengaktifkan "Emulate touch events" di Chrome Developer Tools untuk membantu menguji antarmuka sentuh di sistem non-sentuh.
Penundaan ini untuk memberi browser waktu guna menentukan apakah pengguna melakukan gestur lain - khususnya, zoom ketuk dua kali. Tentu saja, hal ini dapat menjadi masalah jika Anda ingin memiliki respons instan terhadap sentuhan jari. Ada pekerjaan yang sedang berlangsung untuk mencoba membatasi skenario terjadinya penundaan ini secara otomatis.
Cara pertama dan termudah untuk menghindari penundaan ini adalah "memberi tahu" browser seluler bahwa halaman Anda tidak perlu diperbesar - yang dapat dilakukan menggunakan area pandang tetap, misalnya dengan memasukkan ke dalam halaman:
<meta name="viewport" content="width=device-width,user-scalable=no">
Tentu saja, ini tidak selalu sesuai - ini menonaktifkan zoom cubit, yang mungkin diperlukan karena alasan aksesibilitas, jadi gunakan seperlunya (jika Anda menonaktifkan penskalaan pengguna, Anda mungkin ingin menyediakan cara lain untuk meningkatkan keterbacaan teks di aplikasi Anda). Selain itu, untuk Chrome di perangkat kelas desktop yang mendukung sentuhan, dan browser lain di platform seluler saat halaman memiliki area pandang yang tidak skalabel, penundaan ini tidak berlaku.
#2: Peristiwa Mousemove Tidak Diaktifkan oleh Sentuh
Pada tahap ini, penting untuk diperhatikan bahwa emulasi peristiwa mouse di antarmuka sentuh biasanya tidak diperluas untuk mengemulasi peristiwa mousemove. Jadi, jika Anda mem-build kontrol yang bagus dan digerakkan mouse yang menggunakan peristiwa mousemove, kontrol tersebut mungkin tidak akan berfungsi dengan perangkat sentuh kecuali jika Anda juga menambahkan pengendali touchmove secara khusus.
Browser biasanya otomatis menerapkan interaksi yang sesuai untuk interaksi sentuh pada kontrol HTML. Jadi, misalnya, kontrol Rentang HTML5 hanya akan berfungsi saat Anda menggunakan interaksi sentuh. Namun, jika Anda telah menerapkan kontrol sendiri, kontrol tersebut kemungkinan tidak akan berfungsi pada interaksi jenis klik-dan-tarik; sebenarnya, beberapa library yang umum digunakan (seperti jQueryUI) belum mendukung interaksi sentuh secara native dengan cara ini (meskipun untuk jQueryUI, ada beberapa perbaikan monkey-patch untuk masalah ini). Ini adalah salah satu masalah pertama yang saya temui saat mengupgrade aplikasi Web Audio Playground agar berfungsi dengan sentuhan - penggeser berbasis jQueryUI, sehingga tidak berfungsi dengan interaksi klik dan tarik. Saya beralih ke kontrol Rentang HTML5, dan kontrol tersebut berfungsi. Atau, tentu saja, saya bisa saja menambahkan pengendali touchmove untuk memperbarui penggeser, tetapi ada satu masalah dengan hal itu…
#3: Touchmove dan MouseMove Tidak Sama
Permasalahan yang saya lihat beberapa developer alami adalah memiliki pengendali touchmove dan mousemove yang memanggil jalur kode yang sama. Perilaku peristiwa ini sangat mirip, tetapi sedikit berbeda - khususnya, peristiwa sentuh selalu menargetkan elemen tempat peristiwa sentuh DIMULAI, sedangkan peristiwa mouse menargetkan elemen yang saat ini berada di bawah kursor mouse. Inilah sebabnya kita memiliki peristiwa mouseover dan mouseout, tetapi tidak ada peristiwa touchover dan touchout yang sesuai - hanya touchend.
Cara paling umum yang dapat merugikan Anda adalah jika Anda menghapus (atau memindahkan) elemen yang mulai disentuh pengguna. Misalnya, bayangkan carousel gambar dengan pengendali sentuh di seluruh carousel untuk mendukung perilaku scroll kustom. Saat gambar yang tersedia berubah, Anda menghapus beberapa elemen <img>
dan menambahkan elemen lainnya. Jika pengguna kebetulan mulai menyentuh salah satu gambar tersebut, lalu Anda menghapusnya, pengendali Anda (yang berada di ancestor elemen img) akan berhenti menerima peristiwa sentuh (karena dikirim ke target yang tidak lagi ada dalam hierarki) - akan terlihat seperti pengguna menahan jarinya di satu tempat meskipun mungkin telah dipindahkan dan akhirnya dihapus.
Anda tentu saja dapat menghindari masalah ini dengan tidak menghapus elemen yang memiliki (atau memiliki ancestor yang memiliki) pengendali sentuh saat sentuhan aktif. Atau, panduan terbaiknya adalah, daripada mendaftarkan pengendali touchend/touchmove statis, tunggu hingga Anda mendapatkan peristiwa touchstart, lalu tambahkan pengendali touchmove/touchend/touchcancel ke target peristiwa touchstart (dan hapus pada akhir/batalkan). Dengan cara ini, Anda akan terus menerima peristiwa untuk sentuhan meskipun elemen target dipindahkan/dihapus. Anda dapat memainkannya sedikit di sini - sentuh kotak merah dan sambil menahan tombol escape untuk menghapusnya dari DOM.
#4: Sentuh dan :Arahkan kursor
Metafora pointer mouse memisahkan posisi kursor dari pemilihan aktif, dan hal ini memungkinkan developer menggunakan status pengarahan kursor untuk menyembunyikan dan menampilkan informasi yang mungkin relevan bagi pengguna. Namun, sebagian besar antarmuka sentuh saat ini tidak mendeteksi jari yang "mengarahkan kursor" ke target. Jadi, memberikan informasi yang penting secara semantik (misalnya, memberikan pop-up "apa kontrol ini?") berdasarkan pengarahan kursor tidak diizinkan, kecuali jika Anda juga memberikan cara yang mudah diakses dengan sentuhan untuk mengakses informasi ini. Anda harus berhati-hati dalam menggunakan pengarahan kursor untuk menyampaikan informasi kepada pengguna.
Namun yang cukup menarik, pseudoclass CSS :hover dapat dipicu oleh antarmuka sentuh dalam beberapa kasus - mengetuk elemen akan membuatnya menjadi :active saat jari berada di bawah, dan juga memperoleh status :hover. (Dengan Internet Explorer, :hover hanya berlaku saat jari pengguna berada di atas - browser lain akan tetap menerapkan :hover hingga ketukan atau gerakan mouse berikutnya.) Ini adalah pendekatan yang baik untuk membuat menu pop-out berfungsi di antarmuka sentuh - efek samping dari membuat elemen aktif adalah status :hover juga diterapkan. Contoh:
<style>
img ~ .content {
display:none;
}
img:hover ~ .content {
display:block;
}
</style>
<img src="/awesome.png">
<div class="content">This is an awesome picture of me</div>
Setelah elemen lain diketuk, elemen tersebut tidak lagi aktif, dan status pengarahan kursor akan hilang, sama seperti saat pengguna menggunakan pointer mouse dan memindahkannya dari elemen. Anda dapat menggabungkan konten dalam elemen <a>
untuk menjadikannya juga sebagai tabstop. Dengan begitu, pengguna dapat mengalihkan informasi tambahan dengan mengarahkan kursor atau mengklik mouse, mengetuk sentuh, atau menekan tombol, tanpa memerlukan JavaScript. Saya terkejut saat mulai membuat Web Audio Playground agar berfungsi dengan baik dengan antarmuka sentuh sehingga menu pop-out saya sudah berfungsi dengan baik saat disentuh, karena saya telah menggunakan struktur semacam ini.
Metode di atas berfungsi dengan baik untuk antarmuka berbasis pointer mouse, serta untuk antarmuka sentuh. Hal ini berbeda dengan penggunaan atribut "title" saat mengarahkan kursor, yang TIDAK akan muncul saat elemen diaktifkan:
<img src="/awesome.png" title="this doesn't show up in touch">
#5: Presisi Sentuh vs. Mouse
Meskipun mouse memiliki pemisahan konseptual dari kenyataan, ternyata mouse sangat akurat, karena sistem operasi yang mendasarinya umumnya melacak presisi piksel yang tepat untuk kursor. Di sisi lain, developer seluler telah mempelajari bahwa sentuhan jari pada layar sentuh tidak seakurat itu, terutama karena ukuran area permukaan jari saat bersentuhan dengan layar (dan sebagian karena jari Anda menghalangi layar).
Banyak individu dan perusahaan telah melakukan riset pengguna yang ekstensif tentang cara merancang aplikasi dan situs yang mengakomodasi interaksi berbasis jari, dan banyak buku yang telah ditulis tentang topik tersebut. Saran dasarnya adalah meningkatkan ukuran target sentuh dengan meningkatkan padding, dan mengurangi kemungkinan ketukan yang salah dengan meningkatkan margin antar-elemen. (Margin tidak disertakan dalam penanganan deteksi hit untuk peristiwa sentuh dan klik, sedangkan padding disertakan.) Salah satu perbaikan utama yang harus saya lakukan pada Web Audio Playground adalah meningkatkan ukuran titik koneksi agar lebih mudah disentuh secara akurat.
Banyak vendor browser yang menangani antarmuka berbasis sentuh juga telah memperkenalkan logika ke dalam browser untuk membantu menargetkan elemen yang benar saat pengguna menyentuh layar dan mengurangi kemungkinan klik yang salah - meskipun hal ini biasanya hanya mengoreksi peristiwa klik, bukan bergerak (meskipun Internet Explorer tampaknya juga memodifikasi peristiwa mousedown/mousemove/mouseup).
#6: Pastikan Pengendali Sentuhan Tepat atau Mereka Akan Mengganggu Scroll Anda
Penting juga untuk menjaga pengendali sentuh hanya terbatas pada elemen tempat Anda membutuhkannya; elemen sentuh dapat memiliki bandwidth yang sangat tinggi, jadi penting untuk menghindari pengendali sentuh pada elemen scroll (karena pemrosesan Anda dapat mengganggu pengoptimalan browser untuk scroll sentuh yang cepat dan bebas jank - browser modern mencoba men-scroll pada thread GPU, tetapi ini tidak mungkin jika browser harus memeriksa dengan javascript terlebih dahulu untuk melihat apakah setiap peristiwa sentuh akan ditangani oleh aplikasi). Anda dapat melihat contoh perilaku ini.
Salah satu panduan yang harus diikuti untuk menghindari masalah ini adalah memastikan bahwa jika Anda hanya menangani peristiwa sentuh di sebagian kecil UI, Anda hanya melampirkan pengendali sentuh di sana (bukan, misalnya, di <body>
halaman); singkatnya, batasi cakupan pengendali sentuh Anda sebanyak mungkin.
#7: Multi-sentuh
Tantangan menarik terakhir adalah meskipun kami menyebutnya sebagai antarmuka pengguna "Sentuh", hampir secara universal dukungannya sebenarnya untuk Multi-sentuh - yaitu, API menyediakan lebih dari satu input sentuh sekaligus. Saat mulai mendukung sentuhan di aplikasi, Anda harus mempertimbangkan pengaruh beberapa sentuhan terhadap aplikasi.
Jika Anda telah mem-build aplikasi yang terutama didorong oleh mouse, Anda terbiasa mem-build dengan maksimal satu titik kursor - sistem biasanya tidak mendukung beberapa kursor mouse. Untuk banyak aplikasi, Anda hanya akan memetakan peristiwa sentuh ke satu antarmuka kursor, tetapi sebagian besar hardware yang telah kita lihat untuk input sentuh desktop dapat menangani setidaknya 2 input serentak, dan sebagian besar hardware baru tampaknya mendukung setidaknya 5 input serentak. Untuk mengembangkan keyboard piano virtual, tentu saja Anda ingin dapat mendukung beberapa input sentuh secara bersamaan.
W3C Touch API yang saat ini diterapkan tidak memiliki API untuk menentukan jumlah titik sentuh yang didukung hardware, sehingga Anda harus menggunakan estimasi terbaik untuk jumlah titik sentuh yang diinginkan pengguna - atau, tentu saja, perhatikan jumlah titik sentuh yang Anda lihat dalam praktik dan beradaptasi. Misalnya, dalam aplikasi piano, jika tidak melihat lebih dari dua titik sentuh, Anda dapat menambahkan beberapa UI "akor". PointerEvents API memiliki API untuk menentukan kemampuan perangkat.
Meningkatkan
Semoga artikel ini telah memberi Anda beberapa panduan tentang tantangan umum dalam menerapkan sentuhan bersama interaksi mouse. Yang lebih penting daripada saran lainnya, tentu saja, adalah Anda perlu menguji aplikasi di seluler, tablet, serta lingkungan desktop mouse dan sentuh yang dikombinasikan. Jika Anda tidak memiliki hardware sentuh+mouse, gunakan "Emulate touch events" Chrome untuk membantu Anda menguji berbagai skenario.
Anda tidak hanya dapat, tetapi juga relatif mudah mengikuti panduan ini untuk membuat pengalaman interaktif yang menarik dan berfungsi baik dengan input sentuh, input mouse, dan bahkan kedua gaya interaksi secara bersamaan.