Mendeteksi perangkat layar sentuh dengan Javascript

129

Di Javascript / jQuery, bagaimana saya bisa mendeteksi jika perangkat klien memiliki mouse?

Saya punya situs yang menampilkan panel info kecil ketika pengguna mengarahkan mouse mereka ke suatu item. Saya menggunakan jQuery.hoverIntent untuk mendeteksi hover, tetapi ini jelas tidak bekerja pada perangkat layar sentuh seperti iPhone / iPad / Android. Jadi pada perangkat itu saya ingin kembali ketuk untuk menampilkan panel info.

Brad Robinson
sumber
6
Kenapa kamu tidak bisa melakukan keduanya? Apakah fungsionalitas keran tidak diinginkan di perangkat non-layar sentuh?
EMPraptor
1
Karena beberapa perangkat yang lebih baru tidak mendukung :hover, mungkin lebih baik (ketika mengkodekan satu stylesheet untuk beberapa perangkat) untuk digunakan :hoverhanya untuk keperluan kosmetik.
membanting tulang
@empraptor: poin bagus - ya saya bisa melakukan itu. Namun ... kami juga berpikir untuk selalu menampilkan panel pada perangkat layar sentuh - dalam hal ini saya harus dapat mendeteksi dukungan.
Brad Robinson
Jika Anda selalu dapat menampilkan panel di perangkat layar sentuh, tidak bisakah Anda menampilkannya di perangkat lain juga? Seberapa besar panel dan mengapa diinginkan untuk menunjukkannya hanya pada hover / tap?
EMPraptor

Jawaban:

12

+1 untuk melakukan hoverdan clickkeduanya. Salah satu cara lain bisa menggunakan kueri media CSS dan menggunakan beberapa gaya hanya untuk layar / perangkat seluler yang lebih kecil, yang mana yang paling mungkin memiliki fungsi sentuh / ketuk. Jadi, jika Anda memiliki beberapa gaya spesifik melalui CSS, dan dari jQuery Anda memeriksa elemen-elemen tersebut untuk properti gaya perangkat seluler yang dapat Anda kaitkan ke dalamnya untuk menulis kode khusus seluler Anda.

Lihat di sini: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

Moin Zaman
sumber
1
Solusi yang bagus, Anda mungkin bisa melakukan sesuatu seperti hover check dengan satu () bind sehingga hanya menyala pertama kali.
Timothy Perez
Masalahnya adalah jika Anda menargetkan berdasarkan lebar layar maka ketika Anda memutar perangkat Anda (mari kita ambil iphone 6+ 736x414) itu tidak akan memiliki gaya yang sama. Jadi bukan solusi terbaik: /
antoni
266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Catatan : Hanya karena perangkat mendukung acara sentuh tidak berarti perangkat itu hanya perangkat layar sentuh. Banyak perangkat (seperti Asus Zenbook saya) mendukung acara klik dan sentuh, bahkan ketika mereka tidak memiliki mekanisme input sentuh yang sebenarnya. Saat merancang untuk dukungan sentuh, selalu sertakan dukungan acara klik dan jangan pernah menganggap perangkat apa pun secara eksklusif salah satunya.

KevBurnsJr
sumber
33
Seperti yang dijelaskan dalam dokumen Modernizr, ini hanya mendeteksi kemampuan browser , bukan kemampuan perangkat ... Anda akan mendapatkan hasil positif palsu pada perangkat tanpa input sentuhan yang menjalankan browser yang mendukung sentuhan. Saya tidak tahu cara mendeteksi kemampuan sentuh perangkat secara asli, tanpa hanya menunggu peristiwa sentuhan terjadi.
Stu Cox
12
Untuk mendeteksi IE 10 touch, saya menggunakan: (window.navigator.msMaxTouchPoints || ('ontouchstart' di document.documentElement));
Alexander Kellett
2
'ontouchstart' in document.documentElement salah mengembalikan true pada BlackBerry 9300
Simpler
10
@ tipi jika perangkat lunak (Win 8, browser modern) mendukung sentuhan, ini akan selalu benar - bahkan jika Anda menggunakan perangkat keras (desktop, monitor standar, mouse dan keyboard) yang tidak mendukung sentuhan. Karena itu solusi ini sudah ketinggalan zaman.
Barney
1
funnyItsNotCamelCaseAsJsIsThroughout. Maksud saya orang sekarang perlu menyalin, menempel DAN mengedit kode ... :)
Ross
20

Ditemukan pengujian untuk window.Touch tidak berfungsi di Android tetapi ini berfungsi:

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

Lihat artikel: Apa cara terbaik untuk mendeteksi perangkat 'layar sentuh' menggunakan JavaScript?

