Javascript ile dokunmatik ekranlı cihazları algılama


129

Javascript / jQuery'de, istemci cihazda bir fare olup olmadığını nasıl tespit edebilirim?

Kullanıcı faresini bir öğenin üzerine getirdiğinde küçük bir bilgi paneli yukarı kayan bir sitem var. Fareyle üzerine gelmeyi algılamak için jQuery.hoverIntent kullanıyorum, ancak bu açıkça iPhone / iPad / Android gibi dokunmatik ekranlı cihazlarda çalışmıyor. Bu yüzden bu cihazlarda bilgi panelini göstermek için dokunmaya geri dönmek istiyorum.


6
Neden ikisini birden yapamıyorsun? Dokunma işlevi dokunmatik olmayan cihazlarda istenmiyor mu?
EMPraptor

1
Bazı yeni cihazlar desteklemediğinden :hover, (birden fazla cihaz için bir stil sayfasını kodlarken) :hovertamamen kozmetik amaçlı kullanmak muhtemelen daha iyidir .
köle

@empraptor: iyi nokta - evet bunu yapabilirim. Ancak ... paneli her zaman dokunmatik ekranlı cihazlarda göstermeyi de düşünüyorduk - bu durumda desteği algılayabilmem gerekiyordu.
Brad Robinson

Paneli dokunmatik ekranlı cihazlarda her zaman gösterebilirseniz, diğer cihazlarda da gösteremez miydiniz? Panel ne kadar büyük ve neden yalnızca üzerine gelindiğinde / dokunulduğunda gösterilmesi isteniyor?
EMPraptor

Yanıtlar:


12

Yapmak hoverve clickher ikisi için +1 . Diğer bir yol, CSS medya sorgularını kullanmak ve bazı stilleri yalnızca daha küçük ekranlar / mobil cihazlar için kullanmak olabilir; bunlar, dokunma / dokunma işlevine sahip olma olasılığı en yüksek olanlardır. Dolayısıyla, CSS aracılığıyla belirli stilleriniz varsa ve jQuery'den bu öğeleri mobil cihaz stili özellikleri için kontrol ederseniz, mobil cihazlara özel kod yazmak için bunlara bağlanabilirsiniz.

Buraya bakın: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/


1
İyi çözüm, muhtemelen bir () bağ ile gezinme kontrolü gibi bir şey yapabilirsiniz, böylece yalnızca ilk seferde ateşlenir.
Timothy Perez

Sorun şu ki, ekran genişliğine göre hedeflerseniz, cihazınızı döndürdüğünüzde (iphone 6+ 736x414'ü alalım) aynı stile sahip olmayacak. Yani en iyi çözüm değil: /
Antoni

266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Not : Bir cihazın dokunmatik olayları desteklemesi, yalnızca dokunmatik ekranlı bir cihaz olduğu anlamına gelmez. Pek çok cihaz (Asus Zenbook'um gibi), gerçek dokunma giriş mekanizmaları olmasa bile hem tıklama hem de dokunma olaylarını destekler. Dokunma desteği için tasarım yaparken, her zaman tıklama etkinliği desteğini dahil edin ve hiçbir cihazın yalnızca biri veya diğeri olduğunu varsaymayın.


33
Modernizr belgelerinde açıklandığı gibi, bu yalnızca tarayıcı kapasitesini algılar , cihaz kapasitesini değil ... Dokunmatik özellikli bir tarayıcı çalıştıran dokunmatik girişi olmayan cihazlarda yanlış pozitif sonuç alırsınız. Yalnızca bir dokunma olayının gerçekleşmesini beklemeden, aygıt dokunma özelliğini yerel olarak algılamanın bir yolunu bilmiyorum .
Stu Cox

12
IE 10 touch'ı da algılamak için kullanıyorum: (window.navigator.msMaxTouchPoints || (document.documentElement içinde 'ontouchstart'));
Alexander Kellett

2
'ontouchstart' in document.documentElement BlackBerry 9300'de yanlış bir şekilde doğru döndürür
basit

10
@typhon, yazılım (Win 8, modern tarayıcılar) dokunmayı destekliyorsa, bu her zaman doğru olacaktır - dokunmayı desteklemeyen donanımda (masaüstü, standart monitör, fare ve klavye) olsanız bile. Bu nedenle bu çözüm güncel değil.
Barney

1
funnyItsNotCamelCaseAsJsIsThroughout. Demek istediğim, insanların artık kodu kopyalaması, yapıştırması ve düzenlemesi gerekecek ... :)
Ross

20

Pencere için test bulundu.Touch, Android'de çalışmadı, ancak şu işe yarıyor:

function is_touch_device() {
  return !!('ontouchstart' in window);
}

Şu makaleye bakın: JavaScript kullanarak bir 'dokunmatik ekranlı' cihazı algılamanın en iyi yolu nedir?


Bu, dokunmatik ekranları algılar ancak dikkatli olun çünkü dokunmatik ekranlı dizüstü bilgisayarlar için de DOĞRU döndürür. Dokunmatik ekranlı dizüstü bilgisayarlar için DOĞRU döndürdüğü için kullanıcının telefondan / tabletten VEYA bilgisayardan / dizüstü bilgisayardan olup olmadığını ayırt etmeye çalışıyorsanız bu bir sorun olabilir.
birleştir

8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

MsMaxTouchPoints ile birlikte maxTouchPoints kullanma nedeni:

Microsoft, Internet Explorer 11'den başlayarak, bu özelliğin Microsoft satıcısının önekli sürümünün (msMaxTouchPoints) kaldırılabileceğini belirtti ve bunun yerine maxTouchPoints kullanılmasını önerdi.

Kaynak: http://ctrlq.org/code/19616-detect-touch-screen-javascript


bu çalıştı ve çalıştı google chrome geliştirici araçları simüle cihaz teşekkür ederim
Behnam Mohammadi

7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Her yerde çalışır !!


Bunun fareyle ne alakası var? (asıl soru)
hexalys

isTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew


4

Google Chrome, bu konuda yanlış pozitifler döndürüyor gibi görünüyor:

var isTouch = 'ontouchstart' in document.documentElement;

Sanırım "dokunma olaylarını taklit etme" yeteneği ile bir ilgisi var (F12 -> sağ alt köşedeki ayarlar -> "geçersiz kılmalar" sekmesi -> son onay kutusu). Varsayılan olarak kapalı olduğunu biliyorum, ancak sonuçlardaki değişikliği buna bağlarım (Chrome'da çalışmak için kullanılan "in" yöntemi). Ancak, test ettiğim kadarıyla bu işe yarıyor gibi görünüyor:

var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);

Tüm tarayıcılarda bu kodu typeof "nesne" durumunda çalıştırıyorum, ancak bunun tanımsız olduğunu bildiğim için daha emin hissediyorum :-)

IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, iPad 21.0.1180.80 için Chrome ve iPad Safari'de test edilmiştir. Birinin daha fazla test yapıp sonuçları paylaşması harika olurdu.


Her iki yöntem de FF 23 ve Chrome 28 yüklü Win 8 PC'de yanlış pozitifler döndürüyor. Bu her zaman böyle mi yoksa bir zamanlar bu bilgisayara bir dokunmatik ekran taktığım için mi - muhtemelen FF ve Chrome'u yüklemeden önce - ama artık değil mi? "Dokunma olaylarını taklit et" seçenek setim yok.
typhon

Uh, yeni donanım konusunda her zaman bir mücadele oluyor. Tarayıcıların işletim sistemi soyutlama katmanları ile çalışması gerekir ... bu her zaman her şeyi uygulamaz ... Kısacası, JS ile tarayıcıya güvenmeniz gerekir :) Asla evrensel bir yol yoktur.
Ash

Bunların ikisi de dokunmatik olmayan bir dizüstü bilgisayarda Ubuntu Firefox'ta doğru olarak geri dönüyor.
NoBugs

4

Bunu sitelerimden biri için yazdım ve muhtemelen en kusursuz çözüm. Özellikle Modernizr bile dokunma algılama konusunda yanlış pozitifler alabildiğinden.

JQuery kullanıyorsanız

$(window).one({
  mouseover : function(){
    Modernizr.touch = false; // Add this line if you have Modernizr
    $('html').removeClass('touch').addClass('mouse');
  } 
});

veya sadece saf JS ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}

4
Dikkatli olsa olun: En az iPad'ler çok onmouseovers atmak
Joril

14
Lanet olsun sana Apple!
Timothy Perez

Ve bir Windows tablette IE kullanan kişiler hem dokunmatik hem de fareyi kullanmak isteyebilir.
Sebazzz

Bu gönderi, Windows Tablet ortaya çıkmadan önce yapıldı.
Timothy Perez

@ s427 - IE'yi kontrol ediyor ... sadece IE8 için bir kontrol yapın. <= IE8'e sahip herhangi bir mobil cihaz olduğunu sanmıyorum.
Timothy Perez

4

İlk gönderim / yorumum için: Hepimiz 'touchstart'ın tıklamadan önce tetiklendiğini biliyoruz. Ayrıca, kullanıcı sayfanızı açtığında şunları yapacağını biliyoruz: 1) fareyi hareket ettirecek 2) tıklayacak 3) ekrana dokunacak (kaydırmak için veya ... :))

Bir şey deneyelim:

// -> Başlat: jQuery

var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';

//attach a once called event handler to window

$(window).one('touchstart mousemove click',function(e){

    if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
        isTouchDevice = 'yes';
});

// <- Bitiş: jQuery

İyi günler!


3

Tartışmada yukarıda belirtilen aşağıdaki kodu test ettim

 function is_touch_device() {
    return !!('ontouchstart' in window);
 }

