Saya sedang mengerjakan situs web seluler yang harus bekerja di berbagai perangkat. Yang membuat saya sakit kepala saat ini adalah BlackBerry.
Kita perlu mendukung klik keyboard dan juga acara sentuh.
Idealnya saya hanya menggunakan:
$thing.click(function(){...})
tetapi masalah yang kita hadapi adalah bahwa beberapa perangkat blackberry ini memiliki penundaan yang sangat mengganggu dari saat disentuh hingga memicu klik.
Obatnya adalah dengan menggunakan touchstart:
$thing.bind('touchstart', function(event){...})
Tetapi bagaimana saya bisa mengikat kedua acara, tetapi hanya menembak satu? Saya masih membutuhkan acara klik untuk perangkat keyboard, tetapi tentu saja, tidak ingin acara klik diaktifkan jika saya menggunakan perangkat sentuh.
Pertanyaan bonus: Apakah ada cara untuk melakukan ini dan juga mengakomodasi browser yang bahkan tidak memiliki acara touchstart? Dalam meneliti ini, sepertinya BlackBerry OS5 tidak mendukung touchstart sehingga juga perlu mengandalkan acara klik untuk browser itu.
TAMBAHAN:
Mungkin pertanyaan yang lebih komprehensif adalah:
Dengan jQuery, apakah mungkin / direkomendasikan untuk menangani interaksi sentuhan dan interaksi mouse dengan binding yang sama?
Idealnya, jawabannya adalah ya. Jika tidak, saya punya beberapa opsi:
1) Kami menggunakan WURFL untuk mendapatkan info perangkat sehingga dapat membuat matriks perangkat kami sendiri. Bergantung pada perangkat, kami akan menggunakan touchstart ATAU klik.
2) Mendeteksi dukungan sentuh di browser melalui JS (Saya perlu melakukan penelitian lebih lanjut tentang itu, tetapi sepertinya itu bisa dilakukan).
Namun, itu masih menyisakan satu masalah: bagaimana dengan perangkat yang mendukung KEDUA. Beberapa ponsel yang kami dukung (yaitu Nokias dan BlackBerries) memiliki layar sentuh dan keyboard. Jadi hal itu membuat saya kembali ke pertanyaan semula ... adakah cara untuk memungkinkan keduanya sekaligus?
sumber
.bind('touchstart mouseup')
akan menyelesaikannya (berdasarkan salah satu komentar di bawah)Jawaban:
Pembaruan : Lihat proyek jQuery Pointer Events Polyfill yang memungkinkan Anda untuk mengikat "penunjuk" acara daripada memilih antara mouse & touch.
Ikat keduanya, tetapi buat bendera sehingga fungsinya hanya menyala sekali per 100 ms atau lebih.
sumber
click
mengubahnya kemousedown
... mungkin penundaan yang lama adalah perbedaan antaramousedown
danmouseup
bagaimana caraclick
ditentukan.touchend
dengan menerapkan kelastouched
. Kebakaran ini sebelum acara klik disebut. Saya kemudian menambahkan acara klik yang pertama memeriksa keberadaan kelas itu. Jika ada, kami menganggap acara sentuh diaktifkan dan kami tidak melakukan apa pun dengan klik selain menghapus nama kelas untuk 'mengatur ulang' untuk interaksi berikutnya. Jika kelas tidak ada di sana, maka kami menganggap mereka telah menggunakan keyboard untuk mengklik item, dan memicu fungsi dari sana.Ini adalah perbaikan yang saya "buat" dan mengeluarkan GhostClick dan mengimplementasikan FastClick. Coba sendiri dan beri tahu kami jika itu berhasil untuk Anda.
sumber
event.handled
akan samaundefined
setiap kali acara dipicu. Inilah solusinya: atur bendera 'ditangani' di elemen target itu sendiri dengan menggunakanjQuery.data()
.event.stopPropagation();
danevent.preventDefault();
dari pemahaman saya (dan pengujian) acara hanya dapat dipecat sekali dengan ini. jadi mengapa memeriksaif(event.handled !== true)
? Bagi saya itu tidak perlu atau apakah saya melewatkan sesuatu?event.handled
harus diperiksa nilainyatrue
? Sejauh yang saya tahu itu tidak pernahfalse
. Ini dimulai sebagaiundefined
, dan kemudian Anda ingin tahu apakah sudah diaturtrue
.Anda dapat mencoba sesuatu seperti ini:
sumber
Biasanya ini berfungsi juga:
sumber
Hanya menambahkan
return false;
di akhiron("click touchstart")
fungsi acara dapat menyelesaikan masalah ini.Dari dokumentasi jQuery di .on ()
sumber
Saya harus melakukan hal serupa. Ini adalah versi sederhana dari apa yang berhasil untuk saya. Jika acara sentuh terdeteksi, hapus ikatan klik.
Dalam kasus saya, peristiwa klik terikat ke suatu
<a>
elemen, jadi saya harus menghapus ikatan klik dan memutar balik peristiwa klik yang mencegah tindakan default untuk<a>
elemen tersebut.sumber
Saya berhasil dengan cara berikut.
Peasy mudah ...
sumber
e
parameter difunction()
Saya percaya praktik terbaik sekarang adalah menggunakan:
CONTOH
EDIT (2017)
Mulai 2017, browser dimulai dengan Chrome dan membuat langkah menuju pembuatan acara klik
.on("click")
lebih kompatibel untuk mouse dan sentuhan dengan menghilangkan penundaan yang dihasilkan oleh acara ketuk pada permintaan klik.Ini mengarah pada kesimpulan bahwa kembali menggunakan hanya peristiwa klik akan menjadi solusi paling sederhana untuk maju.
Saya belum melakukan pengujian lintas browser untuk melihat apakah ini praktis.
sumber
mouseup
hasil yang tidak terduga, terutama ketika menggunakan trackpad daripada mouse tradisional.Secara umum Anda tidak ingin mencampur api sentuh dan non-sentuh (klik) default. Setelah Anda pindah ke dunia sentuhan, lebih mudah untuk berurusan hanya dengan fungsi terkait sentuhan. Di bawah ini adalah beberapa kode pseudo yang akan melakukan apa yang Anda inginkan.
Jika Anda terhubung dalam acara touchmove dan melacak lokasi, Anda dapat menambahkan lebih banyak item di fungsi doTouchLogic untuk mendeteksi gerakan dan yang lainnya.
sumber
periksa tombol cepat dan pilih klik dari google https://developers.google.com/mobile/articles/fast_buttons
sumber
Baiklah ... Semua ini sangat rumit.
Jika Anda memiliki modernizr, itu adalah no-brainer.
sumber
Implementasi lain untuk pemeliharaan yang lebih baik. Namun, teknik ini juga akan melakukan event.stopPropagation (). Klik tidak tertangkap pada elemen lain yang diklik selama 100 ms.
sumber
Hanya untuk keperluan dokumentasi, inilah yang telah saya lakukan untuk klik tercepat / paling responsif pada desktop / ketuk pada solusi seluler yang dapat saya pikirkan:
Saya mengganti
on
fungsi jQuery dengan yang dimodifikasi yang, setiap kali browser mendukung acara sentuh, mengganti semua acara klik saya dengan touchstart.Penggunaan daripada akan sama persis seperti sebelumnya, seperti:
Tapi itu akan menggunakan touchstart saat tersedia, klik bila tidak. Tidak ada penundaan dalam bentuk apa pun: D
sumber
Saya baru saja datang dengan ide untuk menghafal jika
ontouchstart
pernah dipicu. Dalam hal ini kami menggunakan perangkat yang mendukungnya dan ingin mengabaikanonclick
acara tersebut. Karenaontouchstart
harus selalu dipicu sebelumnyaonclick
, saya menggunakan ini:sumber
Anda dapat mencoba seperti ini:
sumber
Dalam kasus saya ini berfungsi dengan baik:
Masalah utama adalah ketika bukannya mouseup saya coba klik, pada perangkat sentuh memicu klik dan touchend pada saat yang sama, jika saya menggunakan klik, beberapa fungsi tidak berfungsi sama sekali pada perangkat seluler. Masalah dengan klik adalah bahwa itu adalah acara global yang memecat sisa acara termasuk touchend.
sumber
Ini bekerja untuk saya, ponsel mendengarkan keduanya, jadi cegah salah satunya, yang merupakan acara sentuh. desktop hanya mendengarkan mouse.
sumber
Bagi saya jawaban terbaik yang diberikan oleh Mottie, saya hanya mencoba untuk membuat kode-nya lebih dapat digunakan kembali, jadi inilah kontribusi saya:
sumber
Saya juga bekerja pada aplikasi web Android / iPad, dan tampaknya jika hanya menggunakan "touchmove" sudah cukup untuk "memindahkan komponen" (tidak perlu touchstart). Dengan menonaktifkan touchstart, Anda dapat menggunakan .click (); dari jQuery. Ini sebenarnya berfungsi karena belum kelebihan beban oleh touchstart.
Akhirnya, Anda dapat binb .live ("touchstart", function (e) {e.stopPropagation ();}); untuk meminta acara touchstart berhenti propagasi, ruang tamu mengklik () untuk dipicu.
Ini berhasil untuk saya.
sumber
touchstart
?Ada banyak hal yang perlu dipertimbangkan ketika mencoba menyelesaikan masalah ini. Sebagian besar solusi baik istirahat bergulir atau tidak menangani peristiwa klik hantu dengan benar.
Untuk solusi lengkap, lihat https://developers.google.com/mobile/articles/fast_buttons
NB: Anda tidak bisa menangani acara klik hantu berdasarkan per elemen. Klik yang tertunda dipicu oleh lokasi layar, jadi jika acara sentuh Anda memodifikasi halaman dengan cara tertentu, acara klik akan dikirim ke versi halaman yang baru.
sumber
Mungkin efektif untuk ditugaskan ke acara
'touchstart mousedown'
atau'touchend mouseup'
untuk menghindari efek samping yang tidak diinginkan dari penggunaanclick
.sumber
Mengambil keuntungan dari fakta bahwa klik akan selalu mengikuti acara sentuhan, di sini adalah apa yang saya lakukan untuk menghilangkan "klik hantu" tanpa harus menggunakan batas waktu atau bendera global.
Pada dasarnya setiap kali suatu
ontouchstart
kejadian terjadi pada elemen tersebut, sebuah tanda di set dan kemudian dihapus (dan diabaikan), ketika klik itu datang.sumber
Mengapa tidak menggunakan API Acara jQuery?
http://learn.jquery.com/events/event-extensions/
Saya telah menggunakan acara sederhana ini dengan sukses. Ini bersih, namespaceable dan cukup fleksibel untuk diperbaiki.
sumber
Jika Anda menggunakan jQuery, yang berikut berfungsi dengan baik untuk saya:
Solusi lain juga bagus tapi saya mengikat banyak acara dalam satu lingkaran dan membutuhkan fungsi self calling untuk membuat penutupan yang tepat. Juga, saya tidak ingin menonaktifkan pengikatan karena saya ingin dapat dipanggil pada klik / touchstart berikutnya.
Bisa membantu seseorang dalam situasi yang sama!
sumber
Untuk fitur sederhana, cukup kenali sentuhan atau klik saya menggunakan kode berikut:
Ini akan mengembalikan "sentuhan" jika acara touchstart ditentukan dan "tidak ada sentuhan" jika tidak. Seperti yang saya katakan ini adalah pendekatan sederhana untuk acara klik / ketuk saja.
sumber
Saya mencoba ini dan sejauh ini berhasil (tapi saya hanya di Android / Phonegap jadi peringatan emptor)
Saya tidak suka fakta bahwa saya mengikat kembali penangan pada setiap sentuhan, tetapi semua hal yang dianggap sentuhan tidak terlalu sering terjadi (dalam waktu komputer!)
Saya memiliki TON penangan seperti '#keypad' sehingga memiliki fungsi sederhana yang memungkinkan saya menangani masalah tanpa terlalu banyak kode adalah alasan saya menggunakan cara ini.
sumber
Coba gunakan
Virtual Mouse (vmouse) Bindings
darijQuery Mobile
. Ini acara virtual khusus untuk kasus Anda:http://api.jquerymobile.com/vclick/
Daftar dukungan browser: http://jquerymobile.com/browser-support/1.4/
sumber
EDIT: Jawaban saya sebelumnya (berdasarkan jawaban di utas ini) bukan cara yang cocok untuk saya. Saya ingin sub-menu untuk memperluas masuk mouse atau menyentuh klik dan untuk runtuh pada cuti mouse atau klik sentuh lainnya. Karena peristiwa mouse biasanya dipecat setelah peristiwa sentuhan, agak sulit untuk menulis pendengar acara yang mendukung input layar sentuh dan mouse pada saat yang sama.
Plugin jQuery: Sentuh Atau Mouse
Saya akhirnya menulis sebuah plugin jQuery yang disebut " Touch Or Mouse " (diperkecil 897 bytes) yang dapat mendeteksi apakah suatu peristiwa dipanggil oleh layar sentuh atau mouse (tanpa pengujian untuk dukungan sentuh!). Ini memungkinkan dukungan layar sentuh dan mouse secara bersamaan dan benar-benar memisahkan acara mereka.
Dengan cara ini OP dapat menggunakan
touchstart
atautouchend
untuk cepat menanggapi klik sentuhan danclick
untuk klik dipanggil hanya oleh mouse.Demonstrasi
Yang pertama harus dibuat yaitu. acara sentuhan elemen trek:
Peristiwa mouse kami terikat ke elemen dengan cara default dan dengan memanggil
$body.touchOrMouse('get', e)
kami dapat mengetahui apakah acara itu dipanggil oleh layar sentuh atau mouse.Lihat plugin di tempat kerja di http://jsfiddle.net/lmeurs/uo4069nh .
Penjelasan
touchstart
dantouchend
acara, dengan cara initouchend
acara tidak harus diaktifkan pada elemen pemicu (mis. tautan atau tombol). Di antara kedua acara sentuh ini, plugin ini menganggap acara mouse apa pun untuk dipanggil oleh sentuhan.touchend
, ketika acara mouse dipecat di dalamghostEventDelay
(opsi, 1000 ms secara default) setelahtouchend
, plugin ini menganggap acara mouse untuk dipanggil oleh sentuhan.:active
status. Themouseleave
event hanya dipecat setelah elemen kehilangan negara ini dengan yaitu. mengklik elemen lain. Karena ini bisa berupa detik (atau menit!) Setelahmouseenter
acara dipecat, plugin ini melacakmouseenter
acara terakhir elemen : jikamouseenter
acara terakhir dipanggil dengan sentuhan,mouseleave
acara berikut ini juga dianggap dipanggil oleh sentuhan.sumber
Berikut cara mudah untuk melakukannya:
Anda pada dasarnya menyimpan tipe peristiwa pertama yang dipicu ke properti 'pemicu' di objek data jQuery yang dilampirkan ke dokumen root, dan hanya mengeksekusi ketika jenis peristiwa sama dengan nilai dalam 'pemicu'. Pada perangkat sentuh, rantai acara kemungkinan akan menjadi 'layar sentuh' diikuti oleh 'klik'; namun, penangan 'klik' tidak akan dieksekusi karena "klik" tidak cocok dengan jenis acara awal yang disimpan dalam 'pemicu' ("touchstart").
Asumsinya, dan saya yakin itu aman, adalah bahwa ponsel cerdas Anda tidak akan secara spontan berubah dari perangkat sentuh ke perangkat mouse atau jika tidak, ketukan tidak akan pernah mendaftar karena jenis acara 'pemicu' hanya disimpan satu kali per memuat halaman dan "klik" tidak akan pernah cocok dengan "touchstart".
Berikut ini adalah codepen yang dapat Anda mainkan (coba ketuk tombol pada perangkat sentuh - seharusnya tidak ada penundaan klik): http://codepen.io/thdoan/pen/xVVrOZ
Saya juga menerapkan ini sebagai plugin jQuery sederhana yang juga mendukung penyaringan keturunan jQuery dengan mengirimkan string pemilih:
Codepen: http://codepen.io/thdoan/pen/GZrBdo/
sumber
$.data()
untuk menyimpan data yang dapat diakses oleh banyak fungsi namun tidak termasuk dalam lingkup global. Nilai tambahnya adalah karena saya menyimpannya dalam sebuah elemen, itu secara alami memberi saya lebih banyak konteks.Metode terbaik yang saya temukan adalah menulis acara sentuh dan meminta acara itu memanggil acara klik normal secara terprogram. Dengan cara ini Anda memiliki semua acara klik normal dan kemudian Anda perlu menambahkan hanya satu pengendali acara untuk semua acara sentuh. Untuk setiap simpul yang Anda ingin jadikan terjamah, cukup tambahkan kelas "terjamah" ke dalamnya untuk memanggil penangan sentuh. Dengan Jquery berfungsi seperti itu dengan beberapa logika untuk memastikan itu adalah peristiwa sentuhan nyata dan bukan positif palsu.
sumber