Saya sedang menulis situs Web yang dimaksudkan untuk digunakan dari desktop dan tablet. Saat dikunjungi dari desktop, saya ingin area layar yang dapat diklik menyala dengan :hover
efek (warna latar belakang berbeda, dll.) Dengan tablet, tidak ada mouse, jadi saya tidak ingin efek hover apa pun.
Masalahnya adalah, ketika saya mengetuk sesuatu di tablet, peramban ternyata memiliki semacam "kursor mouse tak terlihat" yang bergerak ke lokasi yang saya ketuk, lalu meninggalkannya di sana - jadi benda yang baru saya ketuk menyala dengan arahkan kursor hingga saya mengetuk yang lain.
Bagaimana saya bisa mendapatkan efek hover saat saya menggunakan mouse, tetapi menahannya saat saya menggunakan layar sentuh?
Seandainya seseorang berpikir untuk menyarankannya, saya tidak ingin menggunakan sniffing agen pengguna. Perangkat yang sama dapat memiliki layar sentuh dan mouse (mungkin tidak begitu umum saat ini, tetapi lebih banyak lagi di masa mendatang). Saya tidak tertarik dengan perangkatnya, saya tertarik dengan cara penggunaannya saat ini: mouse atau layar sentuh.
Saya sudah mencoba mengaitkan touchstart
, touchmove
dan touchend
acara dan memanggil preventDefault()
semua dari mereka, yang tidak menekan "tak terlihat kursor mouse" beberapa waktu; tetapi jika saya mengetuk bolak-balik dengan cepat di antara dua elemen yang berbeda, setelah beberapa ketukan, "kursor mouse" akan mulai menggerakkan "kursor mouse" dan tetap menyalakan efek hover - sepertinya saya preventDefault
tidak selalu dihormati. Saya tidak akan membuat Anda bosan dengan detailnya kecuali jika diperlukan - saya bahkan tidak yakin itu pendekatan yang tepat untuk diambil; jika ada yang memiliki perbaikan yang lebih sederhana, saya mendengarkan.
Sunting: Ini dapat direproduksi dengan CSS standar rawa :hover
, tapi berikut repro cepat untuk referensi.
<style>
.box { border: 1px solid black; width: 150px; height: 150px; }
.box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>
Jika Anda mengarahkan mouse ke salah satu kotak, itu akan mendapatkan latar belakang biru, yang saya inginkan. Tetapi jika Anda mengetuk salah satu kotak, itu juga akan mendapatkan latar belakang biru, yang saya coba cegah.
Saya juga memposting contoh di sini yang melakukan hal di atas dan juga mengaitkan acara mouse jQuery. Anda dapat menggunakannya untuk melihat bahwa peristiwa tap juga akan aktif mouseenter
, mousemove
dan mouseleave
.
sumber
Jawaban:
Saya mengambil dari pertanyaan Anda bahwa efek hover Anda mengubah konten halaman Anda. Dalam hal ini, saran saya adalah:
touchstart
danmouseenter
.mouseleave
,touchmove
danclick
.Alternatifnya, Anda dapat mengedit halaman Anda yang tidak ada perubahan konten.
Latar Belakang
Untuk mensimulasikan mouse, browser seperti Webkit seluler mengaktifkan peristiwa berikut jika pengguna menyentuh dan melepaskan jarinya pada layar sentuh (seperti iPad) (sumber: Touch And Mouse di html5rocks.com):
touchstart
touchmove
touchend
mouseover
mouseenter
mouseover
,mouseenter
ataumousemove
peristiwa mengubah konten halaman, peristiwa berikut tidak pernah diaktifkan.mousemove
mousedown
mouseup
click
Tampaknya tidak mungkin untuk hanya memberi tahu browser web untuk melewati acara mouse.
Yang lebih buruk, jika peristiwa gerakan mouse mengubah konten halaman, peristiwa klik tidak pernah diaktifkan, seperti yang dijelaskan di Panduan Konten Web Safari - Penanganan Acara , khususnya gambar 6.4 di Peristiwa Satu Jari . Apa sebenarnya "perubahan konten" itu, bergantung pada browser dan versinya. Saya telah menemukan bahwa untuk iOS 7.0, perubahan warna latar belakang bukanlah (atau tidak lagi?) Perubahan konten.
Solusi Dijelaskan
Rangkuman:
touchstart
danmouseenter
.mouseleave
,touchmove
danclick
.Perhatikan bahwa tidak ada tindakan
touchend
!Ini jelas berfungsi untuk peristiwa mouse:
mouseenter
danmouseleave
(versi yang sedikit lebih baik darimouseover
danmouseout
) diaktifkan, dan menambah serta menghapus hover.Jika pengguna benar-benar memiliki
click
tautan, efek hover juga dihapus. Ini memastikan bahwa itu dihapus jika pengguna menekan tombol kembali di browser web.Ini juga berfungsi untuk acara sentuh: saat memulai sentuhan, efek melayang ditambahkan. Ini '' 'tidak' '' dihapus pada sentuhan. Itu ditambahkan lagi pada
mouseenter
, dan karena ini tidak menyebabkan perubahan konten (itu sudah ditambahkan),click
acara juga diaktifkan, dan tautan diikuti tanpa perlu pengguna mengeklik lagi!Penundaan 300 md yang dimiliki browser di antara
touchstart
peristiwa danclick
sebenarnya digunakan dengan baik karena efek hover akan ditampilkan selama waktu yang singkat ini.Jika pengguna memutuskan untuk membatalkan klik, gerakan jari akan melakukannya seperti biasa. Biasanya, ini menjadi masalah karena tidak ada
mouseleave
peristiwa yang dipicu, dan efek hover tetap ada. Untungnya, ini dapat dengan mudah diperbaiki dengan menghilangkan efek hovertouchmove
.Itu dia!
Perhatikan bahwa penundaan 300 milidetik dapat dihapus, misalnya menggunakan pustaka FastClick , tetapi ini di luar cakupan pertanyaan ini.
Solusi Alternatif
Saya telah menemukan masalah berikut dengan alternatif berikut:
touchend
: Ini akan mengikuti tautan secara tidak benar, meskipun pengguna hanya ingin menggulir atau memperbesar / memperkecil, tanpa bermaksud untuk benar-benar mengeklik tautan tersebut.touchend
yang digunakan sebagai kondisi-jika dalam peristiwa mouse berikutnya untuk mencegah perubahan status pada saat itu. Variabel disetel ulang dalam acara klik. Lihat jawaban Walter Roman di halaman ini. Ini adalah solusi yang layak jika Anda benar-benar tidak menginginkan efek hover pada antarmuka sentuh. Sayangnya, ini tidak berfungsi jika atouchend
diaktifkan karena alasan lain dan tidak ada peristiwa klik yang diaktifkan (mis. Pengguna menggulir atau memperbesar), dan kemudian mencoba mengikuti tautan dengan mouse (yaitu pada perangkat dengan mouse dan antarmuka sentuh ).Bacaan lebih lanjut
mouseover
ataumousemove
peristiwa.sumber
touchend
alih - alihtouchstart
dalam banyak kasus untuk menghindari memicu tindakan segera ketika pengguna mencoba untuk menggeser-geser ke atas atau ke bawah halaman. Akan tetap terjadi tetapi cenderung tidak mengganggu atau membingungkan (dengan asumsi itu adalah sesuatu yang tidak berbahaya seperti menampilkan label, bukan sesuatu yang perlu diketahui pengguna terjadi)Mungkin tidak menganggapnya sebagai menekan efek hover untuk layar sentuh, tetapi menambahkan efek hover untuk kejadian mouse?
Jika Anda ingin mempertahankan
:hover
efek di CSS, Anda dapat menentukan gaya yang berbeda untuk media yang berbeda:Kecuali sayangnya banyak perangkat seluler yang mengabaikan hal ini dan hanya menggunakan aturan layar. Untungnya, banyak browser seluler / tablet yang lebih baru mendukung beberapa kueri media yang lebih menarik:
Jadi meskipun bagian "layar" atau "genggam" diabaikan, "lebar-maksimal" akan membantu Anda. Anda dapat berasumsi bahwa apa pun dengan layar yang lebih kecil dari 800 piksel pasti merupakan tablet atau ponsel, dan tidak menggunakan efek hover. Untuk pengguna langka yang menggunakan mouse pada perangkat resolusi rendah, mereka tidak akan melihat efek hover tetapi situs Anda akan baik-baik saja jika tidak.
Bacaan lebih lanjut tentang pertanyaan media? Ada banyak artikel tentang online ini - ini salah satunya: http://www.alistapart.com/articles/return-of-the-mobile-stylesheet
Jika Anda menggeser efek hover dari CSS dan menerapkannya dengan JavaScript, maka Anda dapat mengikat secara khusus ke peristiwa mouse, dan / atau lagi Anda bisa membuat beberapa asumsi hanya berdasarkan ukuran layar dengan "masalah" kasus terburuk adalah beberapa pengguna yang menggunakan mouse melewatkan efek hover.
sumber
preventDefault()
, yang terkadang menekan peristiwa mouse, tetapi seperti yang saya katakan dalam pertanyaan saya, itu tidak dapat diandalkan.Saya menulis JS berikut untuk proyek baru-baru ini, yang merupakan situs desktop / seluler / tablet yang memiliki efek hover yang seharusnya tidak muncul saat disentuh.
The
mobileNoHoverState
Modul bawah memiliki variabelpreventMouseover
(awalnya dinyatakan sebagaifalse
), yang diatur untuktrue
saat pengguna kebakarantouchstart
acara pada elemen,$target
.preventMouseover
kemudian disetel kembali kefalse
setiap kalimouseover
peristiwa diaktifkan, yang memungkinkan situs berfungsi sebagaimana mestinya jika pengguna menggunakan layar sentuh dan mouse mereka.Kami tahu itu
mouseover
dipicu setelahnyatouchstart
karena urutan yang dideklarasikan di dalamnyainit
.Modul ini kemudian dibuat instance-nya lebih jauh ke bawah:
sumber
Saya benar-benar menginginkan
css
solusi murni untuk ini sendiri, karena memercikkan solusi javascript yang berat di sekitar semua pandangan saya tampak seperti opsi yang tidak menyenangkan. Terakhir, ditemukan kueri @ media.hover , yang dapat mendeteksi "apakah mekanisme masukan utama memungkinkan pengguna untuk mengarahkan kursor ke elemen". Ini untuk menghindari perangkat sentuh yang "mengarahkan" lebih merupakan tindakan yang diemulasi daripada kemampuan langsung perangkat masukan.Jadi misalnya, jika saya memiliki tautan:
Maka saya dapat dengan aman menatanya hanya
:hover
ketika perangkat dengan mudah mendukungnya dengan inicss
:Meskipun sebagian besar browser modern mendukung kueri fitur media interaksi, beberapa browser populer seperti IE dan Firefox tidak. Dalam kasus saya ini berfungsi dengan baik, karena saya hanya bermaksud untuk mendukung Chrome di desktop dan Chrome dan Safari di seluler.
sumber
Solusi saya adalah menambahkan kelas css hover-active ke tag HTML, dan menggunakannya di awal semua pemilih CSS dengan: arahkan kursor dan hapus kelas itu pada acara touchstart pertama.
http://codepen.io/Bnaya/pen/EoJlb
JS:
HTML:
CSS:
sumber
'ontouchstart' in window
. misalnyaif ('ontouchstart' in window) document.querySelector('html').classList.remove('hover-active');
Apa yang telah saya lakukan untuk memecahkan masalah yang sama adalah memiliki deteksi fitur (saya menggunakan sesuatu seperti kode ini ), melihat apakah onTouchMove didefinisikan, dan jika demikian saya menambahkan kelas css "touchMode" ke tubuh, kalau tidak saya tambahkan " desktopMode ".
Kemudian setiap kali beberapa efek gaya hanya berlaku untuk perangkat sentuh, atau hanya untuk desktop, aturan css diawali dengan kelas yang sesuai:
Sunting : Strategi ini tentu saja menambahkan beberapa karakter tambahan ke css Anda, jadi Jika Anda khawatir tentang ukuran css, Anda dapat mencari definisi touchMode dan desktopMode dan memasukkannya ke dalam file yang berbeda, sehingga Anda dapat menyajikan css yang dioptimalkan untuk setiap perangkat Tipe; atau Anda dapat mengubah nama kelas menjadi lebih pendek sebelum pergi ke prod.
sumber
Benar, saya pertama kali memiliki masalah serupa tetapi berhasil memperbaikinya dengan kueri media dan CSS sederhana. Saya yakin saya melanggar beberapa aturan di sini, tetapi itu berhasil untuk saya.
Saya pada dasarnya harus mengambil aplikasi besar-besaran yang dibuat seseorang, dan membuatnya responsif. Mereka menggunakan jQueryUI dan meminta saya untuk tidak merusak jQuery mereka, jadi saya dibatasi untuk menggunakan CSS saja.
Saat saya menekan salah satu tombol mereka dalam mode layar sentuh, efek hover akan menyala sesaat sebelum tindakan tombol tersebut diterapkan. Begini cara saya memperbaikinya.
sumber
Dalam proyek saya, kami memecahkan masalah ini menggunakan https://www.npmjs.com/package/postcss-hover-prefix dan https://modernizr.com/ Pertama kami memposting file css keluaran dengan
postcss-hover-prefix
. Ia menambahkan.no-touch
untuk semuahover
aturan css .css
menjadi
Saat runtime
Modernizr
secara otomatis menambahkan kelas css kehtml
tag seperti iniPasca-pemrosesan css plus Modernizr menonaktifkan hover untuk perangkat sentuh dan mengaktifkannya untuk perangkat lain. Sebenarnya pendekatan ini terinspirasi oleh Bootstrap 4, bagaimana mereka menyelesaikan masalah yang sama: https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#sticky-hoverfocus-on-mobile
sumber
Anda dapat memicu
mouseLeave
acara setiap kali Anda menyentuh elemen di layar sentuh. Berikut adalah solusi untuk semua<a>
tag:sumber
Iv menemukan 2 solusi untuk masalah ini, yang tersirat bahwa Anda mendeteksi sentuhan dengan modernizr atau sesuatu yang lain dan mengatur kelas sentuh pada elemen html.
Ini bagus tetapi tidak didukung dengan baik:
Tetapi ini memiliki dukungan yang sangat baik :
Bekerja dengan sempurna bagi saya, itu membuat semua efek hover menjadi seperti ketika Anda menyentuh tombol itu akan menyala tetapi tidak berakhir menjadi buggy sebagai efek hover awal untuk acara mouse.
Mendeteksi sentuhan dari perangkat tanpa sentuhan, saya pikir modernizr telah melakukan pekerjaan terbaik:https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.jsEDIT
Saya menemukan solusi yang lebih baik dan lebih sederhana untuk masalah ini
Bagaimana cara menentukan apakah klien adalah perangkat sentuh
sumber
Mungkin membantu untuk melihat CSS Anda, karena ini terdengar seperti masalah yang agak aneh. Tapi bagaimanapun, jika itu terjadi dan semuanya baik-baik saja, Anda bisa mencoba menggeser efek hover ke javascript (Anda juga bisa menggunakan jquery). Cukup, ikat ke gerakan mouse atau lebih baik lagi mouseenter acara dan nyalakan elemen Anda saat acara diaktifkan.
Lihat contoh terakhir di sini: http://api.jquery.com/mouseover/ , Anda dapat menggunakan sesuatu yang mirip dengan log saat acara diaktifkan dan mengambilnya dari sana!
sumber
mouseenter
; tidak ada dadu. Mengetuk akan memindahkan "kursor mouse tak terlihat", sehingga memicumouseenter
danmousemove
(danmouseleave
saat Anda mengetuk di tempat lain).Jika Anda senang menggunakan JavaScript, Anda dapat menggunakan Modernizr di halaman Anda. Saat halaman dimuat, browser non-layar sentuh akan menambahkan kelas '.no-touch' ke tag html, tetapi untuk browser layar sentuh, tag html akan memiliki kelas '.touch' yang ditambahkan ke tag html .
Kemudian ini hanya kasus memeriksa untuk melihat apakah tag html memiliki kelas tanpa sentuhan sebelum memutuskan untuk menambahkan pendengar mouseenter dan mouseleave.
Untuk perangkat layar sentuh, acara tidak akan memiliki pendengar sehingga Anda tidak akan mendapatkan efek hover saat mengetuk.
sumber
.touch
dan.no-touch
. Untuk menulis ulang jawaban Anda dalam CSS bersama dengan Modernizer,html.no-touch .box:hover {background-color: "#0000ff"}
dan tidak mendefinisikan apa pun untukhtml.touch .box:hover
harus melakukan trik, karena OP hanya mencoba untuk menghindari ponsel:hover
.Dalam sebuah proyek yang saya lakukan baru-baru ini, saya memecahkan masalah ini dengan fitur acara yang didelegasikan dari jQuery. Itu mencari elemen tertentu menggunakan selektor jQuery, dan menambahkan / menghapus kelas CSS ke elemen tersebut saat mouse berada di atas elemen. Tampaknya berfungsi dengan baik sejauh yang saya bisa mengujinya, yang mencakup IE10 pada notebook berkemampuan sentuh yang menjalankan Windows 8.
edit: solusi ini, tentu saja, mengharuskan Anda mengubah CSS untuk menghapus pemilih ": hover", dan renungkan terlebih dahulu elemen mana yang Anda inginkan untuk "dapat di-hover".
Jika Anda memiliki sangat banyak elemen di halaman Anda (seperti beberapa ribu) mungkin akan sedikit lambat, karena solusi ini menangkap peristiwa dari tiga jenis pada semua elemen di halaman, dan kemudian melakukan tugasnya jika selektor cocok. Saya menamai kelas CSS "mouseover" bukan "hover", karena saya tidak ingin ada pembaca CSS yang membaca ": hover" tempat saya menulis ".hover".
sumber
Inilah solusi saya: http://jsfiddle.net/agamemnus/g56aw709/-- kode di bawah.
Yang perlu dilakukan hanyalah mengubah ": hover" menjadi ".hover" ... itu saja! Perbedaan besar antara ini dan yang lainnya adalah bahwa ini juga akan berfungsi pada pemilih elemen non-singular seperti
.my_class > *:hover {
.sumber
Sertakan Modernizr di halaman Anda dan atur status hover Anda seperti ini:
sumber
Halo orang dari masa depan, Anda mungkin ingin menggunakan
pointer
dan / atauhover
kueri media. Thehandheld
permintaan Media itu usang.sumber
Coba solusi jquery 2019 yang mudah ini, meskipun sudah ada cukup lama;
tambahkan plugin ini ke head:
src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"
tambahkan ini ke js:
$("*").on("touchend", function(e) { $(this).focus(); }); //applies to all elements
beberapa variasi yang disarankan untuk ini adalah:
Catatan
Referensi:
https://code.jquery.com/ui/
https://api.jquery.com/category/selectors/jquery-selector-extensions/
sumber