: aktif sözde sınıf mobil safaride çalışmıyor


109

İPhone / iPad / iPod'daki Webkit'te, bir <a>etiket için bir: active sözde sınıf için stil belirtmek , öğeye dokunduğunuzda tetiklenmez. Bunu nasıl tetikleyebilirim? Örnek kod:

<style> 
a:active { 
    background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>

Yanıtlar:


238
<body ontouchstart="">
    ...
</body>

Sayfadaki tüm düğmeleri düzelten her düğme öğesinin aksine, yalnızca bir kez uygulandı. Alternatif olarak, ' Fastclick ' adlı bu küçük JS kitaplığını kullanabilirsiniz . Dokunmatik cihazlarda tıklama olaylarını hızlandırır ve bu sorunu da giderir.


19
ontouchstartOlmadan eklemek yeterli değil =""mi? (HTML5)
feklee

2
Gelecekteki okuyucular için burada bir demo yayınladım: http://jsbin.com/EjiWILe/3/ . İOS cihazınızdaki işlevselliği kontrol edin.
mhulse

6
Vücuda neden boş bir dinleyici uyguladığınızı açıklayabilir misiniz? Nasıl çalışır?
Maurizio Battaghini

2
Ben: odak kullanıyordum ve bu da bunun için çalışıyor. Sihir için teşekkürler.
TecBrat

Bu yöntemi kullanarak iOS 9.1 ve 9.3'te sayfa donmaları alıyorum ... bu sürümlerde js hatası vardı, ancak yine de bu işletim sistemlerinde% 0,5 kullanıcısı var
Ruskin

55

Diğer yanıtların da belirttiği gibi, iOS Safari :active, öğeye bir dokunma olayı eklenmedikçe sözde sınıfı tetiklemez , ancak şu ana kadar bu davranış "sihirli" olmuştur. Safari Geliştirici Kitaplığı'nda bunu açıklayan şu küçük habere rastladım (vurgu benim):

-webkit-tap-highlight-colorCSS özelliğini, düğmeleri masaüstüne benzer davranacak şekilde yapılandırmak için bir dokunma olayı ayarlamayla birlikte de kullanabilirsiniz . İOS'ta, fare olayları o kadar hızlı gönderilir ki kapalı veya etkin durum asla alınmaz. Bu nedenle, :activesözde durum yalnızca HTML öğesinde ayarlanmış bir dokunma olayı olduğunda tetiklenir - örneğin, öğe üzerinde ontouchstart aşağıdaki gibi ayarlandığında:

<button class="action" ontouchstart=""
        style="-webkit-tap-highlight-color: rgba(0,0,0,0);">
    Testing Touch on iOS
</button>

Artık düğmeye dokunulduğunda ve iOS'ta tutulduğunda, düğme, çevresindeki şeffaf gri renk görünmeden belirtilen renge dönüşür.

Başka bir deyişle, bir ontouchstartolay ayarlamak (boş olsa bile) tarayıcıya açık bir şekilde dokunma olaylarına tepki vermesini söyler.

Bence bu kusurlu bir davranıştır ve muhtemelen "mobil" web'in temelde mevcut olmadığı zamana dayanmaktadır (ne demek istediğimi görmek için bağlantılı sayfadaki ekran görüntülerine bakın) ve her şey fare odaklıydı. Android gibi diğer, daha yeni mobil tarayıcıların, iOS için gerekli olanlara benzer herhangi bir hile olmadan dokunulduğunda ``: active '' sözde durumu gayet iyi görüntülediğini not etmek ilginçtir.

(Yan not: iOS'ta kendi özel stillerinizi kullanmak istiyorsanız, yukarıdaki aynı bağlantılı sayfada açıklandığı gibi :active, -webkit-tap-highlight-colorCSS özelliğini kullanarak iOS'un sözde durum yerine kullandığı varsayılan gri yarı saydam kutuyu da devre dışı bırakabilirsiniz. .)


Bazı deneylerden sonra , tüm dokunma olaylarının balonlaştığı ontouchstart, <body>öğe üzerinde bir olay ayarlamanın beklenen çözümü tam olarak çalışmıyor. Sayfa yüklendiğinde, o zaman gayet iyi çalışıyor, ama aşağı kaydırma ve görüntü alanının dışında bir öğe dokunarak ne zaman eleman görüntü kapısında görünür durumdaysa değil tetiklemek olması gerektiği gibi sözde devlet. Yani, yerine:active

<!DOCTYPE html>
<html><body ontouchstart></body></html>

gövdede köpüren olaya güvenmek yerine olayı tüm öğelere ekleyin (jQuery kullanarak):

$('body *').on('touchstart', function (){});

Ancak, bunun performans etkilerinin farkında değilim, bu yüzden dikkatli olun.


DÜZENLEME: Bu çözümde ciddi bir kusur var: Sayfayı kaydırırken bir öğeye dokunmak bile :activesözde durumu etkinleştirecektir . Hassasiyet çok güçlü. Android, durum gösterilmeden önce, sayfa kaydırıldığında iptal olan çok küçük bir gecikme getirerek bunu çözer. Bunun ışığında, bunu yalnızca belirli öğelerde kullanmanızı öneririm. Benim durumumda, temelde sayfalarda gezinmek ve eylemler göndermek için düğmelerin bir listesi olan alanda kullanılmak üzere bir web uygulaması geliştiriyorum. Sayfanın tamamı bazı durumlarda hemen hemen düğme olduğundan, bu benim için işe yaramayacak. Bununla birlikte, :hoverbunun yerine sözde durumu dolduracak şekilde ayarlayabilirsiniz . Varsayılan gri kutuyu devre dışı bıraktıktan sonra bu mükemmel çalışır.


6
Sadece nasıl değil , nedeninin harika açıklaması ! Teşekkürler!
coderfin

6
Geliştiricilere sadece "sihirli" bir tarif değil, anlayış verdikleri için oy verildi. Bu, diğerlerinden son derece daha bilgilendiricidir; bunu bizim için yazdığınız için teşekkür ederiz.
user508633

Ayrıntılı açıklama + uyarılar için oy verildi. Bu doğru cevap olmalı.
Master of Ducks

39

<a> etiketinize ontouchstart için bir olay işleyici ekleyin. Bu, CSS'nin sihirli bir şekilde çalışmasına neden olur.

<a ontouchstart="">Click me</a>

3
Üzgünüm, bu eski cevap, ama bu neden işe yarıyor? Bir sebep olarak "sihirli" umurumda değil, ama neden işe yaradığını açıklayabilirseniz, daha fazla ayrıntı okumak isterim.
mhulse

1
@mhulse Ayrıca nedenini bilmek isterim.
Jesse Rusak

Ha! Aynı gemideyiz. Biraz araştırma yapmaya çalışacağım ve konuyla ilgili (yarı) resmi belgelere bir bağlantı göndereceğim. Bu tekniğin işe yaramasını seviyorum, sadece merak ediyorum neden?
mhulse

7

Bu benim için çalışıyor:

document.addEventListener("touchstart", function() {},false);

Not: Bu numarayı yaparsanız, Mobil Safari aşağıdaki CSS kuralını kullanarak uygulanan varsayılan hafifçe vurma-vurgulama rengini de kaldırmaya değer.

html {
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}

5

8 Aralık 2016 itibarıyla kabul edilen yanıt ( <body ontouchstart="">...</body>) benim için Safari 10'da (iPhone 5s) çalışmıyor: Bu saldırı yalnızca sayfa yüklenirken görünen öğeler için işe yarıyor.

Ancak ekleyerek:

<script type='application/javascript'>
  document.addEventListener("touchstart", function() {}, false);
</script>

için headşimdi de kaydırma sırasında tüm dokunmatik olayları tetiklediğini olumsuz ile, istediğim gibi çalışmıyor mu :activedokundu elemanlarında sözde devlet. (Bu sizin için bir sorunsa, FighterJet'in :hover geçici çözümünü düşünebilirsiniz .)


4
//hover for ios
-webkit-tap-highlight-color: #ccc;

Bu benim için çalışıyor, vurgulamak istediğiniz öğenin üzerine CSS'nize ekleyin


3

Tüm sözde sınıfları mı yoksa yalnızca birini mi kullanıyorsunuz? En az iki kullanıyorsanız, bunların doğru sırada olduğundan emin olun, yoksa hepsi bozulur:

a:link
a:visited
a:hover
a:active

..bu sırayla. Ayrıca, yalnızca: active kullanıyorsanız, stilini değiştirmemiş olsanız bile bir: link ekleyin.


sözde sınıfları şekillendirirken sıranın önemli olması hakkında harika bir ipucu.
brianarpie

1

Bu sorunu sizin için çözmesi gereken bir araç yayınladım.

Yüzeyde sorun basit görünüyor, ancak gerçekte, zaman aşımı işlevleri ve "bağlantı listesini kaydırdığınızda ne olur" veya "bağlantıya bastığınızda ne olur" gibi şeyler de dahil olmak üzere dokunma ve tıklama davranışının oldukça kapsamlı bir şekilde özelleştirilmesi gerekiyor. fareyi / parmağınızı etkin alandan uzaklaştırın "

Bu, hepsini bir kerede çözmelidir: https://www.npmjs.com/package/active-touch

Aktif stillerinizin .active sınıfına atanması veya kendi sınıf adınızı seçmeniz gerekir. Komut dosyası, varsayılan olarak tüm bağlantı öğeleriyle çalışır, ancak kendi seçiciler dizinizle bunun üzerine yazabilirsiniz.

Dürüst, faydalı geri bildirimler ve katkılar çok takdir edilmektedir!


2
Bu kütüphane, her bağlantı öğesine 9 (pasif olmayan) olay dinleyicisi ekler, ancak removeEventListener'ı çağırmaz - bu tek sayfalı uygulamalar için büyük bir kusur olur diye düşünüyorum
Drenai

1
Teşekkürler Ryan. Bu kodu bir yılı aşkın süredir desteklemiyorum veya kullanmıyorum; Onu indireceğim. Biraz düşündükten ve denemeden sonra, tarayıcılar tarafından hesaba katılmayan veya üzerinde düşünülmeyen etkileşimleri zorlamak yerine uygulamanın tasarımını değiştirdim.
dmitrizzle

1

Ontouchstart'ı kullanmak istemeyenler için bu kodu kullanabilirsiniz

<script>
 document.addEventListener("touchstart", function(){}, true);
</script>

1

Bu yanıtı ve varyantlarını denedim , ancak hiçbiri güvenilir bir şekilde işe yaramadı (ve bunun gibi şeyler için 'sihre' güvenmekten hoşlanmıyorum). Bunun yerine, yalnızca Apple'da değil, tüm platformlarda mükemmel çalışan aşağıdakileri yaptım:

  1. Kullanılan Yeniden adlandırılan css bildirimleri :activeiçin .active.
  2. Etkilenen tüm öğelerin bir listesini yaptı pointerdown/mousedown/touchstartve .activesınıfı uygulamak için pointerup/mouseup/touchendolay işleyicileri ve onu kaldırmak için olay işleyicileri ekledi . JQuery kullanarak:

    let controlActivationEvents = window.PointerEvent ? "pointerdown" : "touchstart mousedown";
    let controlDeactivationEvents = window.PointerEvent ? "pointerup pointerleave" : "touchend mouseup mouseleave";
    
    let clickableThings = '<comma separated list of selectors>';
    $(clickableThings).on(controlActivationEvents,function (e) {
        $(this).addClass('active');
    }).on(controlDeactivationEvents, function (e) {
        $(this).removeClass('active');
    });

Bu biraz sıkıcıydı, ancak şimdi Apple OS sürümleri arasındaki kırılmaya karşı daha az savunmasız olan bir çözümüm var. (Ve böyle bir kırılmaya kimin ihtiyacı var?)


Bence soruya bir cevap veriyor. : Active sözde sınıfı mobil Safari'de çalışmak için sağlamanın güvenilir bir yolu yok gibi görünüyor. Ancak bu, verdiğim çözümü kullanarak güvenilir bir şekilde taklit edilebilir. Bunu uygulamamda yaptım ve tüm platformlarda mükemmel çalışıyor. Ve açıklama yoluyla kod ekledim.
daffinm

0

Çözüm, aşağıdakiler :targetyerine güvenmektir :active:

<style> 
a:target { 
    background-color: red;
}
</style>
<!-- snip -->
<a id="click-me" href="#click-me">Click me</a>

Stil, bağlantı mobil cihazlarda bile güçlü olan mevcut URL tarafından hedeflendiğinde tetiklenecektir. Bunun dezavantajı, url'deki çapayı temizlemek için başka bir bağlantıya ihtiyacınız olmasıdır. Tam örnek:

a:target { 
    background-color: red;
}
<a id="click-me" href="#click-me">Click me</a>
<a id="clear" href="#">Clear</a>


-3

Bu soruyla% 100 ilgili değil, ancak bunu başarmak için css kardeş hack'ini de kullanabilirsiniz.

HTML

<input tabindex="0" type="checkbox" id="145"/>
<label for="145"> info</label>
<span> sea</span>

SCSS

input {
    &:checked + label {
      background-color: red;
    }
  }

Saf html / css araç ipucunu kullanmak istiyorsanız

span {
  display: none;
}
input {
    &:checked ~ span {
      display: block;
    }
  }

-6
<!DOCTYPE html>

<html lang="en">

<head>
<meta charset="utf-8">

<title></title>

<style>
        a{color: red;}
        a:hover{color: blue;}
</style>
</head>

<body>

        <div class="main" role="main">
                <a href="#">Hover</a>
        </div>

</body>
</html>

1
SSS'ye göre imzalara ve kendi kendini tanıtmaya izin verilmez.
LittleBobbyTables - Au Revoir
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.