iPad / iPhone üzerine gelme sorunu kullanıcının bir bağlantıyı çift tıklamasına neden oluyor


125

Daha önce oluşturduğum, jquery fare olayları kullanan bazı web sitelerim var ... Yeni bir ipad aldım ve tüm mouse over olaylarının tıklama olarak çevrildiğini fark ettim ... yani örneğin bir yerine iki tıklama yapmam gerekiyor .. (ilk fareyle üzerine gelme, gerçek tıklamadan çok)

Bunu çözmeye hazır bir çözüm var mı? belki fareyle üzerine gelme / çıkma vb. yerine kullandığım bir jquery komutu .. teşekkürler!


1
senin olayların neye bağlı? Örneğin, onclick olayları iyi çalışmalıdır ... onmouseover, onmouseout ve CSS: hover, dokunmatik ekranda "üzerine gelme" olmadığından kullanımı biraz zor olanlardır. Bir kod örneğiniz var mı?
scunliffe

Mümkünse arayüzünüzü yeniden düşünmenizi önereceğim bir şey var. ipad / iphone üzerindeki etkileşim bir bilgisayardaki etkileşimi tam olarak yansıtmaz ve muhtemelen web sitenizi benzer çoklu dokunma mekanizmalarına sahip ipad / iphone / diğer dokunmatik cihazlar için yazılmış gibi hissettirmek akıllıca bir şeydir. Sadece bir düşünce.
jer

"Jer" e katılıyorum. Bu garip bir soru, buradaki çözümün kişisel olarak bir "geçici çözüm" olduğunu düşünmüyorum. Bir masaüstü tarayıcıda bir "fare vurgusunu" dokunmatik ekranlı bir tarayıcıda "parmakla dokunmaya" çevirmenin mantıklı olduğunu düşünüyorum. Bu çeviriye katılıyorsanız, ancak iki yerine bir dokunuş istiyorsanız, muhtemelen iPad olayları için özellik algılama (örneğin, "touchstart") yapacağım ve olay işleyicilerinizi değiştireceğim. Belki kodunuzu, özelliklere göre farklı şekilde tetiklenen, ancak web sitenize / uygulamanıza özgü görünen bir jquery eklentisi "dokunma veya tıklama" türündeki bir işlevselliğe çıkartabilirsiniz.
Andy Atkinson

1
Aslında bu çeviriyi bir özellik olarak görüyorum. Fareyle üzerine gelme etkinlikleri ayarladıysanız, onları görmek için bazı yardımcı programların olması gerekir. Tek bir dokunuş üzerine gelinen bir öğeyi gösterir, ikinci bir dokunuş ise fareyle üzerine gelenin "arkasındaki" bağlantıyı izler.
Aaron

Yanıtlar:


205

Bunu tam olarak test etmedim, ancak iOS dokunma olaylarını tetiklediğinden, bu, bir jQuery ayarında olduğunuzu varsayarak işe yarayabilir.

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

Buradaki fikir, Mobil WebKit'in touchendbir dokunuşun sonunda bir olay tetiklemesidir , böylece bunu dinleriz ve ardından touchendbir bağlantıda bir olay tetiklendiğinde tarayıcıyı yeniden yönlendiririz .


17
Ödülüm nerede? : P
cduruk

2
Sabır, Padwan. SO, yürürlüğe girmesinin 24 saat sürdüğünü söyledi.
Andrew Hedges

2
JQuery 1.7'den itibaren .ontercih edilmektedir .live. Bu cevabı okuduktan sonra, kodumu $('a').on('click touchend', function(e) {...})mükemmel bir şekilde değiştirmenin işe yaradığını öğrendim .
Blazemonger

23
Eh, bu ilk sorunu çözer, ancak yeni bir sorun yaratır: Üzerine kaydırıldığında tıklanır. Bu bir çözüm değil.
luksak

9
Bunun kusurları var. Bir bağlantıya tıklarsanız target="_blank", aynı pencerede VE yeni bir pencerede açılır.
rybo111

37

Sorunuzun ne olduğu tam olarak belli değil, ancak farenin üzerine gelme etkisini korurken sadece çift tıklamayı ortadan kaldırmak istiyorsanız, tavsiyem şudur:

  • Üzerindeki etkileri hover ekleyin touchstartve mouseenter.
  • Üzerindeki etkileri hover çıkarın mouseleave, touchmoveve click.

Arka fon

