Mobil tarayıcılarda vurgulu efektleri devre dışı bırakın


113

Hem masaüstlerinden hem de tabletlerden kullanılması amaçlanan bir Web sitesi yazıyorum. Bir masaüstünden ziyaret edildiğinde, ekranın tıklanabilir alanlarının :hoverefektlerle (farklı arka plan rengi, vb.) Aydınlatılmasını istiyorum. Tablet ile fare yok, bu yüzden herhangi bir vurgulu efekt istemiyorum.

Sorun şu ki, tablette bir şeye dokunduğumda, tarayıcının açıkça dokunduğum konuma hareket eden bir tür "görünmez fare imlecine" sahip olması ve sonra onu orada bırakması - böylece az önce dokunduğum şey bir başka bir şeye dokunana kadar fareyle üzerine gelme efekti.

Fareyi kullanırken vurgulu efektleri nasıl elde edebilirim, ancak dokunmatik ekranı kullanırken bunları nasıl bastırabilirim?

Birinin bunu önermeyi düşünmesi durumunda, kullanıcı aracısı koklamayı kullanmak istemiyorum. Aynı cihaz hem dokunmatik ekrana hem de fareye sahip olabilir (bugün pek yaygın olmayabilir, ancak gelecekte çok daha fazlası olabilir). Cihazla ilgilenmiyorum, şu anda nasıl kullanıldığıyla ilgileniyorum: fare veya dokunmatik ekran.

Zaten çengel çalıştı touchstart, touchmoveve touchendetkinliklerle çağırarak preventDefault()bastırmak "görünmez fare imlecini" biraz zaman işlevi gören hepsinin üzerinde; ancak iki farklı öğe arasında hızlı bir şekilde ileri geri tıklarsam, birkaç dokunuştan sonra "fare imlecini" hareket ettirmeye ve yine de vurgulu efektleri aydınlatmaya başlar - sanki benim preventDefaulther zaman onurlandırılmamış gibi. Gerekmedikçe sizi ayrıntılarla sıkmayacağım - Bunun doğru yaklaşım olduğundan bile emin değilim; Eğer birinin daha basit bir düzeltmesi varsa, tamamen kulağım.


Düzenleme: Bu, bataklık standardı CSS ile çoğaltılabilir :hover, ancak burada referans için hızlı bir yeniden çalışma var.

<style>
  .box { border: 1px solid black; width: 150px; height: 150px; }
  .box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>

Kutulardan herhangi birinin üzerine fareyi getirirseniz, istediğim mavi bir arka plan alır. Ancak kutulardan birine dokunursanız, mavi bir arka plan da alacaktır, ki bu benim önlemeye çalıştığım şeydir.

Ayrıca burada yukarıdakileri yapan ve jQuery'nin fare olaylarını kancalayan bir örnek yayınladım . Ayrıca ateş edeceğini musluk etkinlikleri görmek için kullanabilirsiniz mouseenter, mousemoveve mouseleave.


7
@Blender, soruyu okudun mu? Kullanıcı aracısı koklamanın neden kötü bir seçim olduğunu zaten açıklamıştım.
Joe White

Hey Joe, bunun için herhangi bir çözüm buldun mu?
Ismatjon

Bu tür bir soruyu arıyordum, bulduğuma sevindim!
2017

Ayrıca, yalnızca mobil cihazlarda değil, dokunmatik özellikli tüm cihazlarda fareyle üzerine gelmeyi devre dışı bırakmayla ilgilenen bu soruya da bakın: stackoverflow.com/questions/23885255/…
blade

Yanıtlar:


83

Sorunuzdan, fareyle üzerine gelme etkinizin sayfanızın içeriğini değiştirdiğini anlıyorum. Bu durumda tavsiyem şudur:

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

Alternatif olarak, sayfanızı içerik değişikliği olmayacak şekilde düzenleyebilirsiniz.

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 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 aynı zamanda dokunma olayları için de geçerlidir: touchstart'ta üzerine gelme efekti eklenir. Dokunmatik uçta '' 'kaldırılmamış' ''. Tekrar eklenir mouseenterve bu 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ı takip edilir!

Bir tarayıcının bir touchstartolay arasında geçirdiği 300 ms'lik gecikme, 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, üzerinde gezinme efekti kaldırılarak bu kolayca düzeltilebilir touchmove.

Bu kadar!

