Masalah hover iPad / iPhone menyebabkan pengguna melakukan double click pada sebuah link


125

Saya memiliki beberapa situs web yang saya buat beberapa waktu lalu, yang menggunakan acara mouse jquery ... Saya baru saja mendapat ipad dan saya perhatikan bahwa semua peristiwa mouse di atas diterjemahkan dalam klik ... jadi misalnya saya harus melakukan dua klik, bukan satu .. (arahkan kursor pertama, daripada klik sebenarnya)

apakah ada solusi yang siap untuk mengatasi ini? mungkin perintah jquery yang harus saya gunakan sebagai pengganti mouseover / out dll .. terima kasih!


1
terikat acara apa misal, acara onclick seharusnya berfungsi dengan baik ... onmouseover, onmouseout, dan CSS: hover adalah yang agak sulit ditangani karena tidak ada "hover" yang tersedia untuk layar sentuh. Apakah Anda memiliki contoh kode?
scunliffe

Satu hal yang saya sarankan Anda lakukan adalah memikirkan kembali antarmuka Anda jika memungkinkan. interaksi di ipad / iphone tidak persis sama dengan yang ada di pc, dan mungkin hal yang bijaksana untuk membuat situs web Anda terasa seperti dibuat untuk ipad / iphone / perangkat sentuh lain dengan mekanisme multitouch serupa. Hanya pemikiran saja.
jer

Saya setuju dengan "jer". Ini adalah pertanyaan yang aneh, menurut saya solusi di sini bukanlah "solusi" secara pribadi. Menurut saya, menerjemahkan "mouse hover" di browser desktop menjadi "tap jari" di browser layar sentuh masuk akal. Jika Anda setuju dengan terjemahan itu, tetapi ingin satu ketukan, bukan dua, maka saya mungkin akan melakukan deteksi fitur untuk acara iPad (misalnya "touchstart") dan mengubah penangan acara Anda. Mungkin ekstrak kode Anda ke dalam jenis fungsi "sentuh atau klik" plugin jquery yang diaktifkan secara berbeda berdasarkan fitur, tetapi tampaknya khusus untuk situs web / aplikasi Anda bagi saya.
Andy Atkinson

1
Saya sebenarnya menganggap terjemahan ini sebagai fitur. Jika Anda memiliki penyiapan peristiwa hover, pasti ada beberapa utilitas untuk melihatnya. Satu ketukan mengungkapkan elemen yang di-hover, ketukan kedua mengikuti link "di belakang" hover.
Aaron

Jawaban:


205

Belum menguji ini sepenuhnya tetapi karena iOS mengaktifkan peristiwa sentuh, ini dapat berfungsi, dengan asumsi Anda berada dalam pengaturan jQuery.

$('a').on('click touchend', function(e) {
    var el = $(this);
    var link = el.attr('href');
    window.location = link;
});

Idenya adalah WebKit Seluler mengaktifkan touchendperistiwa di akhir ketukan sehingga kami mendengarkannya dan kemudian mengarahkan ulang browser segera setelah touchendperistiwa diaktifkan di tautan.


17
Di mana hadiah saya? : P
cduruk

2
Sabar, Padwan. SO mengatakan perlu 24 jam untuk diterapkan.
Andrew Hedges

2
Pada jQuery 1.7, .onlebih disukai .live. Setelah membaca jawaban ini, saya menemukan bahwa mengubah kode saya $('a').on('click touchend', function(e) {...})berfungsi dengan sangat baik.
Blazemonger

23
Nah, ini memecahkan masalah awal, tetapi membuat yang baru: Saat menggesek diklik. Ini bukanlah solusi.
luksak

9
Ini ada kekurangannya. Jika Anda mengklik link, target="_blank"maka link tersebut akan terbuka di jendela yang sama DAN di jendela baru.
rybo111

37

Pertanyaan Anda tidak sepenuhnya jelas, tetapi jika Anda hanya ingin menghilangkan klik dua kali, sambil mempertahankan efek hover untuk mouse, saran saya adalah:

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