Bir fareyi simüle etmek için, Webkit mobile gibi tarayıcılar, bir kullanıcı dokunmatik ekrana (iPad gibi) dokunur ve parmağını bırakırsa aşağıdaki olayları ateşler (kaynak: html5rocks.com'da Touch And Mouse ):

  1. touchstart
  2. touchmove
  3. touchend
  4. 300 ms gecikme, tarayıcının bunun çift dokunuş değil, tek dokunuş olduğundan emin olduğu
  5. mouseover
  6. mouseenter
    • Not : Bir ederse mouseover, mouseenterya da mousemoveolay sayfası içeriği değişir, aşağıdaki olaylar ateş asla.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

Web tarayıcısına fare olaylarını atlamasını söylemek mümkün görünmüyor.

Daha da kötüsü, fareyle üzerine gelme olayı sayfa içeriğini değiştirirse, tıklama olayı, Safari Web İçerik Kılavuzu - Olayları İşleme , özellikle de Tek Parmakla Etkinliklerde şekil 6.4'te açıklandığı gibi asla tetiklenmez . Tam olarak bir "içerik değişikliğinin" ne olduğu, tarayıcıya ve sürüme bağlı olacaktır. İOS 7.0 için arka plan rengindeki bir değişikliğin bir içerik değişikliği olmadığını (veya artık olmadığını) buldum.

Çözüm Açıklaması

Özetlemek için:

  • Üzerindeki etkileri hover ekleyin touchstartve mouseenter.
  • Üzerindeki etkileri hover çıkarın mouseleave, touchmoveve click.

Üzerinde herhangi bir işlem olmadığını unutmayın touchend!

Bu açıkça fare olayları için çalışır: mouseenterve mouseleave(biraz sürümlerini geliştirilmiş mouseoverve mouseouttetiklenmez) ve ekleyip hover kaldırın.

Kullanıcı gerçekten bir clickbağlantı varsa, fareyle üzerine gelme efekti de kaldırılır. Bu, kullanıcı web tarayıcısında geri düğmesine basarsa kaldırılmasını sağlar.

Bu, dokunma olayları için de geçerlidir: üzerine touchstartgelme efekti eklenir. '' 'Üzerinde kaldırılmamış' '' touchend. Tekrar eklenir mouseenterve bu herhangi bir içerik değişikliğine neden olmadığından (zaten eklenmiştir), clickolay da tetiklenir ve kullanıcının tekrar tıklamasına gerek kalmadan bağlantı izlenir!

Bir tarayıcının bir touchstartolay arasında geçirdiği 300 ms'lik gecikme ve clickbu kısa süre içinde fareyle üzerine gelme efekti gösterileceği için aslında iyi bir şekilde kullanılır.

Kullanıcı tıklamayı iptal etmeye karar verirse, parmağınızı hareket ettirmek bunu normal bir şekilde yapacaktır. Normalde, bu bir sorundur çünkü hiçbir mouseleaveolay tetiklenmez ve gezinme efekti yerinde kalır. Neyse ki, bu kolayca hover efekti kaldırarak sabitlenebilir touchmove.

Bu kadar!

Örneğin FastClick kitaplığını kullanarak 300 ms'lik gecikmeyi kaldırmanın mümkün olduğunu , ancak bunun bu soru için kapsam dışında olduğunu unutmayın.

Alternatif çözümler

Aşağıdaki alternatiflerde aşağıdaki sorunları buldum:

  • tarayıcı algılama: Hatalara son derece eğilimlidir. Bir aygıtta fare veya dokunma olduğu varsayılırken, dokunmatik ekranlar çoğaldıkça ikisinin bir kombinasyonu giderek daha yaygın hale gelecektir.
  • CSS medya algılama: Bildiğim yalnızca CSS'ye yönelik çözüm. Hâlâ hatalara meyillidir ve her ikisinin de mümkün olmasına rağmen, bir aygıtta fare veya dokunma olduğunu varsayar.
  • Tıklama olayını şurada taklit edin touchend: Bu, kullanıcı bağlantıyı gerçekten tıklama niyeti olmadan yalnızca kaydırmak veya yakınlaştırmak istese bile bağlantıyı hatalı şekilde izleyecektir.
  • Fare olaylarını bastırmak için bir değişken kullanın: Bu touchend, o andaki durum değişikliklerini önlemek için sonraki fare olaylarında if-koşulu olarak kullanılan bir değişken ayarlayın . Değişken, tıklama etkinliğinde sıfırlanır. Dokunmatik arayüzler üzerinde gerçekten bir gezinme efekti istemiyorsanız, bu iyi bir çözümdür. Maalesef, touchendbaşka bir nedenden dolayı tetiklenirse ve tıklama olayı tetiklenmediyse (örn. Kullanıcı kaydırılmış veya yakınlaştırılmışsa) ve daha sonra bağlantıyı bir fare ile izlemeye çalışıyorsa (yani hem fare hem de dokunmatik arayüze sahip bir cihazda) bu işe yaramaz. ).

