Nonaktifkan efek hover di browser seluler


113

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 :hoverefek (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, touchmovedan touchendacara 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 preventDefaulttidak 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, mousemovedan mouseleave.


7
@ Blender, apakah Anda membaca pertanyaannya? Saya sudah menjelaskan mengapa mengendus agen pengguna adalah pilihan yang buruk.
Joe White

Hai Joe, apakah Anda menemukan solusi untuk ini?
Ismatjon

Saya sedang mencari pertanyaan semacam ini, senang saya menemukannya!
agpt

Lihat juga pertanyaan ini, yang berhubungan dengan penonaktifan hover pada perangkat yang mendukung sentuhan, tidak hanya seluler: stackoverflow.com/questions/23885255/…
blade

Jawaban:


83

Saya mengambil dari pertanyaan Anda bahwa efek hover Anda mengubah konten halaman Anda. Dalam hal ini, saran saya adalah:

  • Tambahkan efek hover pada touchstartdan mouseenter.
  • Hapus efek hover pada mouseleave, touchmovedan click.

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):

  1. touchstart
  2. touchmove
  3. touchend
  4. Penundaan 300 md, saat browser memastikan ini adalah satu ketukan, bukan ketukan dua kali
  5. mouseover
  6. mouseenter
    • Catatan : Jika sebuah mouseover, mouseenteratau mousemoveperistiwa mengubah konten halaman, peristiwa berikut tidak pernah diaktifkan.
  7. mousemove
  8. mousedown
  9. mouseup
  10. 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:

  • Tambahkan efek hover pada touchstartdan mouseenter.
  • Hapus efek hover pada mouseleave, touchmovedan click.

Perhatikan bahwa tidak ada tindakan touchend!

Ini jelas berfungsi untuk peristiwa mouse: mouseenterdan mouseleave(versi yang sedikit lebih baik dari mouseoverdan mouseout) diaktifkan, dan menambah serta menghapus hover.

Jika pengguna benar-benar memiliki clicktautan, 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), clickacara juga diaktifkan, dan tautan diikuti tanpa perlu pengguna mengeklik lagi!

Penundaan 300 md yang dimiliki browser di antara touchstartperistiwa dan clicksebenarnya 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 mouseleaveperistiwa yang dipicu, dan efek hover tetap ada. Untungnya, ini dapat dengan mudah diperbaiki dengan menghilangkan efek hover touchmove.

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:

  • Deteksi browser: Sangat rentan terhadap kesalahan. Mengasumsikan bahwa perangkat memiliki mouse atau sentuhan, sedangkan kombinasi keduanya akan menjadi semakin umum saat layar sentuh berkembang biak.
  • Deteksi media CSS: Satu-satunya solusi khusus CSS yang saya ketahui. Masih rentan terhadap kesalahan, dan masih menganggap bahwa perangkat memiliki mouse atau sentuhan, sementara keduanya memungkinkan.
  • Tiru peristiwa klik dalam touchend: Ini akan mengikuti tautan secara tidak benar, meskipun pengguna hanya ingin menggulir atau memperbesar / memperkecil, tanpa bermaksud untuk benar-benar mengeklik tautan tersebut.
  • Gunakan variabel untuk menekan peristiwa mouse: Ini menetapkan variabel touchendyang 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 a touchenddiaktifkan 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


1
Jawaban bagus. Saya menggunakan biola Anda untuk mulai membuat solusi saya sendiri. Namun sentuhan terkadang dibutuhkan. (ketika touchmove tidak berjalan - yaitu ketika pengguna keluar dari dokumen itu sendiri ...)
Agamemnus

Jawaban yang bagus tetapi dalam banyak kasus, saya menyarankan untuk menggunakan 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)
user56reinstatemonica8

19

Bagaimana saya bisa mendapatkan efek hover saat saya menggunakan mouse, tetapi menahannya saat saya menggunakan layar sentuh?

Mungkin tidak menganggapnya sebagai menekan efek hover untuk layar sentuh, tetapi menambahkan efek hover untuk kejadian mouse?

Jika Anda ingin mempertahankan :hoverefek di CSS, Anda dapat menentukan gaya yang berbeda untuk media yang berbeda:

@media screen { /* hover styles here */ } 

@media handheld { /* non-hover styles here */ }

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:

@media screen and (max-width:800px) { /* non-hover styles here */ }

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.