Latar Belakang

Untuk mensimulasikan mouse, browser seperti Webkit seluler mengaktifkan peristiwa berikut jika pengguna menyentuh dan melepaskan jarinya di 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 Peristiwa , 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 clicklink, efek hover juga dihapus. Ini memastikan bahwa itu dihapus jika pengguna menekan tombol kembali di browser web.

Ini juga berfungsi untuk acara sentuh: pada touchstartefek hover ditambahkan. Ini '' 'tidak' '' dihapus pada touchend. 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 md dapat dihapus, misalnya menggunakan pustaka FastClick , tetapi hal 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. 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

Lihat juga masalah klik ganda iPad / iPhone dan Nonaktifkan efek hover di browser seluler .


2
Sepertinya penjelasan terbaik bagi mereka yang menginginkan solusi masalah yang lebih tepat. Thanx
antiplayer

Terima kasih khusus atas informasi tentang warna latar belakang untuk> iOS7. Saya menghabiskan beberapa waktu mencoba mencari tahu kapan ini mulai berhasil.
staffang

20

Sepertinya ada solusi CSS. Alasan Safari menunggu sentuhan kedua adalah karena gambar latar belakang (atau elemen) yang biasanya Anda tetapkan pada acara: hover. Jika tidak ada untuk ditampilkan - Anda tidak akan mengalami masalah. Solusinya adalah menargetkan platform iOS dengan file CSS sekunder (atau gaya dalam kasus pendekatan JS) yang menimpa: arahkan kursor ke latar belakang untuk mewarisi misalnya dan tetap menyembunyikan elemen yang akan Anda tampilkan di atas mouse:

Berikut ini contoh CSS dan HTML - blok produk dengan label berbintang di atas mouse:

HTML:

<a href="#" class="s"><span class="s-star"></span>Some text here</a>

CSS:

.s {
   background: url(some-image.png) no-repeat 0 0;

}
.s:hover {
   background: url(some-image-r.png) no-repeat 0 0;
}

.s-star {
   background: url(star.png) no-repeat 0 0;
   height: 56px;
   position: absolute;
   width: 72px;
   display:none;
}

.s:hover .s-star {
   display:block;
}

Solusi (CSS sekunder):

/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
   background:inherit;
}
.s:hover .s-star {
   display:none;
}


Jawaban ini ditujukan untuk gambar latar belakang, tetapi apakah Anda memiliki solusi untuk perubahan opasitas sederhana? Solusi ini tidak berfungsi untuk ini.
Ian S

5

Tak perlu bikin ribet.

$('a').on('touchend', function() {
    $(this).click();
});

5

Apa yang berhasil bagi saya adalah apa yang dikatakan orang lain di sini:

Jangan tampilkan / sembunyikan elemen di hover atau mousemove (yang merupakan acara dalam kasus saya).

Inilah yang dikatakan Apple ( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ):

Elemen yang dapat diklik adalah tautan, elemen bentuk, area peta gambar, atau elemen lainnya dengan penangan mousemove, mousedown, mouseup, atau onclick

Jika pengguna menge-tap elemen yang dapat diklik, peristiwa tiba dalam urutan ini: gerakan mouse, gerakan mouse, gerakan mouse, gerakan mouse, gerakan mouse, dan klik. Selain itu, jika konten halaman berubah pada peristiwa mousemove, tidak ada peristiwa berikutnya dalam urutan yang dikirim. Perilaku ini memungkinkan pengguna untuk mengetuk konten baru.

Jadi, Anda dapat menggunakan solusi @ woop: deteksi userAgent, periksa apakah itu dan perangkat iOS dan kemudian ikat acara tersebut. Saya akhirnya menggunakan teknik ini karena sesuai dengan kebutuhan saya dan lebih masuk akal untuk tidak mengikat peristiwa hover saat Anda tidak menginginkannya.

