Truy vấn phương tiện để phát hiện xem thiết bị có phải là màn hình cảm ứng hay không


122

Cách an toàn nhất, sử dụng truy vấn phương tiện, để thực hiện điều gì đó xảy ra khi không sử dụng thiết bị màn hình cảm ứng? Nếu không có cách nào, bạn có đề xuất sử dụng giải pháp JavaScript như !window.TouchModernizr không?


2
Nhanh chóng chuyển tiếp đến năm 2018, CSS tại là natively thể làm điều này stackoverflow.com/a/50285058/1717735
Buzut

Câu trả lời:


37

Tôi sẽ đề xuất sử dụng modernizr và sử dụng các tính năng truy vấn phương tiện của nó.

if (Modernizr.touch){
   // bind to touchstart, touchmove, etc and watch `event.streamId`
} else {
   // bind to normal click, mousemove, etc
}

Tuy nhiên, bằng cách sử dụng CSS, có những lớp giả như trong Firefox. Bạn có thể sử dụng : -moz-system-metric (kích hoạt cảm ứng) . Nhưng những tính năng này không có sẵn cho mọi trình duyệt.

Đối với các thiết bị của Apple , bạn có thể sử dụng đơn giản:

if(window.TouchEvent) {
   //.....
}

Đặc biệt đối với Ipad:

if(window.Touch) {
    //....
}

Tuy nhiên, những điều này không hoạt động trên Android .

Modernizr cung cấp khả năng phát hiện tính năng và phát hiện tính năng là một cách tốt để viết mã, thay vì mã hóa dựa trên trình duyệt.

Các yếu tố cảm ứng tạo kiểu

Modernizer thêm các lớp vào thẻ HTML cho mục đích chính xác này. Trong trường hợp này, touchno-touchdo đó, bạn có thể tạo kiểu cảm ứng khía cạnh liên quan của bạn bằng cách đặt trước selectors của bạn với .touch. vd .touch .your-container. Tín dụng: Ben Swinburne


Tôi có đúng khi nghĩ rằng không có lớp psedo nào hoạt động với tất cả các thiết bị / trình duyệt hiện đại không?
JJJollyjim

@ JJ56, Không phải mọi trình duyệt đều hỗ trợ các lớp giả cảm ứng. Nhưng đó là nơi modernizrsẽ được hoàn hảo :)
Starx

18
Các Modernizr.touchthử nghiệm chỉ cho biết nếu sự hỗ trợ trình duyệt chạm sự kiện, mà không nhất thiết phản ánh một thiết bị màn hình cảm ứng. Ví dụ, điện thoại Palm Pre / WebOS (cảm ứng) không hỗ trợ các sự kiện cảm ứng và do đó đã trượt thử nghiệm này.
numediaweb 14/02/13

5
Chỉ để thêm vào điều này, nếu bạn vẫn bao gồm trình hiện đại hóa; Modernizer thêm các lớp vào thẻ body cho mục đích chính xác này. Trong trường hợp này, touchno-touchdo đó bạn có thể tạo kiểu cho các khía cạnh liên quan đến cảm ứng của mình bằng cách thêm tiền tố vào bộ chọn của bạn .touch. Ví dụ.touch .your-container
Ben Swinburne

2
Đối với tôi, có vẻ như modernizr thêm lớp cảm ứng vào thẻ html, không phải thẻ body.
Robin Cox

162

Thực sự có một thuộc tính cho điều này trong bản nháp truy vấn phương tiện CSS4 .

Tính năng phương tiện 'con trỏ' được sử dụng để truy vấn về sự hiện diện và độ chính xác của thiết bị trỏ chẳng hạn như chuột. Nếu một thiết bị có nhiều cơ chế đầu vào, UA nên báo cáo các đặc điểm của thiết bị trỏ kém khả năng nhất trong số các cơ chế đầu vào chính. Truy vấn phương tiện này nhận các giá trị sau:

'none'
- Cơ chế đầu vào của thiết bị không bao gồm thiết bị trỏ.

'thô'
- Cơ chế đầu vào của thiết bị bao gồm một thiết bị trỏ có độ chính xác hạn chế.

'fine'
- Cơ chế đầu vào của thiết bị bao gồm một thiết bị trỏ chính xác.

Điều này sẽ được sử dụng như vậy:

/* Make radio buttons and check boxes larger if we have an inaccurate pointing device */
@media (pointer:coarse) {
    input[type="checkbox"], input[type="radio"] {
        min-width:30px;
        min-height:40px;
        background:transparent;
    }
}

Tôi cũng đã tìm thấy một vé trong dự án Chromium liên quan đến điều này.

Khả năng tương thích của trình duyệt có thể được kiểm tra tại Quirksmode . Đây là kết quả của tôi (22 tháng 1 năm 2013):

  • Chrome / Win: Hoạt động
  • Chrome / iOS: Không hoạt động
  • Safari / iOS6: Không hoạt động