Saya ingin menambahkan efek hover untuk event mouse saja. Namun peristiwa sentuh meniru peristiwa mouse. Jika saya mengaitkan peristiwa sentuh dan panggilan preventDefault(), yang terkadang menekan peristiwa mouse, tetapi seperti yang saya katakan dalam pertanyaan saya, itu tidak dapat diandalkan.
Joe White

6
Adapun pertanyaan media, apa yang terjadi ketika Windows 8 keluar dan PC memiliki layar sentuh dan mouse? Jika pengguna mengarahkan mouse, mereka akan melihat kursor mouse, dan saya ingin efek hover; jika mereka mengetuk dengan layar sentuh, saya tidak ingin efek hover. Tetapi saya belum menemukan cara yang dapat diandalkan untuk mendeteksi perbedaan antara sentuhan dan mouse.
Joe White

Mungkin pengembang browser akan lebih termotivasi untuk membuat deteksi lebih konsisten setelah mereka memiliki lebih banyak pengguna pada perangkat dengan sentuhan dan mouse. Tapi untuk sekarang? Saya akan membuat tebakan berdasarkan ukuran layar, tetapi ada saran lain di jawaban lain. Maaf saya tidak bisa membantu lebih lanjut.
nnnnnn

9

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 mobileNoHoverStateModul bawah memiliki variabel preventMouseover(awalnya dinyatakan sebagai false), yang diatur untuk truesaat pengguna kebakaran touchstartacara pada elemen, $target.

preventMouseoverkemudian disetel kembali ke falsesetiap kali mouseoverperistiwa diaktifkan, yang memungkinkan situs berfungsi sebagaimana mestinya jika pengguna menggunakan layar sentuh dan mouse mereka.

Kami tahu itu mouseoverdipicu setelahnya touchstartkarena urutan yang dideklarasikan di dalamnya init.

var mobileNoHoverState = function() {

    var hoverClass = 'hover',
        $target = $(".foo"), 
        preventMouseover = false;

    function forTouchstart() {
        preventMouseover = true;
    }

    function forMouseover() {
        if (preventMouseover === false) {
            $(this).addClass(hoverClass);
        } else {
            preventMouseover = false;
        }
    }

    function forMouseout() {
        $(this).removeClass(hoverClass);
    }

    function init() {
        $target.on({
            touchstart  : forTouchstart,
            mouseover   : forMouseover,
            mouseout    : forMouseout
        });                
    }

    return {
        init: init
    };
}();

Modul ini kemudian dibuat instance-nya lebih jauh ke bawah:

mobileNoHoverState.init();

"preventMouseover kemudian disetel kembali ke true setiap kali peristiwa gerakan mouse diaktifkan, yang memungkinkan situs berfungsi sebagaimana mestinya jika pengguna menggunakan layar sentuh dan mouse mereka." - Kode Anda tidak melakukan itu. Apakah saya melewatkan sesuatu?
Redtopia

@Redtopia Terima kasih atas perhatiannya! Saya telah memperbarui jawaban dengan sedikit kode yang tertinggal.
Walter Roman

Anda tidak perlu titik koma setelah deklarasi fungsi
nacholibre

@nacholibre Penggunaan titik koma yang tepat telah diterapkan
Walter Roman

6

Saya benar-benar menginginkan csssolusi 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:

<a href="/" class="link">Home</a>

Maka saya dapat dengan aman menatanya hanya :hoverketika perangkat dengan mudah mendukungnya dengan ini css:

@media (hover: hover) {
  .link:hover { /* hover styles */ }
}

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.


Solusi bagus yang tampaknya berfungsi saat Anda mengemulasi perangkat di devtools Chrome. Tapi masih tidak berfungsi untuk Chrome Android :-(
Sjeiti

Saya rasa ini adalah solusi yang paling nyaman dan tepat. Berharap ini akan segera ditambahkan ke standar W3C.
GProst

5

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:

(function () {
    'use strict';

    if (!('addEventListener' in window)) {
        return;
    }

    var htmlElement = document.querySelector('html');

    function touchStart () {
        document.querySelector('html').classList.remove('hover-active');

        htmlElement.removeEventListener('touchstart', touchStart);
    }

    htmlElement.addEventListener('touchstart', touchStart);
}());

HTML:

<html class="hover-active">

CSS:

.hover-active .mybutton:hover {
    box-shadow: 1px 1px 1px #000;
}

Alih-alih mendengarkan acara sentuh, Anda dapat mengujinya 'ontouchstart' in window. misalnyaif ('ontouchstart' in window) document.querySelector('html').classList.remove('hover-active');
Yuval A.

@Yu. Alasan saya menunggu acara sentuh karena ada perangkat dengan penunjuk dan dukungan sentuh, dan pengguna menggunakan penunjuk, saya tidak ingin menghapus kursor. Mungkin saja pengguna akan menggunakan sentuhan dan kemudian penunjuk tetapi saya tidak memiliki banyak hal untuk dilakukan tentang itu
Bnaya

2

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:

.desktopMode .someClass:hover{ color: red }
.touchMode .mainDiv { width: 100%; margin: 0; /*etc.*/ }

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.


2

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.

@media only screen and (max-width:1024px) {

       #buttonOne{
            height: 44px;
        }


        #buttonOne:hover{
            display:none;
        }
}   

