Медіа-запит, щоб визначити, чи пристрій є сенсорним екраном


122

Який найбезпечніший спосіб зробити медіа-запити, щоб щось сталося, коли не на пристрої з сенсорним екраном? Якщо немає можливості, чи пропонуєте ви використовувати таке рішення JavaScript, як !window.TouchModernizr?


2
Перенесемося в 2018 році, CSS тепер спочатку в стані зробити це stackoverflow.com/a/50285058/1717735
Buzut

Відповіді:


37

Я б запропонував використовувати modernizr та використовувати його функції медіа-запитів.

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

Однак, використовуючи CSS, існують такі псевдокласи, як, наприклад, у Firefox. Ви можете використовувати : -moz-system-metric (сенсорний ввімкнено) . Але ці функції доступні не для кожного браузера.

Для пристроїв Apple можна просто користуватися:

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

Спеціально для Ipad:

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

Але це не працює на Android .

Modernizr надає можливості виявлення функцій, а виявлення функцій - це хороший спосіб кодування, а не кодування на основі браузерів.

Стилізаційні елементи дотику

Модернізатор додає класи до тегу HTML саме для цієї мети. В цьому випадку, touchі no-touchтому ви можете стилізувати ваші дотики аспектів , пов'язаних випереджаючи ваші селектори з .touch. напр .touch .your-container. Кредити: Бен Свінберн


Я маю рацію, думаючи, що жоден клас пседо не працює з усіма сучасними пристроями / браузерами?
JJJollyjim

@ JJ56, Так, не кожен браузер підтримує псевдокласи. Але саме тут modernizrбуде ідеально :)
Starx

18
Modernizr.touchТест показує тільки якщо підтримує браузер помацати події, які не обов'язково відображають сенсорний екран пристрою. Наприклад, телефони Palm Pre / WebOS (touch) не підтримують сенсорні події і тому проходять цей тест.
numediaweb

5
Просто додати до цього, якщо ви все одно включаєте модернізатор; Для цієї мети Modernizer додає класи до тегу body. В цьому випадку, touchі no-touchтому ви можете стилізувати ваш сенсорні аспекти , пов'язані з випереджаючи ваші селектори з .touch. Напр..touch .your-container
Бен Свінберн

2
Мені здається, що модернізатор додає сенсорний клас до тегу html, а не тега body.
Робін Кокс

162

Насправді це властивість для цього в чернетку запитів медіа-запитів CSS4 .

Функція медіа-вказівника використовується для запиту про наявність та точність вказівного пристрою, такого як миша. Якщо пристрій має кілька механізмів введення, рекомендується UA повідомляти про характеристики найменш здатного вказівного пристрою первинних механізмів введення. Цей медіа-запит приймає такі значення:

'none'
- механізм введення пристрою не включає вказівний пристрій.

'груба'
- Механізм введення пристрою включає вказівний пристрій обмеженої точності.

'штраф'
- механізм введення пристрою включає в себе точний вказівний пристрій.

Це буде використано як таке:

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

Я також знайшов квиток у проекті Chromium, пов’язаний із цим.

Сумісність веб-переглядача можна перевірити на Quirksmode . Це мої результати (22 січня 2013 р.):

  • Chrome / Win: працює
  • Chrome / iOS: не працює
  • Safari / iOS6: не працює

3
Як це може бути відповіддю з найбільшою кількістю пунктів, коли запропоноване рішення не працює навіть згідно з афішею?
erdomester

5
Підтримка браузера для цього вже не така вже й погана: Edge, Chrome, Safari, iOS та Android. Дивіться: caniuse.com/#feat=css-media-interaction
Йоса

3
Хороша відповідь. Додатково: developer.mozilla.org/en-US/docs/Web/CSS/@media/hover
1717

Для мене працює;) Дякую за дослідження цього!
Веррі

52

Здається, рішення CSS не є широко доступними з середини 2013 року. Натомість ...

  1. Ніколас Закас пояснює, що Modernizr застосовує no-touchклас CSS, коли браузер не підтримує дотик.

  2. Або виявляйте в JavaScript за допомогою простого фрагмента коду, що дозволяє реалізувати власне рішення, схоже на Modernizr:

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

    Тоді ви можете написати свій CSS так:

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

Другий дуже приємний. Діє принадність для мене! Дякую.
Гаравани

@ bjb568 Дякую за запропоновану редакцію, яка є більш сучасною альтернативою, але оскільки вона працює лише в IE 10 і вище, я думаю, що найкраще зберегти цю версію на даний момент.
Саймон Схід

Здається, що цей клас був би в тезі html; що тоді означатиме, що він за замовчуванням відключений при використанні CSP.
Лев

35

Типи медіа не дозволяють виявляти сенсорні можливості як частину стандарту:

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

Отже, немає можливості це робити послідовно за допомогою CSS або медіа-запитів, доведеться вдаватися до JavaScript.