Tapi ... jika Anda tidak ingin main-main dengan userAgents dan masih menyembunyikan / menampilkan elemen di hover / mousemove, saya menemukan Anda dapat melakukannya dengan menggunakan javascript asli, seperti ini:

$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});

Ini akan berfungsi pada versi Desktop dan tidak akan melakukan apa pun pada versi seluler.

Dan untuk kompatibilitas yang lebih sedikit ...

$("body").on("mouseover", function() {
   if (document.getElementsByTagName && document.querySelector) { // check compatibility
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
    } else {
        $(".my-class").show();
        $(".my-selector div").hide();
    }
});

1
Bit itu "jika konten halaman berubah pada acara mousemove, tidak ada acara berikutnya dalam urutan yang dikirim" benar-benar berhasil untuk saya. Saya memiliki halaman di mana tautan tajuk akan memerlukan ketukan dua kali di mana tombol dalam konten (dengan semua transisi css3 yang bahagia di em) hanya akan membutuhkan satu ketukan. Tampak bahwa link header memiliki elemen semu yang berubah dari opacity: 0 menjadi opacity: 1 saat hover. Menghapus efek itu segera menyelesaikan masalah dan saya menemukan solusi CSS untuk tetap mendapatkan tampilan yang saya inginkan.
Fake Haak

3

Solusi cduruk cukup efektif, tetapi menyebabkan masalah di beberapa bagian situs saya. Karena saya sudah menggunakan jQuery untuk menambahkan kelas hover CSS, solusi termudah adalah dengan tidak menambahkan kelas hover CSS di perangkat seluler (atau lebih tepatnya, HANYA menambahkannya saat BUKAN di perangkat seluler).

Inilah gagasan umumnya:

var device = navigator.userAgent.toLowerCase();
var ios = device.match(/(iphone|ipod|ipad)/);

if (!(ios)) {
    $(".portfolio-style").hover(
        function(){
            $(this).stop().animate({opacity: 1}, 100);
            $(this).addClass("portfolio-red-text");
        },
        function(){
            $(this).stop().animate({opacity: 0.85}, 100);
            $(this).removeClass("portfolio-red-text");
        }
    );
}

* kode dikurangi untuk tujuan ilustrasi


1
Ini jelas jawabannya. "Solusi" lainnya tidak memperbaiki masalah. Safari iOS jelas cacat karena berpikir bahwa kami ingin mengarahkan kursor terlebih dahulu. OS lain memiliki fitur hover yang sebenarnya ketika Anda mengarahkan kursor ke item.
Joshua Pack

Ini adalah satu-satunya hal yang berhasil bagi saya. Terima kasih banyak!
tx291

2

Saya pikir akan bijaksana untuk mencoba mouseentermenggantikan mouseover. Itu yang digunakan secara internal saat mengikat .hover(fn,fn)dan biasanya yang Anda inginkan.


1

Saya memiliki masalah berikut dengan solusi yang ada, dan menemukan sesuatu yang tampaknya menyelesaikan semuanya. Ini mengasumsikan Anda membidik sesuatu lintas browser, lintas perangkat, dan tidak ingin perangkat mengendus.

Masalah yang dipecahkan ini

Menggunakan hanya touchstartatau touchend:

  • Menyebabkan peristiwa diaktifkan ketika orang-orang mencoba untuk menggulir melewati konten dan kebetulan jari mereka di atas elemen ini ketika mereka mulai menggesek - memicu tindakan secara tidak terduga.
  • Dapat menyebabkan acara diaktifkan di longpress , mirip dengan klik kanan di desktop. Misalnya, jika peristiwa klik Anda menuju ke URL X, dan pengguna lama menekan untuk membuka X di tab baru, pengguna akan bingung menemukan X terbuka di kedua tab. Pada beberapa browser (misalnya iPhone) bahkan mungkin mencegah menu tekan lama muncul.