2

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-touchuntuk semua hoveraturan css .

const fs = require("fs");
const postcss = require("postcss");
const hoverPrfx = require("postcss-hover-prefix");

var css = fs.readFileSync(cssFileName, "utf8").toString();
postcss()
   .use(hoverPrfx("no-touch"))
   .process(css)
   .then((result) => {
      fs.writeFileSync(cssFileName, result);
   });

css

a.text-primary:hover {
  color: #62686d;
}

menjadi

.no-touch a.text-primary:hover {
  color: #62686d;
}

Saat runtime Modernizrsecara otomatis menambahkan kelas css ke htmltag seperti ini

<html class="wpfe-full-height js flexbox flexboxlegacy canvas canvastext webgl 
  no-touch 
  geolocation postmessage websqldatabase indexeddb hashchange
  history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage
  borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients
  cssreflections csstransforms csstransforms3d csstransitions fontface
  generatedcontent video audio localstorage sessionstorage webworkers
  applicationcache svg inlinesvg smil svgclippaths websocketsbinary">

Pasca-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


1

Anda dapat memicu mouseLeaveacara setiap kali Anda menyentuh elemen di layar sentuh. Berikut adalah solusi untuk semua <a>tag:

function removeHover() {
    var anchors = document.getElementsByTagName('a');
    for(i=0; i<anchors.length; i++) {
        anchors[i].addEventListener('touchstart', function(e){
            $('a').mouseleave();
        }, false);
    }
}

JSHint mengatakan "jangan membuat fungsi dalam satu lingkaran".
NetOperator Wibby

Ini hack. Ini BUKAN kode yang dapat digunakan kembali yang dapat dianggap sebagai praktik yang baik. @NetOatorByBby
Kata Kholwandi

Memang tidak terlalu membantu untuk memposting kode yang tidak dapat dianggap sebagai praktik yang baik. Itu seperti memasang plester pada luka pisau.
NetOperator Wibby

1

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:

html.touch *:hover {
    all:unset!important;
}

Tetapi ini memiliki dukungan yang sangat baik :

html.touch *:hover {
    pointer-events: none !important;
}

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.js

EDIT

Saya menemukan solusi yang lebih baik dan lebih sederhana untuk masalah ini

Bagaimana cara menentukan apakah klien adalah perangkat sentuh


0

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!


Tidak ada yang istimewa tentang CSS; lihat hasil edit saya. Dan saya sudah mencoba mouseenter; tidak ada dadu. Mengetuk akan memindahkan "kursor mouse tak terlihat", sehingga memicu mouseenterdan mousemove(dan mouseleavesaat Anda mengetuk di tempat lain).
Joe White

0

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.

if($('html').hasClass('no-touch')){
    $('.box').on("mouseenter", function(event){
            $(this).css('background-color','#0000ff')
    });
    $('.box').on("mouseleave", function(event){
            $(this).css('background-color','')
    });
}

Untuk perangkat layar sentuh, acara tidak akan memiliki pendengar sehingga Anda tidak akan mendapatkan efek hover saat mengetuk.


Ketika itu bisa dilakukan dengan css jangan gunakan javascript (jquery) itu membuang-buang tenaga komputer
Simon Dragsbæk

1
Lebih sederhana lagi, di CSS Anda, Anda dapat menentukan aturan terpisah untuk .touchdan .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 untuk html.touch .box:hoverharus melakukan trik, karena OP hanya mencoba untuk menghindari ponsel :hover.
Walter Roman

0

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.

$(document).ready(
    function()
    {
        // insert your own selector here: maybe '.hoverable'?
        var selector = 'button, .hotspot';

        $('body')
            .on('mouseover', selector, function(){ $(this).addClass('mouseover');    })
            .on('mouseout',  selector, function(){ $(this).removeClass('mouseover'); })
            .on('click',     selector, function(){ $(this).removeClass('mouseover'); });
    }
);

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".