Örneğin FastClick kitaplığını kullanarak 300 ms'lik gecikmeyi kaldırmanın mümkün olduğunu , ancak bunun bu sorunun 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. Hala 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. Bu sayfadaki Walter Roman'ın cevabına bakın. Dokunmatik arayüzler üzerinde gerçekten bir gezinme efekti istemiyorsanız, bu iyi bir çözümdür. Ne yazık ki, touchendbaşka bir nedenden dolayı bir tetiklenirse ve herhangi bir tıklama olayı tetiklenmediyse (örneğin, 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


1
Güzel cevap. Kendi çözümümü yaratmaya başlamak için kemanınızı kullandım. Ancak bazen dokunuşa ihtiyaç duyulur. (bir
dokunmatik

Güzel cevap ancak çoğu durumda kullanıyorum öneririm touchend yerine ait touchstartkullanıcı çalıştığında hemen tetikleme eylemleri önlemek için çoğu durumda yukarı tokatlamak-kaydırmak ya da sayfaya yerleştirilir. Yine de olacak, ancak dikkati dağıtma veya kafa karıştırmaya daha az olası (kullanıcının bilmesi gereken bir şey değil, etiket görüntülemek gibi zararsız bir şey olduğunu varsayarak)
user56reinstatemonica8

19

Fareyi kullanırken vurgulu efektleri nasıl elde edebilirim, ancak dokunmatik ekranı kullanırken bunları nasıl bastırabilirim?

Belki bunu dokunmatik ekranlar için fareyle üzerine gelme efektlerini bastırmak olarak değil, fare olayları için üzerine gelme efektleri eklemek olarak mı düşünüyorsunuz?

:hoverCSS'nizdeki efektleri korumak istiyorsanız, farklı ortamlar için farklı stiller belirtebilirsiniz:

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

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

Ancak maalesef bunu görmezden gelen ve sadece ekran kurallarını kullanan birçok mobil cihaz var. Neyse ki birçok yeni mobil / tablet tarayıcısı, bazı daha meraklı medya sorgularını desteklemektedir:

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

Dolayısıyla, "ekran" veya "avuçiçi" kısmı yok sayılsa bile "maksimum genişlik" sizin için hile yapacaktır. Ekranı 800 pikselden küçük olan her şeyin bir tablet veya telefon olması gerektiğini ve üzerine gelme efektleri kullanmaması gerektiğini varsayabilirsiniz. Düşük çözünürlüklü bir cihazda fare kullanan nadir kullanıcılar için, fareyle üzerine gelme etkilerini görmezler, ancak aksi takdirde siteniz iyi olur.

Medya sorguları hakkında daha fazla okumak ister misiniz? Bununla ilgili çevrimiçi pek çok makale var - işte bir tane: http://www.alistapart.com/articles/return-of-the-mobile-stylesheet

Fareyle üzerine gelme efektlerini CSS'nizin dışına kaydırır ve bunları JavaScript ile uygularsanız, özellikle fare olaylarına bağlanabilirsiniz ve / veya yine, yalnızca ekran boyutuna dayalı olarak bazı varsayımlar yapabilirsiniz ve en kötü durum "sorun" Fare kullanan kullanıcı, üzerine gelme efektlerini kaçırır.


Yalnızca fare etkinlikleri için vurgulu efektler eklemeyi çok isterim. Ancak dokunma olayları fare olaylarını taklit eder. Dokunma olaylarını bağlarsam ve ararsam preventDefault(), bu bazen fare olaylarını bastırır, ancak sorumda söylediğim gibi, bu güvenilir değildir.
Joe White

6
Windows 8 çıkıyor ve PC'ler dokunmatik ekranlar hem olduğunda medya sorguları gelince, ne olur ve fareler? Kullanıcı fareyle üzerine gelirse, fare imlecini görür ve üzerine gelme efektlerini istiyorum; dokunmatik ekrana dokunurlarsa, vurgulu efektleri istemiyorum. Ancak dokunma ve fare arasındaki farkı saptamanın güvenilir bir yolunu bulamadım.
Joe White

Belki de tarayıcı geliştiricileri, dokunmatik ve fareli cihazlarda daha fazla sayıda kullanıcıya sahip olduklarında algılamayı daha tutarlı hale getirmek için daha motive olacaklardır. Ama şimdilik? Ekran boyutuna göre tahminler yapıyor olurdum, ancak diğer cevaplarda başka tavsiyeler de var. Maalesef daha fazla yardımcı olamıyorum.
nnnnnn

9

Dokunmatik olarak görünmemesi gereken vurgulu efektlere sahip bir masaüstü / mobil / tablet sitesi olan yeni bir proje için aşağıdaki JS'yi yazdım.

Aşağıdaki mobileNoHoverStatemodül , bir kullanıcı bir öğe üzerinde olayı başlattığında ayarlanan bir değişkene preventMouseover(başlangıçta olarak bildirilir false) sahiptir .truetouchstart$target

preventMouseoverdaha sonra false, mouseoverolayın tetiklendiği zamana geri dönülür ve bu, bir kullanıcı hem dokunmatik ekranını hem de faresini kullanıyorsa sitenin amaçlandığı gibi çalışmasına olanak tanır.

İçerisinde ilan edildikleri emir nedeniyle mouseoverbunun tetiklendiğini biliyoruz .touchstartinit

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

Modül daha sonra satırın daha aşağısında somutlaştırılır:

mobileNoHoverState.init();

"ÖnlemeMouseover, fareyle üzerine gelme olayı her tetiklendiğinde, bir kullanıcı hem dokunmatik ekranını hem de faresini kullanıyorsa sitenin amaçlandığı gibi çalışmasına olanak tanıyan her defasında gerçek haline getiriliyor." - Kodunuz bunu yapmıyor. Bir şey mi kaçırıyorum?
Redtopia

@Redtopia Uyarılar için teşekkürler! Yanıtı, kalan kod parçasıyla güncelledim.
Walter Roman

İşlev bildiriminden sonra noktalı virgüllere ihtiyacınız yok
nacholibre

@nacholibre Doğru noktalı virgül kullanımı yerine getirildi
Walter Roman

6

cssTüm görüşlerimin etrafına ağır bir javascript çözümü serpmek hoş olmayan bir seçenek gibi göründüğünden, buna gerçekten saf bir çözüm bulmak istedim . Sonunda , "birincil giriş mekanizmasının kullanıcının öğelerin üzerine gelmesine izin verip vermediğini" algılayabilen @ media.hover sorgusunu buldu . Bu, "gezinme" nin giriş cihazının doğrudan bir özelliğinden çok taklit edilmiş bir eylem olduğu dokunmatik cihazları önler.

Örneğin, bir bağlantım varsa:

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

O :hoverzaman, yalnızca cihaz bunu kolayca desteklediğinde güvenli bir şekilde biçimlendirebilirim css:

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

Modern tarayıcıların çoğu etkileşim ortamı özelliği sorgularını desteklerken, IE ve Firefox gibi bazı popüler tarayıcılar desteklemez . Benim durumumda bu iyi çalışıyor, çünkü Chrome'u yalnızca masaüstünde ve Chrome ve Safari'yi mobil cihazda desteklemeyi amaçladım.


Chrome geliştiricilerinde cihazları taklit ettiğinizde işe yarayan güzel bir çözüm. Ancak yine de Chrome Android için çalışmıyor :-(
Sjeiti

Bence bu en uygun ve doğru çözüm. Umarım yakında W3C standartlarına eklenecektir.
GProst

5

Benim çözümüm, HTML etiketine hover-active css sınıfı eklemek ve bunu tüm CSS seçicilerinin başında kullanmaktır: hover ve bu sınıfı ilk touchstart olayında kaldırın.

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

Bir dokunma olayını dinlemek yerine test edebilirsiniz 'ontouchstart' in window. örneğinif ('ontouchstart' in window) document.querySelector('html').classList.remove('hover-active');
Yuval A.

@YuvalA. Dokunma olayını beklememin nedeni, işaretçi ve dokunma destekli cihazların olması ve kullanıcının imleci kullanması, imleci kaldırmak istemiyorum. Kullanıcının dokunmayı ve ardından işaretleyiciyi kullanması mümkündür, ancak bununla ilgili yapacak çok
şeyim

2

Aynı sorunu çözmek için yaptığım şey, bir özellik algılamaya sahip olmak ( bu kod gibi bir şey kullanıyorum ), onTouchMove'un tanımlanıp tanımlanmadığını görmek ve eğer öyleyse css sınıfını "touchMode" gövdesine eklerim, yoksa eklerim " desktopMode".

Daha sonra, bazı stil efektlerinin yalnızca dokunmatik bir cihaza veya yalnızca bir masaüstüne uygulandığı her seferinde, css kuralı uygun sınıfın başına eklenir:

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

Düzenleme : Bu strateji elbette css'nize birkaç ekstra karakter ekler, bu nedenle css boyutuyla ilgili endişeleriniz varsa, touchMode ve desktopMode tanımlarını arayabilir ve bunları farklı dosyalara koyabilirsiniz, böylece her cihaz için optimize edilmiş css sunabilirsiniz. tip; ya da üretim yapmadan önce sınıf adlarını çok daha kısa bir adla değiştirebilirsiniz.


2

Doğru, ben de benzer bir sorun yaşadım ama bunu medya sorguları ve basit CSS ile çözmeyi başardım. Eminim burada bazı kuralları çiğniyorum, ama bu benim için çalışıyor.

Temelde birinin yaptığı büyük bir uygulamayı alıp yanıt verebilir hale getirmek zorunda kaldım. JQueryUI kullandılar ve benden jQuery'lerinin hiçbirini kurcalamamamı istediler, bu yüzden sadece CSS kullanmakla sınırlı kaldım.

Dokunmatik ekran modunda düğmelerinden birine bastığımda, gezinme efekti, düğmenin eylemi yürürlüğe girmeden önce bir saniye boyunca yanmaya başladı. İşte nasıl düzelttim.

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

       #buttonOne{
            height: 44px;
        }


        #buttonOne:hover{
            display:none;
        }
}   