3
Làm thế nào đây có thể là câu trả lời có nhiều điểm nhất khi giải pháp được cung cấp không hoạt động ngay cả theo áp phích?
erdomester

5
Hỗ trợ trình duyệt cho điều này không còn tệ nữa: Edge, Chrome, Safari, iOS và Android. Xem: caniuse.com/#feat=css-media-interaction
Josa


Làm việc cho tôi;) Cảm ơn vì nghiên cứu này!
Verri

52

Các giải pháp CSS dường như không được cung cấp rộng rãi vào giữa năm 2013. Thay thế...

  1. Nicholas Zakas giải thích rằng Modernizr áp dụng một no-touchlớp CSS khi trình duyệt không hỗ trợ cảm ứng.

  2. Hoặc phát hiện trong JavaScript bằng một đoạn mã đơn giản, cho phép bạn triển khai giải pháp giống Modernizr của riêng mình:

    <script>
        document.documentElement.className += 
        (("ontouchstart" in document.documentElement) ? ' touch' : ' no-touch');
    </script>

    Sau đó, bạn có thể viết CSS của mình dưới dạng:

    .no-touch .myClass {
        ...
    }
    .touch .myClass {
        ...
    }

Cái thứ hai là rất tốt đẹp. Hoạt động một sự quyến rũ cho tôi! Cảm ơn.
Garavani

@ bjb568 Cảm ơn bạn đã đề xuất chỉnh sửa, đây là một giải pháp thay thế hiện đại hơn, nhưng vì nó chỉ hoạt động trong IE 10 trở lên, nên tôi nghĩ tốt nhất là nên giữ phiên bản này trong thời gian này.
Simon East,

Có vẻ như lớp đó sẽ nằm trên thẻ html; điều đó có nghĩa là nó bị tắt theo mặc định khi sử dụng CSP.
Leo

35

Các loại phương tiện không cho phép bạn phát hiện các khả năng cảm ứng như một phần của tiêu chuẩn:

http://www.w3.org/TR/css3-mediaqueries/

Vì vậy, không có cách nào để làm điều đó một cách nhất quán thông qua CSS hoặc truy vấn phương tiện, bạn sẽ phải sử dụng đến JavaScript.

Không cần sử dụng Modernizr, bạn chỉ có thể sử dụng JavaScript đơn giản:

<script type="text/javascript">
    var is_touch_device = 'ontouchstart' in document.documentElement;
    if(is_touch_device) alert("touch is enabled!");
</script>

AFAIK, window.touch&& window.TouchEventchỉ hoạt động với các thiết bị apple.
Starx

22
@vsync Modernizr là một cách tuyệt vời để đặt tất cả các bài kiểm tra hữu ích cho các nhà phát triển trong một thư viện phù hợp, để họ không cần phải sử dụng Google mỗi khi họ cần kiểm tra một tính năng cụ thể, chẳng hạn như sự kiện chạm và phải tìm trang này. FYI có một bản dựng Modernizr tùy chỉnh mà bạn có thể tùy chỉnh với các thử nghiệm bạn muốn. Đó là một cách tuyệt vời để kiểm tra các tính năng luôn giống nhau giữa các dự án, bạn sử dụng cú pháp JS (tức là: Modernizr.touch) hoặc các lớp CSS (.touch .my-element {}). Tôi nghĩ rằng đó là một sự xúc phạm đối với trí thông minh của con người khi không nhận ra rằng chúng ta có thể làm mọi thứ mà không cần phải phát minh lại bánh xe mỗi lần.
Alejandro García Iglesias

11
Chà, tôi đã làm việc trên hàng trăm dự án và tôi chưa bao giờ cần một thứ như vậy, trong hầu hết trường hợp, tất cả những gì bạn cần là một bộ thử nghiệm rất nhỏ, tôi sẽ nói không bao giờ nhiều hơn 5 (trong hầu hết các trường hợp), vì vậy chỉ cần tìm 5 cái đó và đặt chúng vào mã của bạn trực tiếp, không cần phải thực sự truy cập trang web Modernizer, tạo một bản dựng tùy chỉnh, đưa nó vào trang của bạn hoặc bất cứ điều gì. Các nhà phát triển không nên lười biếng. Một nhà phát triển web nên luôn có suy nghĩ "làm thế nào để làm cho mã nhẹ hơn?" .. IMHO và nhiều năm kinh nghiệm. các nhà phát triển hiện nay dường như tình yêu bao gồm cả tấn kịch bản: /
vsync

2
Một số nói rằng lười biếng. Tôi nói tại sao lại phát minh ra bánh xe? Còn khi một thiết bị / phiên bản / nền tảng mới xuất hiện và trường hợp đặc biệt của bạn cần thay đổi? Bạn có a) Cố gắng tự mình tìm ra mã phát hiện trường hợp đặc biệt và báo cáo lại mã tùy chỉnh của bạn, tự sơn lại mã trong quá trình này, hoặc b) tải xuống phiên bản Modernizr mới hơn và thả nó vào? Tôi biết tôi phải làm gì. +1 cho GarciaWebDev.
Sc0ttyD