Daha fazla okuma

Ayrıca bkz. İPad / iPhone çift tıklama sorunu ve mobil tarayıcılarda fareyle üzerine gelme efektlerini devre dışı bırak .


2
Kesin sorun çözümünden daha fazlasını isteyenler için en iyi açıklama gibi görünüyor. Thanx
antiplayer

> İOS7 için arka plan rengi hakkındaki bilgiler için özel teşekkürler. Bunun ne zaman işe yaradığını anlamaya çalışmak için biraz zaman harcadım.
staffang

20

Görünüşe göre bir CSS çözümü var. Safari'nin ikinci bir dokunuşu beklemesinin nedeni, genellikle: hover olayına atadığınız arka plan görüntüsü (veya öğeler) nedeniyledir. Gösterilecek hiçbir şey yoksa - herhangi bir sorun yaşamazsınız. Çözüm, iOS platformunu geçersiz kılan ikincil CSS dosyasıyla (veya bir JS yaklaşımı durumunda stil) hedeflemektir: örneğin, devralmak için arka plan üzerine gelin ve fareyle üzerinde göstereceğiniz öğeleri gizli tutun:

Örnek bir CSS ve HTML - fareyle üzerine gelindiğinde yıldız işaretli bir ürün bloğu:

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;
}

Çözüm (ikincil CSS):

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


Bu cevap, arka plan resimlerine yöneliktir, ancak basit opaklık değişiklikleri için bir çözümünüz var mı? Bu çözüm bunun için işe yaramıyor.
Ian S

5

Aşırı karmaşık hale getirmeye gerek yok.

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

5

Benim için işe yarayan, buradaki diğerlerinin daha önce söylediği şeydi:

Öğeleri fareyle üzerine gelme veya fare imlecinde gösterme / gizleme (benim durumumdaki olay budur).

Apple'ın söyledikleri ( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ):

Tıklanabilir bir öğe, bir bağlantı, form öğesi, görüntü eşleme alanı veya fare imleci, fare aşağı indirme, fareyi yukarı çekme veya onclick işleyicileri olan diğer öğelerdir

Kullanıcı tıklanabilir bir öğeye dokunduğunda, olaylar şu sırayla gelir: fareyle üzerine gelme, fare ile kaldırma, fare indirme, fareyi kaldırma ve tıklama. Ayrıca, mousemove olayında sayfanın içeriği değişirse, sıradaki sonraki olaylar gönderilmez. Bu davranış, kullanıcının yeni içeriğe dokunmasına izin verir.

Böylece, @ woop'un çözümünü kullanabilirsiniz: userAgent'ı algılayın, onun ve iOS cihazının olup olmadığını kontrol edin ve ardından olayı bağlayın. Bu tekniği kullandım çünkü ihtiyaçlarıma uyuyor ve istemediğinizde gezinme olaylarını bağlamayın daha mantıklı.

Ancak ... userAgents ile uğraşmak istemiyor ve yine de öğeleri hover / mousemove üzerinde gizlemek / göstermek istemiyorsanız, bunu yerel javascript kullanarak yapabileceğinizi öğrendim:

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

Bu, Masaüstü sürümünde çalışacak ve mobil sürümde hiçbir şey yapmayacaktır.

Ve biraz daha uyumluluk için ...

$("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
Bu bit, "mousemove olayında sayfanın içeriği değişirse, sıradaki hiçbir olay gönderilmez" gerçekten benim için yaptı. Başlık bağlantılarının içerikteki düğmelerin (em üzerinde tüm mutlu css3 geçişleri ile) yalnızca tek bir dokunuş gerektirdiği bir çift dokunma gerektirdiği bir sayfam vardı. Üstbilgi bağlantılarının, üzerine gelindiğinde opaklık: 0'dan opaklık: 1'e giden bir sözde öğe içerdiği ortaya çıktı. Bu etkinin kaldırılması sorunu hemen çözdü ve hala istediğim görünümü elde etmek için bir CSS çözümü buldum.
Sahte Haak

3

cduruk'un çözümü oldukça etkiliydi, ancak sitemin birkaç bölümünde sorunlara neden oldu. CSS vurgulu sınıfını eklemek için zaten jQuery kullandığım için, en kolay çözüm CSS vurgulu sınıfını mobil cihazlara eklememek (veya daha doğrusu YALNIZCA bir mobil cihazda OLMADIĞINDA eklemekti).

Genel fikir şuydu:

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");
        }
    );
}