hallodom
sumber
Ini mendeteksi layar sentuh tetapi berhati-hatilah karena ia mengembalikan TRUE untuk laptop dengan layar sentuh juga. Ini bisa menjadi masalah jika Anda mencoba untuk membedakan apakah pengguna dari ponsel / tablet ATAU komputer / laptop karena untuk laptop dengan layar sentuh itu mengembalikan BENAR.
Gabungkan
8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Alasan untuk menggunakan maxTouchPoints bersama dengan msMaxTouchPoints:

Microsoft telah menyatakan bahwa mulai dengan Internet Explorer 11, versi prefixed vendor Microsoft properti ini (msMaxTouchPoints) dapat dihapus dan merekomendasikan menggunakan maxTouchPoints sebagai gantinya.

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

pengguna
sumber
ini bekerja dan bekerja di perangkat simulasi pengembang google chrome terima kasih
Behnam Mohammadi
7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Bekerja di mana saja !!

Kode Mata-mata
sumber
Dan apa hubungannya dengan mouse? (pertanyaan aktual)
hexalys
Akan lebih mudah dilakukanisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew
4

Saya menggunakan:

if(jQuery.support.touch){
    alert('Touch enabled');
}

di jQuery mobile 1.0.1

Menandai
sumber
2
jQuery merekomendasikan agar tidak menggunakan jQuery.support yang mendukung Modernizr ( modernizr.com ): referensi - api.jquery.com/jQuery.support -
Jonathan Marzullo
4

Google Chrome tampaknya mengembalikan hasil positif yang salah:

var isTouch = 'ontouchstart' in document.documentElement;

Saya kira itu ada hubungannya dengan kemampuannya untuk "meniru acara sentuh" ​​(F12 -> pengaturan di sudut kanan bawah -> "menimpa" tab -> kotak centang terakhir). Saya tahu ini dinonaktifkan secara default, tetapi itulah yang saya sambungkan dengan perubahan hasil (metode "dalam" yang digunakan untuk bekerja di Chrome). Namun, ini tampaknya berhasil, sejauh yang saya uji:

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

Semua browser saya sudah menjalankan kode itu pada status typeof adalah "objek" tapi saya merasa lebih yakin mengetahui bahwa itu adalah apa pun kecuali yang tidak terdefinisi :-)

Diuji pada IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome untuk iPad 21.0.1180.80 dan iPad Safari. Akan lebih keren jika seseorang melakukan beberapa tes lagi dan membagikan hasilnya.

Abu
sumber
Kedua metode mengembalikan false positive pada Win 8 PC dengan FF 23 dan Chrome 28. Apakah ini selalu terjadi atau karena saya pernah memiliki layar sentuh yang terpasang pada komputer ini - mungkin sebelum menginstal FF dan Chrome - tetapi sekarang tidak lagi? Saya tidak memiliki set opsi "meniru acara sentuh".
typhon
Eh, selalu ada kesulitan dengan perangkat keras baru. Browser harus bekerja dengan lapisan abstraksi OS ... yang tidak selalu mengimplementasikan semuanya ... singkatnya, dengan JS Anda harus bergantung pada browser :) Tidak pernah ada cara universal.
Ash
Keduanya mengembalikan true di Ubuntu Firefox pada laptop non-touch.
NoBugs
4

Tulis ini untuk salah satu situs saya dan mungkin merupakan solusi paling mudah. Terutama karena bahkan Modernizr bisa mendapatkan hasil positif palsu pada deteksi sentuhan.

Jika Anda menggunakan jQuery

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

atau hanya JS murni ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}
Timothy Perez
sumber
4
Berhati-hatilah: paling tidak iPads melempar onmouseover
Joril
14
Sialan kamu Apple!
Timothy Perez
Dan orang yang menggunakan IE pada tablet Windows mungkin ingin menggunakan sentuhan dan mouse.
Sebazzz
Posting ini dibuat sebelum Tablet Windows muncul.
Timothy Perez
@ s427 - Fecking IE ... lakukan saja pemeriksaan untuk IE8. Saya tidak berpikir ada perangkat seluler dengan <= IE8.
Timothy Perez
4

Untuk posting / komentar pertama saya: Kita semua tahu bahwa 'touchstart' dipicu sebelum klik. Kita juga tahu bahwa ketika pengguna membuka halaman Anda ia akan: 1) menggerakkan mouse 2) klik 3) sentuh layar (untuk menggulir, atau ... :))

Mari kita coba sesuatu:

// -> Mulai: 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';
});

// <- Akhir: jQuery

Semoga harimu menyenangkan!