Memicu mouseoveracara di touchstartdan mouseoutdi touchmovememiliki konsekuensi kurang serius, tetapi tidak mengganggu perilaku browser biasa, misalnya:

  • Tekanan yang lama akan memicu gerakan mouse yang tidak pernah berakhir.
  • Banyak browser Android memperlakukan lokasi jari di touchstartseperti mouseover, yang akan mouseoutdiedit berikutnya touchstart. Oleh karena itu, salah satu cara untuk melihat konten gerakan mouse di Android adalah dengan menyentuh area yang diinginkan dan menggoyangkan jari Anda, menggulir laman sedikit. Memperlakukan touchmovesebagai mouseoutistirahat ini.

Solusinya

Secara teori, Anda bisa menambahkan bendera dengan touchmove, tetapi iPhone memicu gerakan sentuh meskipun tidak ada gerakan. Secara teori, Anda bisa membandingkan touchstartdan touchendacara pageXdan pageY tapi di iPhone, tidak ada touchend pageXataupageY .

Jadi sayangnya untuk mencakup semua pangkalan itu berakhir sedikit lebih rumit.

$el.on('touchstart', function(e){
    $el.data('tstartE', e);
    if(event.originalEvent.targetTouches){
        // store values, not reference, since touch obj will change
        var touch = e.originalEvent.targetTouches[0];
        $el.data('tstartT',{ clientX: touch.clientX, clientY: touch.clientY } );
    }
});
$el.on('touchmove', function(e){
    if(event.originalEvent.targetTouches){
        $el.data('tstartM', event.originalEvent.targetTouches[0]);
    }
});