* açıklama amacıyla indirgenmiş kod


1
Cevap açıkça budur. Diğer "çözümler" sorunu çözmez. iOS safari, önce üzerine gelmek istediğimizi düşünmede açıkça kusurlu. Diğer işletim sistemleri, bir öğenin üzerine geldiğinizde gerçek vurgulu özelliklere sahiptir.
Joshua Pack

Bu benim için işe yarayan tek şeydi. Çok teşekkür ederim!
tx291

2

Ben denemek için akıllıca olacağını düşünüyorum mouseenteryerine mouseover. Bağlanırken dahili olarak kullanılan .hover(fn,fn)ve genellikle istediğiniz şeydir.


1

Mevcut çözümlerle ilgili aşağıdaki sorunları yaşadım ve hepsini çözen bir şey buldum. Bu, tarayıcılar arası, cihazlar arası bir şey hedeflediğinizi ve cihaz koklamasını istemediğinizi varsayar.

Çözdüğü sorunlar

Yalnızca touchstartveya kullanarak touchend:

  • İnsanlar içeriği kaydırmaya çalışırken ve kaydırmaya başladıklarında parmaklarını bu öğenin üzerine getirdiklerinde olayın tetiklenmesine neden olur - bu da eylemi beklenmedik bir şekilde tetikler.
  • Masaüstünde sağ tıklamaya benzer şekilde , olayın uzun basışta çalışmasına neden olabilir . Örneğin, tıklama etkinliğiniz X URL'sine giderse ve kullanıcı X'i yeni bir sekmede açmak için uzun süre basarsa, kullanıcının her iki sekmede de X'i açık bulmasıyla kafası karışır. Bazı tarayıcılarda (örneğin iPhone), uzun basma menüsünün görünmesini bile engelleyebilir.

Tetikleme mouseoveretkinlikleri touchstartve mouseoutüzerinde touchmovedaha az ciddi sonuçları vardır, ancak örneğin her zamanki tarayıcı davranışına müdahale etmez:

  • Uzun bir basış, asla bitmeyen bir fareyle üzerine gelmeyi tetikler.
  • Çoğu Android tarayıcısı, parmağın konumunu, touchstartbir sonraki sayfada düzenlenecek mouseoverolan a gibi ele alır . Bu nedenle, Android'de fareyle üzerine gelinen içeriği görmenin bir yolu, ilgi alanına dokunup parmağınızı kıpırdatarak sayfayı hafifçe kaydırmaktır. Bunu bozmuş gibi davranmak .mouseouttouchstarttouchmovemouseout

Çözüm

Teorik olarak, bir bayrak ekleyebilirsiniz touchmove, ancak iPhone'lar hareket olmasa bile dokunma hareketini tetikler. Teorik olarak, sadece karşılaştırabilirsiniz touchstartve touchendolayı pageXve pageY ancak iPhone'lar, hiçbir var touchend pageXyapageY .

Bu yüzden maalesef tüm üsleri kapsamak biraz daha karmaşık hale geliyor.

$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);

Teoride, yaklaşık olarak 1000 kullanmak yerine uzun basma için kullanılan tam zamanı almanın yolları vardır , ancak pratikte bu o kadar basit değildir ve makul bir proxy kullanmak en iyisidir .


1

MacFreak'in cevabı bana çok yardımcı oldu. Size yardımcı olma ihtimaline karşı bazı uygulamalı kodlar.

PROBLEM - dokunma ucunun uygulanması , parmağınızı bir öğenin üzerine her kaydırdığınızda , sadece geçmeye çalışıyor olsanız bile ona bastığınız gibi yanıt verir.

JQuery ile, üzerine getirilen düğmeyi "vurgulamak" için bazı düğmelerin altında bir satır beliren bir efekt oluşturuyorum. Bunun, bağlantıyı takip etmek için dokunmatik cihazlarda düğmeye iki kez basmanız gerektiği anlamına gelmesini istemiyorum.

İşte düğmeler:

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

"Menu_underline" div öğesinin fareyle üzerine gelindiğinde solmasını ve fareyi bıraktığınızda kaybolmasını istiyorum. AMA, dokunmatik cihazların bağlantıyı iki değil tek bir tıklamayla izleyebilmesini istiyorum.