silassare
sumber
3

Saya telah menguji kode berikut yang disebutkan di atas dalam diskusi

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

bekerja di android Mozilla, chrome, Opera, browser default android dan safari di iphone ... semua positif ...

tampaknya solid untukku :)

Prasad
sumber
Sangat sederhana dan berfungsi dengan baik untuk saya. Diuji di Android (Galaxy Note lama) dan dengan emulator (Chrome) dan di iPad.
Ralf
Mengembalikan positif palsu untuk saya di Chrome.
James
2

Ini bekerja untuk saya:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
Turtletrail
sumber
1
berapa banyak platform, browser, OS ', perangkat yang telah Anda uji?
BerggreenDK
1
FF, Chrome, Safari di Android dan iOS (iPad)
Turtletrail
1
Cukup bagus Saya baru saja menguji pada desktop dan mendapat banyak "tidak terdefinisi" yang membuat struktur IF agak berantakan. Jika Anda hanya menyesuaikan sedikit nilai pengembalian Anda, seperti ini: return true == ("ontouchstart" di jendela || window.DocumentTouch && instance dokumen DocumentTouch); Maka Anda memiliki benar atau salah :-)
BerggreenDK
2
Di Chrome, "ontouchstart" di jendela benar pada PC saya tanpa layar sentuh, jadi ini tidak berfungsi. Seperti yang dikomentari sebelumnya, ini menguji apakah browser itu mampu sentuh. Juga, true == tidak melakukan apa-apa dan harus dihilangkan.
rakensi
1
Ketika saya mencoba ini di Chrome dengan emulator bawaan, ia akan mendeteksi sentuhan ketika diaktifkan di emulator, dan tidak akan mendeteksi sentuhan ketika dimatikan. Jadi bekerja dengan baik untuk saya. Tetapi: Saya menggunakan versi pendek oleh Prasad (di bawah) yang tidak menggunakan || dalam kode Turtletrail. Dan: Saya tidak peduli jika itu berfungsi untuk 100% perangkat. 99% akan membantu saya.
Ralf
1

Jika Anda menggunakan Modernizr , sangat mudah digunakan Modernizr.touchseperti yang disebutkan sebelumnya.

Namun, saya lebih suka menggunakan kombinasi Modernizr.touchdan pengujian agen pengguna, hanya 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));

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

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

Perhatikan juga bahwa pengujian agen pengguna iemobileakan memberi Anda jangkauan yang lebih luas dari perangkat seluler Microsoft yang terdeteksi Windows Phone.

Lihat juga pertanyaan SO ini

Peter Pan
sumber
2
Apakah respons yang sama untuk 4 pertanyaan sekarang ... dan ini bukan solusi untuk pertanyaan yang diajukannya.
jycr753
1
Saya yakin itu menjawab pertanyaan di sini
Peter-Pan
itu bukan jawaban tetapi itu adalah petunjuk saya pikir untuk siapa yang ingin mendeteksi apakah perangkat dapat disentuh sebelum pengguna menyentuhnya
Shahadat Hossain Khan
1

Di jQuery Mobile, Anda cukup melakukan:

$.support.touch

Tidak tahu mengapa ini sangat tidak berdokumen .. tetapi crossbrowser aman (2 versi terbaru dari browser saat ini).

OZZIE
sumber
0

Seperti yang telah disebutkan, perangkat dapat mendukung input mouse dan sentuh. Sangat sering, pertanyaannya bukan "apa yang didukung" tetapi "apa yang saat ini digunakan".

Untuk kasus ini, Anda cukup mendaftarkan acara mouse (termasuk pendengar melayang) dan menyentuh acara yang sama.

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

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

...

JavaScript harus secara otomatis memanggil pendengar yang benar berdasarkan input pengguna. Jadi, dalam hal acara sentuhan,onTouchStartCallback akan dipecat, meniru kode hover Anda.

Perhatikan bahwa sentuhan dapat memunculkan kedua jenis pendengar, sentuhan dan mouse. Namun, pendengar sentuh masuk terlebih dahulu dan dapat mencegah pendengar mouse berikutnya menembak dengan memanggil event.preventDefault().

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

Bacaan lebih lanjut di sini .

pengguna3792852
sumber
-3

Untuk pengembangan iPad saya menggunakan:

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

Saya kemudian dapat secara selektif mengikat acara berbasis sentuhan (misalnya ontouchstart) atau acara berbasis mouse (misalnya onmousedown). Saya belum diuji di Android.

Halton
sumber
1
Ini tidak berfungsi dengan Opera Mobile 10 atau Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ
4
bad crossbrowser / cross OS / cross platform advice.
BerggreenDK