android Mozilla, chrome, Opera, android varsayılan tarayıcı ve iphone'da safari üzerinde çalışır ... hepsi olumlu ...

benim için sağlam görünüyor :)


Süper basit ve benim için iyi çalışıyor. Android'de (eski Galaxy Note) ve emülatörlerle (Chrome) ve iPad'de test edilmiştir.
Ralf

Chrome'da benim için yanlış bir pozitif döndürüyor.
James


2

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

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}

1
kaç platform, tarayıcı, işletim sistemi, cihaz üzerinde test ettiniz?
BerggreenDK

1
Android ve iOS (iPad) üzerinde FF, Chrome, Safari
Turtletrail

1
Yeterince güzel. Az önce masaüstünde test ettim ve IF yapısını biraz zorlaştıran bir sürü "tanımsız" aldım. Dönüş değerinizi biraz ayarlarsanız, şöyle: true == ("ontouchstart" pencerede || window.DocumentTouch && document instanceof DocumentTouch); O zaman doğru veya yanlış var :-)
BerggreenDK

2
Chrome'da, dokunmatik ekran olmadan bilgisayarımda penceredeki "ontouchstart" doğrudur, bu nedenle bu çalışmaz. Daha önce belirtildiği gibi, bu, tarayıcının dokunma özellikli olup olmadığını test eder. Ayrıca, true == hiçbir şey yapmaz ve atlanmalıdır.
rakensi

1
Bunu yerleşik emülatörle Chrome'da denediğimde, öykünücüde açıldığında dokunmayı algılayacak ve kapatıldığında dokunmayı algılamayacak. Benim için iyi çalışıyor. Ama: Prasad'ın (aşağıda) || 'i kullanmayan kısa versiyonunu kullanıyorum. Turtletrail kodunda. Ve: Cihazların% 100'ünde çalışıp çalışmadığı umurumda değil. % 99 benim için yapacak.
Ralf

1

Eğer kullanırsanız Modernizr , çok kolay kullanmaktır Modernizr.touchönce belirtildiği gibi.

Bununla birlikte, Modernizr.touchgüvenli olmak için, 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));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

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

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

Ayrıca bu SO sorusuna bakın


2
Şu anda 4 soru için aynı yanıt ... ve bu sorduğu soru için bir çözüm değil.
jycr753

1
Buradaki soruyu cevapladığına inanıyorum
Peter-Pan

cevap değil ama kullanıcı dokunmadan önce cihazın dokunulabilir olup olmadığını tespit etmek isteyenler için bir ipucu olduğunu düşünüyorum
Shahadat Hossain Khan

1

JQuery Mobile'da şunları yapabilirsiniz:

$.support.touch

Bunun neden bu kadar belgelenmemiş olduğunu bilmiyorum .. ama tarayıcılar arası güvenlidir (mevcut tarayıcıların en son 2 sürümü).


0

Daha önce belirtildiği gibi, bir cihaz hem fareyi hem de dokunmatik girişi destekleyebilir. Çoğu zaman, soru "neyin desteklendiği" değil, "şu anda ne kullanıldığı" sorusudur.

Bu durumda, fare olaylarını (fareyle üzerine gelme dinleyicisi dahil) ve aynı şekilde dokunma olaylarını kaydedebilirsiniz.

element.addEventListener('touchstart',onTouchStartCallback,false);

element.addEventListener('onmousedown',onMouseDownCallback,false);

...

JavaScript, kullanıcı girdisine bağlı olarak doğru dinleyiciyi otomatik olarak çağırmalıdır. Bu nedenle, bir dokunma olayı durumunda, onTouchStartCallbackvurgulu kodunuzu taklit ederek ateşlenecektir.

Bir dokunuşun her iki tür dinleyiciyi, dokunmayı ve fareyi ateşleyebileceğini unutmayın. Ancak, dokunma dinleyicisi önce gelir ve arama yaparak sonraki fare dinleyicilerin ateşlemesini önleyebilir event.preventDefault().

function onTouchStartCallback(ev) {
    // Call preventDefault() to prevent any further handling
    ev.preventDefault();
    your code...
}

Burada daha fazla bilgi edinin .


-3

İPad geliştirme için kullanıyorum:

  if (window.Touch)
  {
    alert("touchy touchy");
  }
  else
  {
    alert("no touchy touchy");
  }

Daha sonra dokunma tabanlı olaylara (örn. Ontouchstart) veya fare tabanlı olaylara (örn. Onmousedown) seçici olarak bağlanabilirim. Henüz android üzerinde test etmedim.


1
Bu, Opera Mobile 10 veya Internet Explorer Mobile 6 (Windows Mobile 6.5) ile çalışmaz.
32'de çift

4
kötü tarayıcı / çapraz işletim sistemi / çapraz platform tavsiyesi.
BerggreenDK
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.