ÇÖZÜM - İşte çalışmasını sağlayacak jQuery:

//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();
});

Bu MacFreak ile ilgili yardımınız için çok teşekkürler.


1

Boş bir dinleyici eklerseniz işe yaradığını yeni öğrendim, nedenini sormayın, ancak iPhone ve iPad'de iOS 9.3.2 ile test ettim ve iyi çalıştı.

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(){});
    }
}

1

Bağlantılarınızda farenin üzerinde tek dokunuşun tek dokunuşla etkinleştirildiği ve çift dokunmanın bağlantıyı etkinleştirdiği bir farenin üzerinde etkinlik olmadığını "düşünüyorum". ama idk. İPad'im yok. Bence jest / dokunma olaylarını kullanmalısın.

https://developer.apple.com/documentation/webkitjs


0

Aynı sorunu yaşadım ama dokunmatik bir cihazda değil. Etkinlik, her tıkladığınızda tetiklenir. Olay sıralamasıyla ilgili bir şey var.

Ancak benim çözümüm şöyleydi: Tıklama olayında (veya dokunma?) Bir zamanlayıcı ayarlarsınız. Bağlantı X ms içinde tekrar tıklanırsa, yalnızca yanlış döndürürsünüz.

Öğe başına zamanlayıcı ayarlamak için kullanabilirsiniz $.data().

Bu aynı zamanda yukarıda açıklanan @Ferdy sorununu da çözebilir.


Bu kodun neye benzediğini gönderebilir misin? Bu tıklama etkinliğinin iki kez tetiklenmesi sorunu yaşıyorum.
süslü

0

Modernizr kullanıyorsanız, daha önce belirtildiği gibi Modernizr.touch'u kullanmak çok kolaydır.

Ancak, güvenli olmak için Modernizr.touch ve kullanıcı aracısı testinin bir kombinasyonunu kullanmayı tercih ediyorum.

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();
};

Modernizr kullanmıyorsanız, Modernizr.touchyukarıdaki işlevi şununla değiştirebilirsiniz:('ontouchstart' in document.documentElement)

Ayrıca, iemobile kullanıcı aracısını test etmenin, size Windows Phone'dan daha geniş bir Microsoft mobil cihaz yelpazesi sunacağını unutmayın.


0

Sen kullanabilirsiniz click touchend,

misal:

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

Yukarıdaki örnek, dokunmatik cihazlardaki tüm bağlantıları etkileyecektir.

Yalnızca belirli bağlantıları hedeflemek istiyorsanız, bunları bir sınıf belirleyerek yapabilirsiniz, yani:

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;
});

Alkış,

Jeroen


0

Olayların bir öğenin mouseenter / mouseleave / tıklama durumlarına bağlı olduğu benzer bir durumla karşılaştım, ancak bir iPhone'da, kullanıcının önce mouseenter olayını tetiklemek için öğeyi çift tıklaması, ardından tekrar tıklama olayını tetiklemesi gerekiyordu .

Bunu yukarıdakiyle benzer bir yöntem kullanarak çözdüm, ancak jQuery $ .browser eklentisini (jQuery 1.9> için) kullandım ve aşağıdaki gibi mouseenter bağlama olayına bir .trigger olayı ekledim:

// 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, iPhone'larda veya iPad'lerde görüntülendiğinde öğenin fareyle girilmesi (veya ilk tıklanması) üzerine .click olay işleyicisini tetikleyerek öğeyi çift tıklama ihtiyacını önler. En zarif çözüm olmayabilir, ancak benim durumumda harika çalışıyor ve zaten sahip olduğum bir eklentiyi kullanıyor ve mevcut etkinliklerimin bu cihazlar altında çalışmasını sağlamak için tek bir kod satırı eklememi gerektirdi.

JQuery $ .browser eklentisini buradan edinebilirsiniz: https://github.com/gabceb/jquery-browser-plugin


0

Parmağınızı yanlışlıkla bir bağlantıya kaydırdığınızda yeniden yönlendirmeyi önlemek için sadece bir iyileştirme.

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

MacFreak'ten aldığım ilhamla benim için çalışan bir şeyi bir araya getirdim.

Bu js yöntemi, fareyle üzerine gelmenin bir ipad'e yapışmasını önler ve bazı durumlarda tıklamanın iki tıklama olarak kaydedilmesini engeller. CSS'de, css'nizde: hover psudo sınıflarınız varsa, bunları .hover olarak değiştirin Örneğin .some-class: hover olarak .some-class.hover olarak değiştirin