$el.on('click touchend', function(e){
    var oldE = $el.data('tstartE');
    if( oldE && oldE.timeStamp + 1000 < e.timeStamp ) {
        $el.data('tstartE',false);
        return;
    }
    if( $el.data('iosTouchM') && $el.data('tstartT') ){
        var start = $el.data('tstartT'), end = $el.data('tstartM');
        if( start.clientX != end.clientX || start.clientY != end.clientY ){
            $el.data('tstartT', false);
            $el.data('tstartM', false);
            $el.data('tstartE',false);
            return;
        }
    }
    $el.data('tstartE',false);

Secara teori, ada cara untuk mendapatkan waktu yang tepat yang digunakan untuk longpress daripada hanya menggunakan 1000 sebagai perkiraan, tetapi dalam praktiknya tidak sesederhana itu dan yang terbaik adalah menggunakan proxy yang masuk akal .


1

Jawaban MacFreak sangat membantu saya. Berikut beberapa kode praktis jika itu membantu Anda.

MASALAH - menerapkan sentuhan berarti setiap kali Anda menggulirkan jari Anda di atas suatu elemen, itu merespons seolah-olah Anda telah menekannya, bahkan jika Anda hanya mencoba untuk menggulir melewati.

Saya membuat efek dengan jQuery yang memudar baris di bawah beberapa tombol untuk "menyorot" tombol yang melayang. Saya tidak ingin ini berarti Anda harus menekan tombol dua kali pada perangkat sentuh untuk mengikuti tautan.

Berikut tombol-tombolnya:

<a class="menu_button" href="#">
    <div class="menu_underline"></div>
</a>

Saya ingin div "menu_underline" memudar saat gerakan mouse dan menghilang saat mouseout. TAPI saya ingin perangkat sentuh dapat mengikuti tautan dengan satu klik, bukan dua.

SOLUSI - Inilah jQuery untuk membuatnya berfungsi:

//Mouse Enter
$('.menu_button').bind('touchstart mouseenter', function(){
    $(this).find(".menu_underline").fadeIn();
});

//Mouse Out   
$('.menu_button').bind('mouseleave touchmove click', function(){
    $(this).find(".menu_underline").fadeOut();
});

Terima kasih banyak atas bantuan Anda di MacFreak ini.


1

Saya baru tahu bahwa ini berfungsi jika Anda menambahkan pendengar kosong, jangan tanya mengapa, tetapi saya mengujinya di iPhone dan iPad dengan iOS 9.3.2 dan berfungsi dengan baik.

if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
    var elements = document.getElementsByTagName('a');
    for(var i = 0; i < elements.length; i++){
        elements[i].addEventListener('touchend',function(){});
    }
}


0

Saya memiliki masalah yang sama tetapi tidak pada perangkat sentuh. Peristiwa dipicu setiap kali Anda mengklik. Ada sesuatu tentang antrian acara atau lebih.

Namun, solusi saya seperti ini: Saat acara diklik (atau sentuh?) Anda menyetel pengatur waktu. Jika tautan diklik lagi dalam X ms, Anda hanya mengembalikan false.

Untuk mengatur per timer elemen, Anda dapat menggunakan $.data().

Ini juga dapat memperbaiki masalah @Ferdy yang dijelaskan di atas.


Dapatkah Anda memposting seperti apa kode ini? Saya mengalami masalah peristiwa klik yang dipicu dua kali.
mewah

0

Jika Anda menggunakan Modernizr, sangat mudah untuk menggunakan Modernizr.touch seperti yang disebutkan sebelumnya.

Namun, saya lebih suka menggunakan kombinasi Modernizr.touch dan pengujian agen pengguna, agar aman.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

function Tipsy(element, options) {
    this.$element = $(element);
    this.options = options;
    this.enabled = !isTouchDevice;
    this.fixTitle();
};

Jika Anda tidak menggunakan Modernizr, Anda cukup mengganti Modernizr.touchfungsi di atas dengan('ontouchstart' in document.documentElement)

Perhatikan juga bahwa menguji iemobile agen pengguna akan memberi Anda perangkat seluler Microsoft yang terdeteksi lebih luas daripada Windows Phone.


0

Kamu bisa memakai click touchend ,

contoh:

$('a').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Contoh di atas akan memengaruhi semua tautan pada perangkat sentuh.

Jika Anda hanya ingin menargetkan tautan tertentu, Anda dapat melakukannya dengan menetapkan kelas padanya, yaitu:

HTML:

<a href="example.html" class="prevent-extra-click">Prevent extra click on touch device</a>

Jquery:

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Bersulang,

Jeroen


0

Saya mengalami situasi serupa di mana saya mengalami peristiwa yang terkait dengan status mouseenter / mouseleave / klik suatu elemen, namun pada iPhone, pengguna harus mengklik dua kali elemen tersebut untuk pertama-tama memicu peristiwa mouseenter, lalu mengaktifkan peristiwa klik .

Saya menyelesaikan ini menggunakan metode yang mirip seperti di atas, tetapi saya memanfaatkan plugin jQuery $ .browser (untuk jQuery 1.9>) dan menambahkan acara .trigger ke acara pengikatan mouseenter, sebagai berikut:

// mouseenter event
$('.element').on( "mouseenter", function() {
    // insert mouseenter events below

    // double click fix for iOS and mouseenter events
    if ($.browser.iphone || $.browser.ipad) $(this).trigger('click');
});
// mouseleave event
$('.element').on( "mouseleave", function() { 
    // insert mouseout events below
});
// onclick event
$('.element').on( "click", function() {
    // insert click events below
});

.Trigger mencegah kebutuhan untuk mengklik dua kali elemen dengan mengaktifkan .click event handler pada mouseenter (atau klik awal) elemen tersebut saat dilihat di iPhone atau iPad. Mungkin bukan solusi yang paling elegan, tetapi berfungsi dengan baik dalam kasus saya dan menggunakan plugin yang sudah saya miliki, dan meminta saya untuk menambahkan satu baris kode agar acara saya yang ada berfungsi di bawah perangkat ini.

Anda bisa mendapatkan plugin jQuery $ .browser di sini: https://github.com/gabceb/jquery-browser-plugin


0

Hanya perbaikan untuk menghindari pengalihan saat Anda menggeser jari Anda pada tautan secara tidak sengaja.

// tablet "one touch (click)" X "hover" > link redirection
$('a').on('touchmove touchend', function(e) {

    // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
    if (e.type == 'touchmove') {
        $.data(this, "touchmove_cancel_redirection", true );
        return;
    }

    // if it's a simple touchend, data() for this element doesn't exist.
    if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
        var el = $(this);
        var link = el.attr('href');
        window.location = link;
    }

    // if touchmove>touchend, to be redirected on a future simple touchend for this element
    $.data(this, "touchmove_cancel_redirection", false );
});