0

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 {.

handle_css_hover_effects ()

function handle_css_hover_effects (init) {
 var init = init || {}
 var handle_touch_events = init.handle_touch_events || true
 var handle_mouse_events = init.handle_mouse_events || true
 var hover_class         = init.hover_class         || "hover"
 var delay_preferences   = init.delay_preferences   || {touch: {add: 500, remove: 500}}
 function default_handler (curobj, input_type, op) {
  var hovered_element_selector = "*" + ((op == "add") ? ":" : ("." + hover_class))
  var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll(hovered_element_selector))
  var modified_list = []
  while (true) {
   if ((curobj == null) || (curobj == document.documentElement)) break
   if (hovered_elements.indexOf(curobj) != -1) modified_list.push (curobj)
   curobj = curobj.parentNode
  }
  function do_hover_change () {modified_list.forEach (function (curobj) {curobj.classList[op](hover_class)})}
  if ((!delay_preferences[input_type]) || (!delay_preferences[input_type][op])) {
   do_hover_change ()
  } else {
   setTimeout (do_hover_change, delay_preferences[input_type][op])
  }
 }

 if (handle_mouse_events) {
  document.body.addEventListener ('mouseover' , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "add")})
  document.body.addEventListener ('mouseout'  , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "remove")})
  document.body.addEventListener ('click'     , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "remove")})
 }

 if (handle_touch_events) {
  document.body.addEventListener ('touchstart', function (evt) {var curobj = evt.target; default_handler (curobj, "touch", "add")})
  document.body.addEventListener ('touchend'  , function (evt) {var curobj = evt.target; default_handler (curobj, "touch", "remove")})
  document.body.addEventListener ('touchmove',  function (evt) {
   var curobj = evt.target
   var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll("*:hover"))
   var lastobj = null
   evt = evt.changedTouches[0]
   var elements_at_point = get_elements_at_point (evt.pageX, evt.pageY)
   // Get the last element that isn't at the current point but is still hovered over, and remove only its hover attribute.
   while (true) {
    if ((curobj == null) || (curobj == document.documentElement)) break
    if ((hovered_elements.indexOf(curobj) != -1) && (elements_at_point.indexOf(curobj) == -1)) lastobj = curobj
    curobj = curobj.parentNode
   }
   if (lastobj == null) return
   if ((!delay_preferences.touch) || (!delay_preferences.touch.remove)) {
    lastobj.classList.remove(hover_class)
   } else {
    setTimeout (function () {lastobj.classList.remove(hover_class)}, delay_preferences.touch.remove)
   }

   function get_elements_at_point (x, y) {
    var el_list = [], pe_list = []
    while (true) {
     var curobj = document.elementFromPoint(x, y)
     if ((curobj == null) || (curobj == document.documentElement)) break
     el_list.push (curobj); pe_list.push (curobj.style.pointerEvents)
     curobj.style.pointerEvents = "none"
    }
    el_list.forEach (function (current_element, i) {current_element.style.pointerEvents = pe_list[i]})
    return el_list
   }
  })
 }
}


0

Halo orang dari masa depan, Anda mungkin ingin menggunakan pointerdan / atau hoverkueri media. The handheldpermintaan Media itu usang.

/* device is using a mouse or similar */
@media (pointer: fine) {
  a:hover {
    background: red;
  }
}

-1

Coba solusi jquery 2019 yang mudah ini, meskipun sudah ada cukup lama;

  1. tambahkan plugin ini ke head:

    src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"

  2. tambahkan ini ke js:

    $("*").on("touchend", function(e) { $(this).focus(); }); //applies to all elements

  3. beberapa variasi yang disarankan untuk ini adalah:

    $(":input, :checkbox,").on("touchend", function(e) {(this).focus);}); //specify elements
    
    $("*").on("click, touchend", function(e) { $(this).focus(); });  //include click event`
    
    css: body { cursor: pointer; } //touch anywhere to end a focus`

Catatan

  • tempatkan plugin sebelum bootstrap.js, jika ada, untuk menghindari pengaruh tooltips
  • hanya diuji di iphone XR ios 12.1.12, dan ipad 3 ios 9.3.5, menggunakan Safari atau Chrome.

Referensi:

https://code.jquery.com/ui/

https://api.jquery.com/category/selectors/jquery-selector-extensions/

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.