Не потрібно використовувати Modernizr, ви можете просто використовувати звичайний JavaScript:

<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.TouchEventпрацюють лише для яблучних пристроїв.
Starx

22
@vsync Modernizr - це чудовий спосіб помістити всі тести, корисні для розробників, у збережену бібліотеку, щоб вони не мали Google кожного разу, коли їм потрібно тестувати певну функцію, як-от сенсорні події та пошук цієї сторінки. FYI є спеціальна побудова Modernizr, яку ви можете налаштувати за допомогою потрібних тестів. Це чудовий спосіб тестування функцій завжди однаково між проектами, або ви використовуєте синтаксис JS (тобто: Modernizr.touch) або класи CSS (.touch .my-element {}). Я думаю, що це образа людського інтелекту, що не визнає, що ми можемо робити речі, не вигадуючи колесо кожен раз.
Алехандро Гарсія Іглесіас

11
Ну, я працював над сотнями проектів, і мені ніколи не потрібна була така річ, у більшості випадків все, що вам потрібно, - це дуже невеликий набір тестів, ніколи більше 5 я б сказав (у більшості випадків), тому просто знайдіть ці 5 і введіть їх у свій код безпосередньо, не потрібно насправді переходити на веб-сайт Modernizer, робити власну збірку, включати її на свою сторінку чи будь-що інше. Розробники не повинні ЛЮБИТИ. Веб-розробник повинен завжди мати розум про те, "як я можу зробити код легшим?" .. ІМХО та багаторічний досвід.
Зараз,

2
Деякі кажуть ледачий. Я кажу, навіщо винаходити колесо? А як бути, коли з’являється новий пристрій / версія / платформа, і ваш особливий корпус потребує змін? Ви a) Спроба самостійно опрацювати спеціальний код виявлення випадків та підкріпити його власним кодом, повторно познайомившись із ним у процесі, або б) завантажити новітню версію Modernizr та залишити її? Я знаю, що б я зробив. +1 до GarciaWebDev.
Sc0ttyD

@ Sc0ttyD Мої особисті переваги - навчитися кодувати речі спочатку, не залежно від бібліотек, таких як Modernizr. Колись вам може знадобитися бути тим, хто кодує новий пристрій, і ви не хочете застрявати, тому що ви не можете зробити це без бібліотеки. Не кажучи вже про те, що, мабуть, багато людей, які просто не мають часу на своїй роботі, щоб вивчити нову бібліотеку.
Alex W

28

У 2017 році запит на медіа CSS з другої відповіді все ще не працює на Firefox. Я знайшов для цього солютон : -moz-touch-enable


Отже, ось медіа-запит між браузерами:

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

це має бути вище і схвалена відповідь. firefox працює над впровадженням специфікації, тому -moz-touch-enabledне буде потрібно незабаром
Dogoku


@ user3445853 OP запитує, як виявити (за допомогою медіа-запиту) пристрій за допомогою сенсорного екрана. Якщо правило "(pointer: none)" буде істинним, то на пристрої точно не буде сенсорного екрана. Але хтось повинен підтвердити мою думку (чи ні) :)
Sokołow

-moz-touch-enabledнібито не підтримується у Firefox 58+. Як і в даному рішенні, це рішення не охоплює Firefox 58-63 (оскільки Firefox 64+ підтримує запит вказівника). Джерело: developer.mozilla.org/en-US/docs/Web/CSS/@media/…
fgblomqvist

24

Насправді існує медіа-запит щодо цього:

@media (hover: none) {  }

Крім Firefox, він досить добре підтримується . Сафарі та Chrome, що є найпоширенішими браузерами на мобільних пристроях, може бути достатньою для швидшого використання.


2
... і підтримка, яка з’являється в наступні тижні і для ФФ.
ретровертиго

5

Це спрацює. Якщо це не дає мені знати

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

редагувати: наведення на вимогу більше не підтримується


3

Це рішення працюватиме до тих пір, поки CSS4 не отримає глобальну підтримку всіх браузерів. Коли настає цей день, просто використовуйте CSS4. але до цього часу це працює для поточних браузерів.

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

onload:

старий спосіб:

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

новіший спосіб:

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

Вищевказаний код додасть клас "is-touch" до тега body, якщо пристрій має сенсорний екран. Тепер будь-яке місце у вашій веб-програмі, де ви мали б css для: наведіть курсор, ви можете зателефонуватиbody:not(.is-touch) the_rest_of_my_css:hover

наприклад:

button:hover

стає:

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

Це рішення дозволяє уникнути використання модернізатора, оскільки модернізатор lib - це дуже велика бібліотека. Якщо ви лише намагаєтесь виявити сенсорні екрани, це буде найкраще, коли розмір остаточного скомпільованого джерела є вимогою.


0

додавання сенсорного екрану класу до тіла за допомогою JS або jQuery

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.