Css ve js hover yönteminin nasıl farklı davrandığını görmek için bu kodu bir ipad üzerinde test edin (yalnızca üzerine gelme efektinde). CSS düğmesinin süslü bir tıklama uyarısı yoktur. 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

Bağlantıların dokunmatik kaydırmayı bozmadan çalışmasını sağlamak için, bunu jQuery Mobile'ın "dokunma" etkinliğiyle çözdüm:

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

0

Çok geç kaldım, biliyorum ama bulduğum en kolay çözümlerden biri bu:

    $('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);
        }
    });

Bu yalnızca bağlar (bağlantı etiketleri) için değil, diğer öğeler için de işe yarar. Bu yardımcı olur umarım.


0

Bu kısa pasaj çalışıyor gibi görünüyor. Bağlantıya dokunulduğunda tıklama etkinliğini tetikleyin:

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

0

Diğer cevaplardan hiçbiri benim için işe yaramıyor. Uygulamamda çok sayıda olay dinleyicisi, kendi onay kutuları ve dinleyicinin olmadığı dinleyicilere ve bağlantılara sahip bağlantılar var.

Bunu kullanıyorum:

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

Bu, jquery kullanıcı arabirimi açılır menüsüne sahip olduğunuzda işime yarar

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

0

Fareyle üzerine gelme css olayının içinde "görüntüleme" stilini değiştirmekten kaçının. Üzerine gelme durumunda "display: block" vardı. İosları kaldırdıktan sonra tek dokunuşla lins'e gitti. Bu arada, en son IOS güncellemelerinin bu "özelliği" düzelttiği görülüyor.


0

IPad'e çift tıklamayı çözmenin en basit yolu, medya sorgusunda fareyle üzerine gelme etkisi için css'nizi sarmalamaktır @media (pointer: fine):

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

Bu medya sorgusuna sarılmış CSS yalnızca masaüstünde uygulanacaktır.

Bu çözümün açıklaması burada https://css-tricks.com/annoying-mobile-double-tap-link-issue/


-1

Şöyle kontrol edebilirsiniz navigator.userAgent:

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

ancak böğürtlen, droid ve diğer dokunmatik ekranlı cihazları kontrol etmeniz gerekir. Ayrıca mouseover'ları yalnızca userAgent Mozilla, IE, Webkit veya Opera içeriyorsa bağlayabilirsiniz, ancak yine de bazı cihazlar için tarama yapmanız gerekir çünkü Droid, örneğin userAgent dizesini şu şekilde bildirir:

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

İPhone'un dizesi benzer. Yalnızca iPhone, iPod, iPad, Android ve Blackberry için ekran yapıyorsanız, el bilgisayarlarının çoğunu alabilirsiniz, ancak hepsini değil.


Şimdilik, çıldırmamak için yapılacak en iyi şey, üzerine gelme olaylarını atlayan bir senaryo olabilirdi ... yani sanırım ilk cevap güzeldi ... ve evet haklısın ... diğer tüm cihazları düşünün ... Keşke Jquery veya bazı eklentilerin bu tür bir algılama özelliği olsaydı ..!
Francesco

wurfl.sourceforge.net Cevabınız bu olabilir. Kablosuz cihazların bir veritabanıdır. Bir jQuery eklentisinin olabileceği kadar basit olmayacak, ancak her zaman bir tane yazabilirsiniz! Bir xml dosyası yerine bir veri tabanı kullanan tera-wurfl.com da vardır . Çok fazla araştırma yapmadım, ancak orada barındırılan bir sürüm olabilir, bu nedenle wurfl dosyanızı veya tera-wurfl veritabanınızı güncel tutma konusunda endişelenmenize gerek kalmaz.
jasongetsdown

1
Bir şey mi kaçırıyorum yoksa soru iPad'leri tespit etmekle ilgili değil, iPad'lerde belirli bir davranış etrafında çalışmakla mı ilgili?
Andrew Hedges

5
UA koklama mı? Nasıl 90'lar: P
Macha

-1

Tabletleri ve mobil cihazları hariç tutan bir CSS medya sorgusu yapın ve fareyle üzerine gelin. Bunun için jQuery veya JavaScript'e gerçekten ihtiyacınız yok.

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

Çözünürlükle değil gerçek piksellerle hesapladığından emin olmak için bunu html başlığınıza eklediğinizden emin olun.

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.