@ Sc0ttyD Sở thích cá nhân của tôi là học cách viết mã mọi thứ ban đầu mà không phụ thuộc vào các thư viện như Modernizr. Một ngày nào đó, bạn có thể cần phải là người viết mã cho thiết bị mới và bạn không muốn bị mắc kẹt vì bạn không thể làm điều đó nếu không có thư viện. Chưa kể, có lẽ rất nhiều người không có thời gian làm việc để tìm hiểu một thư viện mới.
Alex W

28

Vào năm 2017, truy vấn phương tiện CSS từ câu trả lời thứ hai vẫn không hoạt động trên Firefox. Tôi đã tìm thấy một giải pháp cho điều đó: -moz-touch-enable


Vì vậy, đây là truy vấn phương tiện đa trình duyệt:

@media (-moz-touch-enabled: 1), (pointer:coarse) {
    .something {
        its: working;
    }
}

điều này sẽ cao hơn và câu trả lời được chấp thuận. firefox đang nghiên cứu triển khai spec, vì vậy -moz-touch-enabledsẽ không phải sớm
Dogoku


@ user3445853 OP hỏi cách phát hiện (thông qua truy vấn phương tiện) thiết bị có màn hình cảm ứng. Nếu quy tắc "(pointer: none)" là đúng, thì chắc chắn thiết bị không có màn hình cảm ứng. Nhưng ai đó nên xác nhận quan điểm của tôi (hoặc không) :)
Sokolow

-moz-touch-enabledđược cho là không được hỗ trợ trong Firefox 58+. Như trong, giải pháp này không áp dụng cho Firefox 58-63 (vì Firefox 64+ hỗ trợ truy vấn con trỏ). Nguồn: developer.mozilla.org/en-US/docs/Web/CSS/@media/…
fgblomqvist 23/04/19

24

Thực sự có một truy vấn phương tiện cho điều đó:

@media (hover: none) {  }

Ngoài Firefox, nó được hỗ trợ khá tốt . Safari và Chrome là những trình duyệt phổ biến nhất trên thiết bị di động, nó có thể đủ cho đến khi được áp dụng nhiều hơn.


2
... và hỗ trợ sắp tới cho FF nữa.
retrovertigo

5

Điều này sẽ hoạt động. Nếu nó không cho tôi biết

@media (hover: none) and (pointer: coarse) {
    /* Touch screen device style goes here */
}

chỉnh sửa: di chuột theo yêu cầu không được hỗ trợ nữa


3

Giải pháp này sẽ hoạt động cho đến khi CSS4 được hỗ trợ trên toàn cầu bởi tất cả các trình duyệt. Khi ngày đó đến, chỉ cần sử dụng CSS4. nhưng cho đến lúc đó, điều này hoạt động cho các trình duyệt hiện tại.

browser-use.js

export const isMobile = {
  android: () => navigator.userAgent.match(/Android/i),
  blackberry: () => navigator.userAgent.match(/BlackBerry/i),
  ios: () => navigator.userAgent.match(/iPhone|iPad|iPod/i),
  opera: () => navigator.userAgent.match(/Opera Mini/i),
  windows: () => navigator.userAgent.match(/IEMobile/i),
  any: () => (isMobile.android() || isMobile.blackberry() || 
  isMobile.ios() || isMobile.opera() || isMobile.windows())
};

đang tải:

cách cũ:

isMobile.any() ? document.getElementsByTagName("body")[0].className += 'is-touch' : null;

cách mới hơn:

isMobile.any() ? document.body.classList.add('is-touch') : null;

Đoạn mã trên sẽ thêm lớp "is-touch" vào thẻ body nếu thiết bị có màn hình cảm ứng. Bây giờ, bất kỳ vị trí nào trong ứng dụng web của bạn mà bạn sẽ có css cho: di chuột, bạn có thể gọibody:not(.is-touch) the_rest_of_my_css:hover

ví dụ:

button:hover

trở thành:

body:not(.is-touch) button:hover

Giải pháp này tránh sử dụng trình hiện đại hóa vì lib hiện đại hóa là một thư viện rất lớn. Nếu tất cả những gì bạn đang cố gắng làm là phát hiện màn hình cảm ứng, Điều này sẽ tốt nhất khi kích thước của nguồn được biên dịch cuối cùng là một yêu cầu.


0

thêm màn hình cảm ứng lớp vào phần thân bằng JS hoặc jQuery

  //allowing mobile only css
    var isMobile = ('ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/));
    if(isMobile){
        jQuery("body").attr("class",'touchscreen');
    }

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.