2

Projemde bu sorunu https://www.npmjs.com/package/postcss-hover-prefix ve https://modernizr.com/ kullanarak çözdük. Önce çıktı css dosyalarını postcss-hover-prefix. .no-touchTüm css hoverkuralları için ekler .

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

olur

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

Çalışma zamanında, böyle etiketlemek Modernizriçin otomatik olarak css sınıfları eklerhtml

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

Css plus Modernizr'in bu tür sonradan işlenmesi, dokunmatik cihazlar için fareyle üzerine gelmeyi devre dışı bırakır ve diğerleri için etkinleştirir. Aslında bu yaklaşım, aynı sorunu nasıl çözdükleri Bootstrap 4'ten esinlenmiştir: https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#sticky-hoverfocus-on-mobile


1

mouseLeaveDokunmatik ekranda bir öğeye her dokunduğunuzda olayı tetikleyebilirsiniz . İşte tüm <a>etiketler için bir çözüm :

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

JSHint "döngü içinde işlev yapma" diyor.
NetOperator Wibby

Bu bir hack. İyi uygulama olarak kabul edilebilecek yeniden kullanılabilir bir kod DEĞİLDİR. @NetOperatorWibby
Said Kholov

İyi uygulama olarak kabul edilemeyecek bir kod göndermek gerçekten yararlı değil. Bıçak yarasına yara bandı koymak gibi.
NetOperator Wibby