0

Dengan inspirasi dari MacFreak, saya mengumpulkan sesuatu yang berhasil untuk saya.

Metode js ini mencegah hover menempel pada ipad, dan mencegah klik terdaftar sebagai dua klik dalam beberapa kasus. Di CSS, jika Anda memiliki: hover kelas psudo di css Anda, ubah menjadi .hover Misalnya .some-class: hover ke .some-class.hover

Uji kode ini pada ipad untuk melihat bagaimana metode css dan js hover berperilaku berbeda (hanya dalam efek hover). Tombol CSS tidak memiliki peringatan klik mewah. http://jsfiddle.net/bensontrent/ctgr6stm/

function clicker(id, doStuff) {
  id.on('touchstart', function(e) {
    id.addClass('hover');
  }).on('touchmove', function(e) {
    id.removeClass('hover');
  }).mouseenter(function(e) {
    id.addClass('hover');
  }).mouseleave(function(e) {
    id.removeClass('hover');
  }).click(function(e) {
    id.removeClass('hover');
    //It's clicked. Do Something
    doStuff(id);
  });
}

function doStuff(id) {
  //Do Stuff
  $('#clicked-alert').fadeIn(function() {
    $(this).fadeOut();
  });
}
clicker($('#unique-id'), doStuff);
button {
  display: block;
  margin: 20px;
  padding: 10px;
  -webkit-appearance: none;
  touch-action: manipulation;
}
.hover {
  background: yellow;
}
.btn:active {
  background: red;
}
.cssonly:hover {
  background: yellow;
}
.cssonly:active {
  background: red;
}
#clicked-alert {
  display: none;
}
<button id="unique-id" class="btn">JS Hover for Mobile devices<span id="clicked-alert"> Clicked</span>

</button>
<button class="cssonly">CSS Only Button</button>
<br>This js method prevents hover from sticking on an ipad, and prevents the click registering as two clicks. In CSS, if you have any :hover in your css, change them to .hover For example .some-class:hover to .some-class.hover


0

Agar tautan berfungsi tanpa merusak scrolling sentuh, saya menyelesaikannya dengan acara "tap" jQuery Mobile:

    $('a').not('nav.navbar a').on("tap", function () {
        var link = $(this).attr('href');
        if (typeof link !== 'undefined') {
            window.location = link;
        }
    });

0

Saya terlambat, saya tahu tetapi ini adalah salah satu solusi termudah yang saya temukan:

    $('body').on('touchstart','*',function(){   //listen to touch
        var jQueryElement=$(this);  
        var element = jQueryElement.get(0); // find tapped HTML element
        if(!element.click){
            var eventObj = document.createEvent('MouseEvents');
            eventObj.initEvent('click',true,true);
            element.dispatchEvent(eventObj);
        }
    });

Ini tidak hanya berfungsi untuk tautan (tag jangkar) tetapi untuk elemen lain juga. Semoga ini membantu.


0

Cuplikan singkat ini sepertinya berhasil. Picu peristiwa klik saat tautan diketuk:

  $('a').on('touchstart', function() {
    $(this).trigger('click');
  });

0

Tidak ada dari jawaban lain yang berhasil untuk saya. Aplikasi saya memiliki banyak pendengar acara, kotak centang dan tautan sendiri yang memiliki pendengar dan tautan tanpa pendengar.

Saya menggunakan ini:

var selector = "label, a, button";
var timer;
var startX;
var startY;
$(document).on("click", selector, function (e) {
    if ($(this).data("touched") === true) {
        e.stopImmediatePropagation();
        return false;
    }
    return;
}).on("touchend", selector, function (e) {
    if (Math.abs(startX - e.originalEvent.changedTouches[0].screenX) > 10 || Math.abs(startY - e.originalEvent.changedTouches[0].screenY) > 10)
        // user action is not a tap
        return;
    var $this = $(this);
    // Visit: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand/12801548#12801548
    this.click();
    // prevents double click
    $this.data("touched", true);
    if (timer)
        clearTimeout(timer);
    setTimeout(function () {
        $this.data("touched", false);
    }, 400);
    e.stopImmediatePropagation();
    return false;
}).on("touchstart", function (e) {
    startX = e.originalEvent.changedTouches[0].screenX;
    startY = e.originalEvent.changedTouches[0].screenY;
});

0

Ini bekerja untuk saya ketika Anda memiliki dropdown jquery ui

if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
      $('.ui-autocomplete').off('menufocus hover mouseover');
}

0

Hindari mengubah gaya "tampilan" di dalam acara hover css. Saya memiliki "display: block" dalam keadaan hover. Setelah menghapus ios, lanjutkan dengan satu ketukan. Ngomong-ngomong, tampaknya pembaruan iOS terbaru memperbaiki "fitur" ini


0

Cara termudah untuk menyelesaikan klik dua kali pada iPad adalah membungkus css Anda untuk efek hover di kueri media @media (pointer: fine):

@media (pointer: fine) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

CSS yang dibungkus dalam kueri media ini hanya akan diterapkan di desktop.

Penjelasan solusi ini ada di sini https://css-tricks.com/annoying-mobile-double-tap-link-issue/


-1

Anda bisa memeriksanya navigator.userAgentseperti ini:

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}

tetapi Anda harus memeriksa blackberry, droid, sekian perangkat layar sentuh lainnya. Anda juga dapat mengikat gerakan mouse hanya jika userAgent berisi Mozilla, IE, Webkit, atau Opera, tetapi Anda masih perlu menyaring beberapa perangkat karena Droid, misalnya, melaporkan string userAgent-nya sebagai:

Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

Tali iPhone serupa. Jika Anda hanya menyaring untuk iPhone, iPod, iPad, Android dan Blackberry, Anda mungkin mendapatkan mayoritas perangkat genggam, tetapi tidak semuanya.


Saya pikir, untuk saat ini, agar tidak menjadi gila, hal terbaik yang harus dilakukan bisa jadi hanya skrip yang melewatkan acara hover..jadi saya kira jawaban pertama bagus ... dan ya Anda benar..saya harus pikirkan tentang semua perangkat lain ... saya berharap Jquery atau beberapa plugin memiliki fitur deteksi semacam ini ..!
Francesco

wurfl.sourceforge.net Ini mungkin jawaban Anda. Ini adalah database perangkat nirkabel. Tidak akan semudah plugin jQuery, tetapi Anda selalu dapat menulisnya! Ada juga tera-wurfl.com yang menggunakan databse daripada file xml. Belum melakukan banyak penggalian tetapi mungkin ada versi yang dihosting di luar sana sehingga Anda tidak perlu khawatir tentang menjaga file wurfl atau database tera-wurfl Anda tetap mutakhir.
jasongetsdown

1
Apakah saya melewatkan sesuatu atau apakah pertanyaannya BUKAN tentang mendeteksi iPad, tetapi tentang mengatasi perilaku tertentu di iPad?
Andrew Hedges

5
Mengendus UA? Bagaimana 90-an: P
Macha

-1

Cukup buat kueri media CSS yang mengecualikan tablet dan perangkat seluler, lalu arahkan kursor ke sana. Anda tidak benar-benar membutuhkan jQuery atau JavaScript untuk ini.

@media screen and (min-device-width:1024px) {
    your-element:hover {
        /* Do whatever here */
    }
}

Dan pastikan untuk menambahkan ini ke kepala html Anda untuk memastikan bahwa itu menghitung dengan piksel sebenarnya dan bukan resolusinya.

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
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.