Saya sedang mengembangkan aplikasi web (bukan situs web dengan halaman teks yang menarik) dengan antarmuka yang sangat berbeda untuk disentuh (jari Anda menyembunyikan layar saat Anda mengklik) dan mouse (sangat bergantung pada pratinjau kursor). Bagaimana saya bisa mendeteksi bahwa pengguna saya tidak memiliki mouse untuk menyajikan antarmuka yang tepat kepadanya? Saya berencana untuk meninggalkan saklar untuk orang-orang dengan mouse dan sentuhan (seperti beberapa notebook).
Kemampuan acara sentuh di browser sebenarnya tidak berarti pengguna menggunakan perangkat sentuh (misalnya, Modernizr tidak memotongnya). Kode yang menjawab pertanyaan dengan benar harus kembali salah jika perangkat memiliki mouse, benar sebaliknya. Untuk perangkat dengan mouse dan sentuhan, itu harus mengembalikan false (tidak hanya menyentuh)
Sebagai catatan, antarmuka sentuh saya mungkin juga cocok untuk perangkat yang hanya menggunakan keyboard, jadi lebih kekurangan mouse yang ingin saya deteksi.
Agar lebih jelas, berikut adalah API yang ingin saya terapkan:
// Level 1
// The current answers provide a way to do that.
hasTouch();
// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();
// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)
// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);
// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);
sumber
Jawaban:
Masalah utama adalah bahwa Anda memiliki kelas berbeda dari perangkat / kasus penggunaan:
Yang lebih buruk, adalah bahwa seseorang dapat bertransisi dari beberapa kelas ini ke kelas lain (colok mouse, menyambungkan ke keyboard), atau pengguna mungkin TAMPAK berada di laptop biasa sampai mereka menjangkau dan menyentuh layar.
Anda benar dalam menganggap bahwa kehadiran konstruktor acara di browser bukanlah cara yang baik untuk bergerak maju (dan itu agak tidak konsisten). Selain itu, kecuali jika Anda melacak peristiwa yang sangat spesifik atau hanya mencoba untuk mengesampingkan beberapa kelas di atas, menggunakan acara itu sendiri bukanlah bukti penuh.
Misalnya, Anda telah menemukan bahwa pengguna telah mengeluarkan mouse nyata (bukan yang palsu dari acara sentuh, lihat http://www.html5rocks.com/en/mobile/touchandmouse/ ).
Lalu apa?
Anda mengaktifkan gaya melayang? Anda menambahkan lebih banyak tombol?
Apa pun cara Anda meningkatkan waktu untuk kaca karena Anda harus menunggu acara untuk menembak.
Tetapi kemudian apa yang terjadi ketika pengguna mulia Anda memutuskan ingin mencabut mouse-nya dan melakukan sentuhan penuh .. apakah Anda menunggu dia menyentuh antarmuka Anda yang sekarang penuh sesak, lalu mengubahnya tepat setelah dia berupaya untuk menunjukkan UI Anda yang sekarang penuh sesak?
Dalam bentuk bullet, mengutip stucox di https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101
Selain itu: browser TIDAK tahu kapan pengguna menghubungkan mouse / terhubung ke keyboard, tetapi tidak mengeksposnya ke JavaScript .. sial!
Ini akan mengarahkan Anda ke yang berikut:
Namun, gagasan peningkatan progresif cukup baik diterapkan di sini. Bangun pengalaman yang bekerja dengan lancar tidak peduli konteks pengguna. Kemudian buat asumsi berdasarkan fitur peramban / kueri media untuk menambahkan fungsionalitas yang relatif dalam konteks yang diasumsikan. Kehadiran mouse hanyalah salah satu dari banyak cara di mana pengguna yang berbeda pada perangkat yang berbeda mengalami situs web Anda. Buat sesuatu dengan pantas di kernelnya dan jangan terlalu khawatir tentang bagaimana orang mengklik tombol.
sumber
:hover
elemen dan hal-hal seperti itu) ketika pengguna beralih dari mouse ke sentuhan. Tampaknya tidak mungkin bahwa pengguna saat ini menggunakan mouse + touch pada waktu yang sama (maksud saya comoonn itu seperti memiliki 2 mouse yang terhubung ke komputer yang sama hahaha)Bagaimana kalau mendengarkan acara ibu jari di dokumen. Kemudian sampai Anda mendengar peristiwa itu, Anda menganggap bahwa perangkat itu hanya menyentuh atau keyboard.
(Di mana
listen
danunlisten
mendelegasikan keaddEventListener
atau yangattachEvent
sesuai.)Mudah-mudahan ini tidak akan menyebabkan jank visual terlalu banyak, itu akan menyedot jika Anda membutuhkan tata letak ulang besar-besaran berdasarkan mode ...
sumber
Pada 2018 ada cara yang baik dan dapat diandalkan untuk mendeteksi apakah browser memiliki mouse (atau perangkat input serupa): fitur interaksi media CSS4 yang sekarang didukung oleh hampir semua browser modern (kecuali IE 11 dan browser ponsel khusus).
W3C:
Lihat opsi berikut:
Kueri media juga bisa digunakan di JS:
Terkait:
Dokumentasi W3: https://www.w3.org/TR/mediaqueries-4/#mf-interaction
Dukungan browser: https://caniuse.com/#search=media%20features
Masalah serupa: Mendeteksi jika perangkat klien mendukung: hover dan: status fokus
sumber
@ Wyatt jawabannya bagus dan memberi kami banyak hal untuk dipikirkan.
Dalam kasus saya, saya memilih untuk mendengarkan interaksi pertama, hanya kemudian menetapkan perilaku. Jadi, bahkan jika pengguna memiliki mouse, saya akan memperlakukan sebagai perangkat sentuh jika interaksi pertama adalah sentuhan.
Mempertimbangkan urutan yang diberikan di mana acara diproses :
Kita dapat berasumsi bahwa jika acara mouse dipicu sebelum disentuh, ini adalah peristiwa mouse sungguhan, bukan yang ditiru. Contoh (menggunakan jQuery):
Itu berhasil bagi saya
sumber
Ini hanya mungkin untuk mendeteksi jika browser mampu menyentuh . Tidak ada cara untuk mengetahui apakah itu benar-benar memiliki layar sentuh atau mouse yang terhubung.
Orang dapat memprioritaskan penggunaannya dengan mendengarkan acara sentuh alih-alih acara mouse jika kemampuan sentuh terdeteksi.
Untuk mendeteksi kemampuan lintas-browser:
Maka orang dapat menggunakan ini untuk memeriksa:
atau untuk memilih acara mana yang ingin didengarkan, baik:
atau gunakan pendekatan terpisah untuk sentuhan vs non-sentuhan:
Untuk mouse, seseorang hanya dapat mendeteksi jika mouse sedang digunakan, tidak apakah itu ada atau tidak. Seseorang dapat mengatur bendera global untuk menunjukkan bahwa mouse terdeteksi oleh penggunaan (mirip dengan jawaban yang ada, tetapi sedikit disederhanakan):
(orang tidak dapat memasukkan
mouseup
ataumousedown
karena acara ini juga dapat dipicu oleh sentuhan)Browser membatasi akses ke API sistem tingkat rendah yang diperlukan untuk dapat mendeteksi fitur-fitur seperti kemampuan perangkat keras dari sistem yang digunakan.
Ada kemungkinan untuk mungkin menulis plugin / ekstensi untuk mengaksesnya tetapi melalui JavaScript dan DOM deteksi semacam itu terbatas untuk tujuan ini dan orang harus menulis sebuah plugin khusus untuk berbagai platform OS.
Jadi kesimpulannya: deteksi seperti itu hanya dapat diperkirakan dengan "tebakan yang baik".
sumber
Ketika Media Query Level 4 tersedia di browser, kita akan dapat menggunakan kueri "pointer" dan "hover" untuk mendeteksi perangkat dengan mouse.
Jika kami benar-benar ingin mengomunikasikan informasi itu ke Javascript, kami dapat menggunakan kueri CSS untuk mengatur gaya tertentu sesuai dengan jenis perangkat, dan kemudian menggunakan
getComputedStyle
dalam Javascript untuk membaca gaya itu, dan menurunkan jenis perangkat asli darinya.Tetapi mouse dapat dihubungkan atau dicabut kapan saja, dan pengguna mungkin ingin beralih antara sentuhan dan mouse. Jadi kita mungkin perlu mendeteksi perubahan ini, dan menawarkan untuk mengubah antarmuka atau melakukannya secara otomatis.
sumber
any-pointer
danany-hover
akan membiarkan Anda menyelidiki semua kemampuan perangkat yang berlaku. Senang bisa mengintip bagaimana kita bisa memecahkan masalah ini di masa depan! :)Karena Anda berencana menawarkan cara untuk beralih antar antarmuka, apakah mungkin meminta pengguna untuk mengklik tautan atau tombol untuk "memasukkan" versi aplikasi yang benar? Kemudian Anda dapat mengingat preferensi mereka untuk kunjungan di masa mendatang. Ini bukan teknologi tinggi, tetapi 100% dapat diandalkan :-)
sumber
@SamuelRossille Tidak ada peramban yang saya sadari mengekspos keberadaan (atau ketiadaan) mouse, sayangnya.
Jadi, dengan itu dikatakan, kita hanya harus mencoba dan melakukan yang terbaik yang kita bisa dengan pilihan kita yang ada ... acara. Saya tahu itu bukan apa yang Anda cari ... setuju itu saat ini jauh dari ideal.
Kita dapat melakukan yang terbaik untuk mengetahui apakah pengguna menggunakan mouse atau sentuhan pada saat tertentu. Berikut ini adalah contoh cepat dan kotor menggunakan jQuery & Knockout:
Sekarang Anda dapat mengikat / berlangganan menggunakanMouse () & usingTouch () dan / atau gaya antarmuka Anda dengan kelas body.mouse . Antarmuka akan beralih bolak-balik segera setelah kursor mouse terdeteksi dan di layar sentuh.
Mudah-mudahan kita akan memiliki beberapa opsi yang lebih baik dari vendor browser segera.
sumber
Tera-WURFL dapat memberi tahu Anda kemampuan perangkat yang mengunjungi situs Anda dengan membandingkan tanda tangan browser dengan basis datanya. Coba lihat, gratis!
sumber
Mengapa Anda tidak mendeteksi jika memiliki kemampuan untuk merasakan sentuhan dan / atau bereaksi terhadap gerakan mouse?
sumber
has_touch = 'ontouchstart' in window
akan cukup, dan sebagainya.Ini bekerja untuk saya dalam situasi yang sama. Pada dasarnya, anggap pengguna tidak memiliki mouse sampai Anda melihat serangkaian singkat mousemoves berturut-turut, tanpa campur tangan mousedowns atau mouseups. Tidak terlalu elegan, tetapi berhasil.
sumber
Lihat di modenizr salah satu fiturnya adalah touch
http://modernizr.com/docs/#features-misc
Meskipun saya belum diuji sepenuhnya sepertinya berfungsi dengan sangat baik
Juga ini ditautkan dari halaman modernizr http://www.html5rocks.com/en/mobile/touchandmouse/
sumber
Seperti yang telah ditunjukkan oleh orang lain, secara definitif mendeteksi apakah mereka memiliki mouse atau tidak dapat diandalkan. Ini dapat dengan mudah berubah, tergantung pada perangkat. Ini jelas sesuatu yang tidak dapat Anda lakukan dengan andal dengan boolean benar atau salah, setidaknya pada skala dokumen.
Acara sentuh dan acara mouse adalah eksklusif. Jadi ini dapat sedikit membantu dalam mengambil tindakan yang berbeda. Masalahnya adalah acara sentuh lebih dekat dengan mouse atas / bawah / memindahkan acara, dan juga memicu acara klik.
Dari pertanyaan Anda, Anda mengatakan ingin memiliki pratinjau melayang. Selain itu, saya tidak tahu secara spesifik tentang antarmuka Anda. Saya berasumsi bahwa dengan kekurangan mouse Anda ingin mengetuk pratinjau, sementara klik melakukan tindakan yang berbeda karena pratinjau hover.
Jika itu masalahnya, Anda bisa menggunakan pendekatan yang agak malas untuk deteksi:
Acara onclick akan selalu didahului oleh acara onmouseover dengan mouse. Jadi catat bahwa mouse ada di atas elemen yang telah diklik.
Anda bisa melakukan ini dengan acara onmousemove seluruh dokumen. Anda dapat menggunakan
event.target
untuk merekam elemen tempat mouse berada. Kemudian di dalam acara onclick Anda, Anda dapat memeriksa untuk melihat apakah mouse benar-benar di atas elemen yang diklik (atau anak elemen).Dari sana Anda dapat memilih untuk mengandalkan acara klik untuk keduanya dan mengambil tindakan A atau B tergantung pada hasilnya. Tindakan B bisa berupa apa-apa jika beberapa perangkat sentuh tidak memancarkan acara klik (sebagai gantinya Anda harus mengandalkan acara * ontouch).
sumber
Saya tidak berpikir itu mungkin untuk mengidentifikasi perangkat sentuh saja (setahu saya tentu saja). Masalah utama adalah semua acara mouse dan keyboard dipecat oleh perangkat sentuh juga. Lihat contoh berikut, kedua peringatan mengembalikan true untuk perangkat sentuh.
sumber
true
untuk'onmousedown' in window
Ide terbaik menurut saya adalah
mousemove
pendengar (saat ini adalah jawaban teratas). Saya percaya bahwa metode ini perlu sedikit di-tweak. Memang benar bahwa browser berbasis sentuhan meniru bahkan mousemove event, seperti yang Anda lihat dalam diskusi iOS ini , jadi kita harus sedikit berhati-hati.Masuk akal bahwa browser berbasis sentuhan hanya akan meniru acara ini ketika pengguna mengetuk layar (jari pengguna turun). Ini berarti kita harus menambahkan tes selama pengendali mouse kita untuk melihat tombol mouse mana yang turun (jika ada) selama acara berlangsung. Jika tidak ada tombol mouse yang mati, kami dapat dengan aman menganggap mouse asli hadir. Jika tombol mouse mati, tes tetap tidak meyakinkan.
Jadi bagaimana ini diterapkan? Pertanyaan ini menunjukkan bahwa metode yang paling dapat diandalkan untuk memeriksa tombol mouse mana yang mati selama perpindahan mouse adalah dengan benar-benar mendengarkan 3 peristiwa di tingkat dokumen: mouse mouse, mouse mouse dan mouseup. Atas dan ke bawah hanya akan menetapkan bendera boolean global. Langkah tersebut akan melakukan tes. Jika Anda memiliki gerakan dan boolean salah, kita dapat mengasumsikan mouse ada. Lihat pertanyaan untuk contoh kode yang tepat.
Satu komentar terakhir .. Tes ini tidak ideal karena tidak dapat dilakukan dalam waktu buka. Oleh karena itu, saya akan menggunakan metode peningkatan progresif seperti yang disarankan sebelumnya. Secara default, tunjukkan versi yang tidak mendukung antarmuka mouse spesifik mouse. Jika mouse ditemukan, aktifkan mode ini dalam runtime menggunakan JS. Ini akan muncul semulus mungkin bagi pengguna.
Untuk mendukung perubahan dalam konfigurasi pengguna (mis. Mouse telah diputuskan), Anda dapat menguji ulang secara berkala. Meskipun saya percaya akan lebih baik dalam hal ini untuk hanya memberi tahu pengguna tentang 2 mode dan membiarkan pengguna secara manual beralih di antara mereka (sangat mirip dengan pilihan mobile / desktop yang selalu dapat dibalik).
sumber
Menjalankan beberapa tes di berbagai PC, Linux, iPhone, ponsel Android dan tab. Aneh bahwa tidak ada solusi anti peluru yang mudah. Masalah muncul ketika beberapa yang memiliki Sentuh dan tidak ada mouse masih menyajikan acara Sentuh dan Mouse untuk aplikasi. Karena ingin mendukung instance hanya mouse dan sentuh saja, ingin memproses keduanya, tetapi ini menyebabkan dua kali lipat interaksi pengguna. Jika bisa tahu mouse tidak ada di perangkat, maka bisa tahu untuk mengabaikan acara mouse palsu / dimasukkan. Mencoba mengatur flag jika MouseMove ditemukan, tetapi beberapa browser melempar MouseMove palsu serta MouseUp dan MouseDown. Sudah mencoba memeriksa stempel waktu tetapi menganggap ini terlalu berisiko. Intinya: Saya menemukan browser yang menciptakan acara mouse palsu selalu menyisipkan MouseMove tunggal sebelum MouseDown yang dimasukkan. Dalam 99,99% dari kasus saya, saat berjalan pada sistem yang memiliki mouse asli, ada beberapa kejadian MouseMove berturut-turut - setidaknya dua. Jadi, pantau apakah sistem menemukan dua peristiwa MouseMove berturut-turut dan menyatakan tidak ada mouse jika kondisi ini tidak pernah dipenuhi. Ini mungkin terlalu sederhana, tetapi bekerja pada semua pengaturan pengujian saya. Saya pikir saya akan tetap menggunakannya sampai saya menemukan solusi yang lebih baik. - Jim W
sumber
Solusi sederhana di jQuery untuk mendeteksi penggunaan mouse, yang memecahkan masalah di mana perangkat seluler juga memicu acara 'mousemove'. Cukup tambahkan pendengar touchstart untuk menghapus pendengar mousemove, sehingga tidak terpicu saat disentuh.
Tentu saja, perangkat masih bisa menyentuh DAN mouse, tetapi di atas akan menjamin bahwa mouse asli digunakan.
sumber
Baru saja menemukan solusi yang menurut saya cukup elegan.
sumber
Saya mengalami masalah yang sama, di mana satu sentuhan juga terdaftar sebagai klik. Setelah saya membaca komentar dari jawaban terpilih, saya datang dengan solusi saya sendiri:
Satu-satunya masalah yang saya temukan adalah, Anda harus dapat menggulir, untuk mendeteksi acara sentuh dengan benar. satu tab (sentuhan) dapat membuat masalah.
sumber
Saya menghabiskan waktu berjam-jam untuk mencari tahu masalah ini untuk aplikasi Phonegap saya dan saya membuat hack ini. Ini menghasilkan peringatan konsol jika acara yang dipicu adalah peristiwa "pasif", yang berarti tidak mengaktifkan perubahan apa pun, tetapi berhasil! Saya akan tertarik pada ide untuk meningkatkan atau metode yang lebih baik. Tetapi ini secara efektif memungkinkan saya untuk menggunakan $ .touch () secara universal.
sumber
masalah utama yang saya lihat di sini adalah bahwa sebagian besar perangkat sentuh menyalakan sebuah acara mouse bersama dengan sentuhan satu sentuhan (touchstart -> mousedown, touchmove -> mousemove, dll). Hanya untuk keyboard, akhirnya untuk yang modern, mereka memiliki browser generik sehingga Anda bahkan tidak dapat mendeteksi keberadaan kelas MouseEvent.
Solusi yang kurang menyakitkan di sini adalah, menurut pendapat saya, untuk menampilkan menu saat peluncuran (dengan manajemen 'alt' untuk pengguna keyboard saja) dan mungkin menyimpan pilihan dengan localStorage / cookies / serveride atau yang lain untuk menjaga pilihan yang sama berikutnya waktu pengunjung datang.
sumber
Saya sangat merekomendasikan menentang pendekatan ini. Pertimbangkan layar sentuh, perangkat berukuran desktop, dan Anda memiliki serangkaian masalah yang berbeda untuk dipecahkan.
Harap jadikan aplikasi Anda dapat digunakan tanpa mouse (yaitu, tidak ada pratinjau melayang).
sumber
Ingin merekomendasikan skrip yang membantu saya:
Saya telah membaca dan mencoba segala sesuatu yang disarankan, tanpa hasil yang memadai.
Lalu saya menyelidiki lagi, dan menemukan kode ini - device.js
Saya menggunakan ini di situs web klien saya, untuk mendeteksi keberadaan mouse:
(
<html>
seharusnya memilikidesktop
kelas) dan sepertinya cukup bagus, dan untuktouch
dukungan, saya hanya melakukan pemeriksaan rutin'ontouchend' in document
dan menggunakan informasi dari kedua deteksi untuk mengasumsikan hal spesifik yang saya butuhkan.sumber
Pada umumnya ide yang lebih baik untuk mendeteksi jika fungsi mouseover didukung daripada mendeteksi tipe OS / browser. Anda dapat melakukannya hanya dengan yang berikut:
Pastikan Anda tidak melakukan hal berikut:
Yang terakhir sebenarnya akan memanggil metode, daripada memeriksa keberadaannya.
Anda dapat membaca lebih lanjut di sini: http://www.quirksmode.org/js/support.html
sumber