1

Iv'd, soruna modernizr veya başka bir şeyle dokunmayı algıladığınız ve html öğesinde bir dokunma sınıfı belirlediğiniz anlamına gelen 2 çözüm buldu.

Bu iyi ama pek desteklenmiyor :

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

Ancak bunun çok iyi bir desteği var :

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

Benim için kusursuz çalışıyor, tüm vurgulu efektlerin bir düğmeye dokunduğunuz zamanki gibi olmasını sağlıyor, fare olayları için ilk gezinme efekti olarak yanacak ancak buggy olmayacak.

Dokunmasız cihazlardan dokunmayı algılamak bence modernizr en iyi işi yaptı:

https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js

DÜZENLE

Bu soruna daha iyi ve daha basit bir çözüm buldum

İstemcinin dokunmatik bir cihaz olup olmadığı nasıl belirlenir


0

Oldukça garip bir sorun gibi göründüğü için CSS'nizi görmeniz yardımcı olabilir. Ama yine de, bu oluyorsa ve her şey yolundaysa, fareyle üzerine gelme efektini javascript'e kaydırmayı deneyebilirsiniz (jquery'yi de kullanabilirsiniz). Basitçe fareyle üzerine gelme veya daha iyisi mouseenter olayına bağlanın ve olay patladığında öğenizi aydınlatın.

Son örneğe buradan göz atın : http://api.jquery.com/mouseover/ , olay başladığında günlüğe kaydetmek ve oradan almak için benzer bir şey kullanabilirsiniz!


CSS hakkında özel bir şey yok; düzenlememi gör. Ve ben zaten denedim mouseenter; nafile. Dokunmak "görünmez fare imlecini" hareket ettirir, böylece mouseenterve mousemove(ve mouseleavebaşka bir yere dokunduğunuzda) tetiklenir .
Joe White

0

JavaScript kullanmaktan memnunsanız , sayfanızda Modernizr'i kullanabilirsiniz . Sayfa yüklendiğinde, dokunmatik olmayan bir tarayıcı html etiketine '.no-touch' sınıfını ekleyecektir, ancak dokunmatik ekranlı bir tarayıcı için html etiketinde html etiketine '.touch' sınıfı eklenecektir. .

O zaman bu, mouseenter ve mouseleave dinleyicilerinizi eklemeye karar vermeden önce html etiketinin dokunmasız sınıfa sahip olup olmadığını kontrol etmenin basit bir örneğidir.

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

Dokunmatik ekranlı bir cihaz için olayların dinleyicisi olmayacağından, dokunduğunuzda fareyle üzerine gelme etkisi olmayacaktır.


CSS ile yapılabildiğinde javascript (jquery) kullanmayın, bilgisayar gücü
israfıdır

1
Daha basit, CSS'nizde .touchve için ayrı kurallar tanımlayabilirsiniz .no-touch. Cevabınızı Modernizer ile birlikte CSS'de yeniden yazmak html.no-touch .box:hover {background-color: "#0000ff"}ve hiçbir şey tanımlamamak html.touch .box:hoverişe yaramalı, çünkü OP yalnızca mobil :hovere- postalardan kaçınmaya çalışıyor .
Walter Roman

0

Yakın zamanda yaptığım bir projede, bu sorunu jQuery'nin temsilci olaylar özelliği ile çözdüm. Bir jQuery seçici kullanarak belirli öğeleri arar ve fare öğenin üzerindeyken bu öğelere bir CSS sınıfı ekler / kaldırır. Windows 8 çalıştıran dokunmatik özellikli bir dizüstü bilgisayarda IE10 da dahil olmak üzere test edebildiğim kadarıyla iyi çalışıyor gibi görünüyor.

$(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: bu çözüm, elbette, CSS'nizi ": hover" seçicilerini kaldıracak şekilde değiştirmenizi ve "gezinilebilir" olmasını istediğiniz öğeleri önceden düşünmenizi gerektirir.

Sayfanızda çok fazla öğe varsa (birkaç bin gibi) biraz yavaşlayabilir, çünkü bu çözüm sayfadaki tüm öğelerdeki üç tür olayları yakalar ve ardından seçici eşleşirse işini yapar. CSS sınıfına "hover" yerine "mouseover" adını verdim çünkü hiçbir CSS okuyucusunun ".hover" yazdığım yerde ": hover" okumasını istemiyordum.


0

İşte benim çözümüm: http://jsfiddle.net/agamemnus/g56aw709/ - aşağıdaki kod.

Birinin yapması gereken tek şey ": hover" kelimesini ".hover" a dönüştürmek ... işte bu! Bununla geri kalanı arasındaki en büyük fark, bunun gibi tekil olmayan öğe seçicilerde de çalışacak olmasıdır .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

Sayfanıza Modernizr ekleyin ve bunun yerine fareyle üzerine gelme durumlarınızı şu şekilde ayarlayın:

html.no-touchevents .box:hover {
    background: blue;
}

0

Gelecekten merhaba, muhtemelen pointerve / veya hovermedya sorgusunu kullanmak istersiniz . handheldMedya sorgusu kullanımdan kaldırıldı.

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

-1

Bir süredir olmasına rağmen bu kolay 2019 jquery çözümünü deneyin;

  1. bu eklentiyi başlığa ekleyin:

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

  2. bunu js'ye ekle:

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

  3. bunun için önerilen bazı varyasyonlar şunlardır:

    $(":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`

notlar

  • araç ipuçlarını etkilemekten kaçınmak için eklentiyi bootstrap.js'den önce yerleştirin
  • Safari veya Chrome kullanılarak yalnızca iphone XR ios 12.1.12 ve ipad 3 ios 9.3.5 üzerinde test edilmiştir.

Referanslar:

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

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

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.