Вимкнути ефекти наведення курсора на мобільних браузерах


113

Я пишу веб-сайт, призначений для використання як з настільних ПК, так і з планшетів. Коли його відвідують з робочого столу, я хочу, щоб місця, на які можна натиснути, загорілися :hoverефектами (різний колір тла тощо). На планшеті немає миші, тому я не хочу ніяких ефектів наведення.

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

Як я можу отримати ефекти наведення курсора під час використання миші, але придушити їх, коли я використовую сенсорний екран?

У випадку, якщо хтось думав запропонувати це, я не хочу використовувати нюхання користувачів-агентів. Один і той же пристрій може мати як сенсорний екран, так і мишу (можливо, це не так часто зустрічається сьогодні, але набагато більше в майбутньому). Мене не цікавить пристрій, мене цікавить, як він зараз використовується: миша або сенсорний екран.

Я вже намагався зачепити touchstart, touchmoveі touchendподія , і закликаючи preventDefault()на всіх з них, що робить пригнічує «невидимий курсор миші» деякий час; але якщо я швидко натискаю назад і назад між двома різними елементами, через кілька натискань він почне рухати "курсором миші" і все-таки запалювати ефекти наведення - це як моє preventDefaultне завжди шанується. Я не набридаю вам деталями, якщо не буде необхідності - я навіть не впевнений, що це правильний підхід; якщо хтось має більш просте виправлення, я все вуха.


Редагувати: це може бути відтворено за допомогою стандартного CSS-файлу :hover, але ось короткий довід для довідки

<style>
  .box { border: 1px solid black; width: 150px; height: 150px; }
  .box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>

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

Я також відправив зразок тут , що робить вище , а також перехоплює події миші JQuery в. Ви можете використовувати його для того, щоб побачити, що події крана також будуть відкриватися mouseenter, mousemoveі mouseleave.


7
@Blender, ти читав питання? Я вже пояснив, чому нюхати користувацькі агенти - це поганий вибір.
Джо Вайт

Гей Джо, ти знайшов для цього якесь рішення?
Ісматьон

Я шукав таке питання, радий, що знайшов його!
agpt

Дивіться також це запитання, яке стосується вимкнення наведення курсора на будь-які пристрої з дотиком, не лише мобільні: stackoverflow.com/questions/23885255/…
лезо

Відповіді:


83

Я розумію, що ваше запитання впливає на зміст вашої сторінки. У такому випадку моя порада:

  • Додайте ефекти наведення курсора на touchstartта mouseenter.
  • Видалити ширяння вплив на mouseleave, touchmoveі click.

Крім того, ви можете відредагувати свою сторінку, щоб не було змін змісту.

Фон

Щоб імітувати мишу, веб-переглядачі, такі як Webkit mobile, запускають наступні події, якщо користувач торкається та відпускає палець на сенсорний екран (наприклад, iPad) (джерело: Touch and Mouse на html5rocks.com):

  1. touchstart
  2. touchmove
  3. touchend
  4. 300 мс затримки, коли браузер переконується, що це один дотик, а не подвійний
  5. mouseover
  6. mouseenter
    • Примітка : Якщо mouseover, mouseenterабо mousemoveподія змінює зміст сторінки, такі події ніколи не звільняють.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

Здається, не можна просто сказати веб-браузеру пропустити події миші.

Що ще гірше, якщо подія наведення миші змінює вміст сторінки, подія натискання ніколи не запускається, як це пояснено в посібнику веб-вмісту Safari - Поводження з подіями , зокрема на рисунку 6.4 в Подіях одним пальцем . Що саме означає "зміна вмісту", залежатиме від браузера та версії. Я виявив, що для iOS 7.0 зміна кольору фону не є (або вже не?) Зміною вмісту.

Роз'яснення рішення

Для резюме:

  • Додайте ефекти наведення курсора на touchstartта mouseenter.
  • Видалити ширяння вплив на mouseleave, touchmoveі click.

Зауважте, що ніяких дій на це немає touchend!

Це, очевидно, працює для подій миші: mouseenterі mouseleave(трохи вдосконалені версії mouseoverта mouseout) запускаються, додавання та видалення наведення курсора.

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

Це також працює для сенсорних подій: при сенсорному запуску додається ефект наведення. Це "" не "" "видалено на дотик. Він додається знову mouseenter, і оскільки це не спричиняє змін вмісту (воно вже було додано), clickподія також запускається, а посилання виконується без потреби користувача знову натискати!

Затримка 300 мс, яку має браузер між touchstartподією таclick фактично використовується, тому що ефект покажчика буде показаний протягом цього короткого часу.

Якщо користувач вирішить скасувати натискання, переміщення пальця зробить це так само, як звичайно. Зазвичай це проблема, оскільки жодна mouseleaveподія не проводиться, а ефект наведення курсора залишається в силі. На щастя, це можна легко виправити, знявши ефект наведення touchmove.

Це воно!

Зауважте, що можна видалити затримку 300 мс, наприклад, використовуючи бібліотеку FastClick , але це не вдається для цього питання.

Альтернативні рішення

Я знайшов такі проблеми із наступними альтернативами:

  • Виявлення браузера: надзвичайно схильний до помилок. Передбачається, що пристрій має миша або сенсор, тоді як комбінація обох стане все більш поширеною, коли сенсорні дисплеї збільшуються.
  • Виявлення мультимедійних файлів CSS: Єдине відоме лише для CSS рішення Він все ще схильний до помилок і все ж припускає, що пристрій має або мишу, або сенсорне, хоча обидва можливі.
  • Емуляція події клацання в touchend: Це буде неправильно переходити за посиланням, навіть якщо користувач хотів лише прокручувати або масштабувати, не маючи наміру фактично натиснути на посилання.
  • Використовуйте змінну для придушення подій миші. Цей параметр встановлює змінну, touchendяка використовується як умова if у наступних подіях миші, щоб запобігти змінам стану в цей момент часу. Змінна скидається в події клацання. Дивіться відповідь Вальтера Романа на цій сторінці. Це гідне рішення, якщо ви дійсно не хочете ефекту наведення на сенсорні інтерфейси. На жаль, це не працює, якщо a запускається touchendз іншої причини і не запускається подія клацання (наприклад, користувач прокручує або збільшує масштаб), а згодом намагається перейти за посиланням мишею (тобто на пристрої з інтерфейсом миші та сенсорного інтерфейсу ).

Подальше читання


1
Гарна відповідь. Я використовував вашу загадку, щоб почати створювати власне рішення. Однак іноді потрібен дотик. (коли сенсорний рух не запускається - тобто, коли користувач
відхиляє

Чудова відповідь, але в більшості випадків я б рекомендував використовувати touchend замість цього, а не touchstartв більшості випадків, щоб уникнути ініціювання дії негайно, коли користувач намагається провести пальцем вгору або вниз по сторінці. Все ще відбудеться, але менше шансів відволікти чи заплутати (якщо припустити, що це щось нешкідливе, як показ етикетки, а не те, що потрібно знати користувачеві)
user56reinstatemonica8,

19

Як я можу отримати ефекти наведення курсора під час використання миші, але придушити їх, коли я використовую сенсорний екран?

Може, не думайте про це стільки, як придушення ефектів наведення для сенсорних екранів, а як додавання ефектів наведення для подій миші?

Якщо ви хочете зберегти :hoverефекти у своєму CSS, ви можете вказати різні стилі для різних медіа:

@media screen { /* hover styles here */ } 

@media handheld { /* non-hover styles here */ }

За винятком того, що, на жаль, є безліч мобільних пристроїв, які це ігнорують і просто використовують правила екрана. На щастя, багато новіших браузерів для мобільних пристроїв / планшетів підтримують деякі модні медіа-запити:

@media screen and (max-width:800px) { /* non-hover styles here */ }

Тож навіть якщо «екран» або «ручна» частина буде проігноровано, «максимальна ширина» зробить для вас хитрість. Можна просто припустити, що все, що має екран менше 800 пікселів, має бути планшетом чи телефоном, і не використовувати ефекти наведення курсору. Для рідкісних користувачів, які використовують мишу на пристрої низької роздільної здатності, вони не побачать ефектів наведення, але інакше ваш веб-сайт буде добре.

Подальше читання медіа-запитів? Статей про це в мережі є багато - ось одна: http://www.alistapart.com/articles/return-of-the-mobile-stylesheet

Якщо ви змістите ефекти наведення вказівника зі свого CSS і застосуєте їх за допомогою JavaScript, то ви можете прив’язати конкретно до подій миші та / або знову, ви можете просто зробити деякі припущення лише на основі розміру екрана, а найгірша "проблема" полягає в тому, що деякі Користувач, який користується мишкою, пропускає ефекти наведення курсора.


Я хотів би додати ефекти наведення курсору лише для подій миші. Але сенсорні події імітують події миші. Якщо я підключу дотикові події та дзвоню preventDefault(), це іноді пригнічує події миші, але, як я вже говорив у своєму запитанні, це не є надійним.
Джо Уайт

6
Що стосується медіа-запитів, що відбувається, коли виходить Windows 8 і на ПК є сенсорні екрани та миші? Якщо користувач наводить курсор миші, він побачить курсор миші, і я хочу, щоб ефекти наведення миші; якщо вони торкаються сенсорного екрану, я не хочу ефектів наведення. Але я не знайшов надійного способу виявити різницю між дотиком і мишкою.
Джо Уайт

Ну, можливо, розробники браузерів будуть більш вмотивовані зробити детектування більш послідовним, коли вони матимуть більшу кількість користувачів на пристроях із сенсорним та мишам. Але поки що? Я б робив здогадки залежно від розміру екрана, але в інших відповідях є інші поради. Вибачте, що не можу допомогти далі.
nnnnnn

9

Я написав наступний JS для недавнього проекту, який представляв собою настільний / мобільний / планшетний сайт, який має наведення ефектів, які не повинні з’являтися на дотик.

mobileNoHoverStateНижче модуль має змінну preventMouseover(спочатку оголошений в false), який встановлений на , trueколи користувач запускає touchstartподія на елемент, $target.

preventMouseoverпотім повертається до falseкожного разу, коли mouseoverподія запускається, що дозволяє сайту працювати за призначенням, якщо користувач використовує як сенсорний екран, так і мишу.

Ми знаємо, що mouseoverце спрацьовує після touchstartтого, як вони були оголошені в порядку init.

var mobileNoHoverState = function() {

    var hoverClass = 'hover',
        $target = $(".foo"), 
        preventMouseover = false;

    function forTouchstart() {
        preventMouseover = true;
    }

    function forMouseover() {
        if (preventMouseover === false) {
            $(this).addClass(hoverClass);
        } else {
            preventMouseover = false;
        }
    }

    function forMouseout() {
        $(this).removeClass(hoverClass);
    }

    function init() {
        $target.on({
            touchstart  : forTouchstart,
            mouseover   : forMouseover,
            mouseout    : forMouseout
        });                
    }

    return {
        init: init
    };
}();

Потім модуль інстанціюється далі вниз по лінії:

mobileNoHoverState.init();

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

@Redtopia Дякую за голову! Я оновив відповідь бітом коду, який у мене залишився.
Уолтер Роман

Вам не потрібні крапки з комою після декларації функції
nacholibre

@nacholibre Введено належне використання напівколонки
Вальтер Роман

6

Мені дуже хотілося чистого cssвирішення цього питання, оскільки розповсюдження вагомого рішення JavaScript навколо моїх поглядів здавалося неприємним варіантом. Нарешті знайдений запит @ media.hover , який може виявити "чи дозволяє основний механізм введення користувачеві навести курсор на елементи". Це дозволяє уникнути дотикових пристроїв, де "нависання" - це скоріше емуляція дії, ніж пряма можливість пристрою введення.

Наприклад, якщо у мене є посилання:

<a href="/" class="link">Home</a>

Тоді я можу сміливо стилювати його лише :hoverтоді, коли пристрій легко підтримує це css:

@media (hover: hover) {
  .link:hover { /* hover styles */ }
}

У той час як більшість сучасних браузерів підтримують запити про взаємодію із засобами взаємодії, деякі популярні браузери, такі як IE та Firefox , не мають. У моєму випадку це працює чудово, оскільки я мав намір підтримувати Chrome на робочому столі та Chrome та Safari на мобільному пристрої.


Приємне рішення, яке, здається, працює під час емуляції пристроїв у розробниках Chrome. Але це все ще не працює для Chrome Android :-(
Sjeiti

Я думаю, що це найбільш зручне і правильне рішення. Сподіваємось, незабаром він буде доданий до стандартів W3C.
GProst

5

Моє рішення полягає в тому, щоб додати тег HTML до hover-активного класу css і використовувати його на початку всіх селекторів CSS за допомогою: наведіть і видаліть цей клас у першій події сенсорного початку.

http://codepen.io/Bnaya/pen/EoJlb

JS:

(function () {
    'use strict';

    if (!('addEventListener' in window)) {
        return;
    }

    var htmlElement = document.querySelector('html');

    function touchStart () {
        document.querySelector('html').classList.remove('hover-active');

        htmlElement.removeEventListener('touchstart', touchStart);
    }

    htmlElement.addEventListener('touchstart', touchStart);
}());

HTML:

<html class="hover-active">

CSS:

.hover-active .mybutton:hover {
    box-shadow: 1px 1px 1px #000;
}

Замість того, щоб слухати сенсорну подію, ви можете протестувати 'ontouchstart' in window. наприкладif ('ontouchstart' in window) document.querySelector('html').classList.remove('hover-active');
Ювал А.

@YuvalA. Причиною, що я чекаю сенсорного події, є те, що є пристрої з підтримкою вказівника та сенсорного зв’язку, а користувач використовує вказівник, я не хочу видаляти наведення. Можливо, користувач використовуватиме сенсорний, а потім вказівний, але мені з цим нічого не робити
Bnaya

2

Що я зробив, щоб вирішити ту саму проблему, - це виявлення функції (я використовую щось на кшталт цього коду ), бачу, чи визначено onTouchMove, і якщо так, я додаю в тіло клас css "touchMode", інакше я додаю " desktopMode ".

Тоді кожен раз, коли якийсь ефект стилю застосовується лише до сенсорного пристрою або лише до робочого столу, правило css готується до відповідного класу:

.desktopMode .someClass:hover{ color: red }
.touchMode .mainDiv { width: 100%; margin: 0; /*etc.*/ }

Редагувати : Ця стратегія звичайно додає кілька додаткових символів у ваш css, тому якщо вас турбує розмір css, ви можете шукати дефінітони touchMode та desktopMode і розміщувати їх у різних файлах, щоб ви могли обслуговувати оптимізований css для кожного пристрою тип; або ви можете змінити назви класів на щось набагато коротше, перш ніж перейти до прод.


2

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

Мені в основному довелося взяти величезний додаток, який хтось зробив, і зробити його чуйним. Вони використовували jQueryUI і попросили мене не підробляти жоден їхній jQuery, тому я обмежився лише використанням CSS.

Коли я натиснув одну з їхніх кнопок у режимі сенсорного екрану, ефект наведення ввімкнув би секунду, перш ніж дія кнопки набула чинності. Ось як я це виправив.

@media only screen and (max-width:1024px) {

       #buttonOne{
            height: 44px;
        }


        #buttonOne:hover{
            display:none;
        }
}   

2

У моєму проекті ми вирішили цю проблему за допомогою https://www.npmjs.com/package/postcss-hover-prefix та https://modernizr.com/ Спочатку ми після обробки обробляємо файли CSS postcss-hover-prefix. Він додає .no-touchдо всіх hoverправил css .

const fs = require("fs");
const postcss = require("postcss");
const hoverPrfx = require("postcss-hover-prefix");

var css = fs.readFileSync(cssFileName, "utf8").toString();
postcss()
   .use(hoverPrfx("no-touch"))
   .process(css)
   .then((result) => {
      fs.writeFileSync(cssFileName, result);
   });

css

a.text-primary:hover {
  color: #62686d;
}

стає

.no-touch a.text-primary:hover {
  color: #62686d;
}

Під час виконання програми Modernizrавтоматично додає класи css до htmlтаких тегів

<html class="wpfe-full-height js flexbox flexboxlegacy canvas canvastext webgl 
  no-touch 
  geolocation postmessage websqldatabase indexeddb hashchange
  history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage
  borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients
  cssreflections csstransforms csstransforms3d csstransitions fontface
  generatedcontent video audio localstorage sessionstorage webworkers
  applicationcache svg inlinesvg smil svgclippaths websocketsbinary">

Така післяобробка css плюс Modernizr відключає наведення курсора на сенсорні пристрої та дає можливість іншим. Насправді такий підхід надихнув Bootstrap 4, як вони вирішують ту саму проблему: https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#sticky-hoverfocus-on-mobile


1

Ви можете викликати mouseLeaveподію, коли ви торкаєтесь елемента на сенсорному екрані. Ось рішення для всіх <a>тегів:

function removeHover() {
    var anchors = document.getElementsByTagName('a');
    for(i=0; i<anchors.length; i++) {
        anchors[i].addEventListener('touchstart', function(e){
            $('a').mouseleave();
        }, false);
    }
}

JSHint каже: "не робити функцій в циклі".
NetOperator Wibby

Це злом. НЕ є кодом для багаторазового використання, який можна вважати хорошою практикою. @NetOperatorWibby
Саїд Холов

Ну, не дуже корисно розміщувати код, який не можна вважати хорошою практикою. Це як надягати стрілецьку ножу на рану ножем.
Веб-мережа NetOperator

1

Я знайшов два рішення проблеми, з яких випливало, що ви виявите дотик з модернізатором чи чимось іншим і встановите сенсорний клас на html-елемент.

Це добре, але не підтримується дуже добре:

html.touch *:hover {
    all:unset!important;
}

Але це дуже гарна підтримка :

html.touch *:hover {
    pointer-events: none !important;
}

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

Виявляючи дотик із пристроїв без дотику, я думаю, що модернізатор зробив найкращу роботу:

https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js

EDIT

Я знайшов краще і простіше рішення цього питання

Як визначити, чи є клієнт сенсорним пристроєм


0

Це може допомогти побачити ваш CSS, оскільки це звучить як досить дивна проблема. Але в будь-якому випадку, якщо це відбувається, а все інше добре, ви можете спробувати перенести ефект наведення на javascript (ви також можете використовувати jquery). Просто прив’яжіть до події миші або ще краще події миші та запаліть елемент, коли подія запускається.

Отримайте останній приклад тут: http://api.jquery.com/mouseover/ , ви можете використати щось подібне для входу в систему, коли подія запускається, і взяти її звідти!


Нічого особливого щодо CSS; дивись мою редакцію. І я вже пробував mouseenter; без кісток. Натискання переміщує "невидимий курсор миші", тому він спрацьовує mouseenterі mousemovemouseleaveколи ви натискаєте десь ще).
Джо Уайт

0

Якщо ви раді використовувати JavaScript, ви можете використовувати Modernizr на своїй сторінці. Коли сторінка завантажується, у веб-переглядачі без сенсорного екрана буде доданий клас ".no-touch" до тегу html, але для браузера з сенсорним екраном тег html додасть клас ".ouch" до тегу html .

Тоді це просто випадок перевірити, чи має тег html клас без дотику, перш ніж вирішити додати ваші миші та слухачі миші.

if($('html').hasClass('no-touch')){
    $('.box').on("mouseenter", function(event){
            $(this).css('background-color','#0000ff')
    });
    $('.box').on("mouseleave", function(event){
            $(this).css('background-color','')
    });
}

На пристрої з сенсорним екраном події не матимуть слухачів, тому під час натискання ви не отримаєте ефекту наведення.


Коли це можна зробити за допомогою css, не використовуйте javascript (jquery), це марно витрачайте комп'ютерну потужність
Simon Dragsbæk

1
Простіше, але у своєму CSS ви можете визначити окремі правила для .touchта .no-touch. Щоб переписати свою відповідь у CSS разом із Modernizer, html.no-touch .box:hover {background-color: "#0000ff"}не визначаючи нічого дляhtml.touch .box:hover слід зробити фокус, оскільки ОП намагається лише уникнути мобільних пристроїв :hover.
Вальтер Роман

0

У проекті, який я нещодавно робив, я вирішив цю проблему за допомогою функції делегованих подій jQuery. Він шукає певні елементи за допомогою селектора jQuery і додає / видаляє клас CSS до цих елементів, коли миша перебуває над елементом. Здається, він працює добре, наскільки мені вдалося протестувати його, що включає IE10 на ноутбуці, що працює на дотиках під керуванням Windows 8.

$(document).ready(
    function()
    {
        // insert your own selector here: maybe '.hoverable'?
        var selector = 'button, .hotspot';

        $('body')
            .on('mouseover', selector, function(){ $(this).addClass('mouseover');    })
            .on('mouseout',  selector, function(){ $(this).removeClass('mouseover'); })
            .on('click',     selector, function(){ $(this).removeClass('mouseover'); });
    }
);

редагувати: це рішення вимагає, звичайно, змінити CSS, щоб видалити селектори ": hover" та заздалегідь обміркуйте, які елементи ви хочете "захопити".

Якщо у вас дуже багато елементів на вашій сторінці (наприклад, кілька тисяч), вона, можливо, стає дещо повільною, оскільки це рішення фіксує події трьох типів на всіх елементах сторінки, а потім робить свою справу, якщо селектор відповідає. Я назвав клас CSS "курсором миші" замість "навести курсор", тому що я не хотів, щоб читачі CSS читали ": наведіть", де я написав ".hover".


0

Ось моє рішення: http://jsfiddle.net/agamemnus/g56aw709/-- код нижче.

Все, що потрібно зробити, це перетворити їх ": навести курсор" в ".hover" ... ось і все! Велика різниця між цим та рештою полягає в тому, що це також буде працювати на селекторах несинуальних елементів, таких як .my_class > *:hover {.

handle_css_hover_effects ()

function handle_css_hover_effects (init) {
 var init = init || {}
 var handle_touch_events = init.handle_touch_events || true
 var handle_mouse_events = init.handle_mouse_events || true
 var hover_class         = init.hover_class         || "hover"
 var delay_preferences   = init.delay_preferences   || {touch: {add: 500, remove: 500}}
 function default_handler (curobj, input_type, op) {
  var hovered_element_selector = "*" + ((op == "add") ? ":" : ("." + hover_class))
  var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll(hovered_element_selector))
  var modified_list = []
  while (true) {
   if ((curobj == null) || (curobj == document.documentElement)) break
   if (hovered_elements.indexOf(curobj) != -1) modified_list.push (curobj)
   curobj = curobj.parentNode
  }
  function do_hover_change () {modified_list.forEach (function (curobj) {curobj.classList[op](hover_class)})}
  if ((!delay_preferences[input_type]) || (!delay_preferences[input_type][op])) {
   do_hover_change ()
  } else {
   setTimeout (do_hover_change, delay_preferences[input_type][op])
  }
 }

 if (handle_mouse_events) {
  document.body.addEventListener ('mouseover' , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "add")})
  document.body.addEventListener ('mouseout'  , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "remove")})
  document.body.addEventListener ('click'     , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "remove")})
 }

 if (handle_touch_events) {
  document.body.addEventListener ('touchstart', function (evt) {var curobj = evt.target; default_handler (curobj, "touch", "add")})
  document.body.addEventListener ('touchend'  , function (evt) {var curobj = evt.target; default_handler (curobj, "touch", "remove")})
  document.body.addEventListener ('touchmove',  function (evt) {
   var curobj = evt.target
   var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll("*:hover"))
   var lastobj = null
   evt = evt.changedTouches[0]
   var elements_at_point = get_elements_at_point (evt.pageX, evt.pageY)
   // Get the last element that isn't at the current point but is still hovered over, and remove only its hover attribute.
   while (true) {
    if ((curobj == null) || (curobj == document.documentElement)) break
    if ((hovered_elements.indexOf(curobj) != -1) && (elements_at_point.indexOf(curobj) == -1)) lastobj = curobj
    curobj = curobj.parentNode
   }
   if (lastobj == null) return
   if ((!delay_preferences.touch) || (!delay_preferences.touch.remove)) {
    lastobj.classList.remove(hover_class)
   } else {
    setTimeout (function () {lastobj.classList.remove(hover_class)}, delay_preferences.touch.remove)
   }

   function get_elements_at_point (x, y) {
    var el_list = [], pe_list = []
    while (true) {
     var curobj = document.elementFromPoint(x, y)
     if ((curobj == null) || (curobj == document.documentElement)) break
     el_list.push (curobj); pe_list.push (curobj.style.pointerEvents)
     curobj.style.pointerEvents = "none"
    }
    el_list.forEach (function (current_element, i) {current_element.style.pointerEvents = pe_list[i]})
    return el_list
   }
  })
 }
}


0

Привіт, люди з майбутнього, напевно, ви хочете скористатися запитом pointerта / або hoverмедіа. handheldЗапит ЗМІ засуджувалися.

/* device is using a mouse or similar */
@media (pointer: fine) {
  a:hover {
    background: red;
  }
}

-1

Спробуйте це легке рішення jQery для 2019 року, хоча його вже минуло;

  1. додайте цей плагін до голови:

    src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"

  2. додайте це до js:

    $("*").on("touchend", function(e) { $(this).focus(); }); //applies to all elements

  3. деякі запропоновані варіанти цього:

    $(":input, :checkbox,").on("touchend", function(e) {(this).focus);}); //specify elements
    
    $("*").on("click, touchend", function(e) { $(this).focus(); });  //include click event`
    
    css: body { cursor: pointer; } //touch anywhere to end a focus`

Примітки

  • розмістіть плагін перед bootstrap.js, якщо це застосовано, щоб не впливати на підказки
  • тестується лише на iphone XR ios 12.1.12 та ipad 3 ios 9.3.5, використовуючи Safari або Chrome.

Список літератури:

https://code.jquery.com/ui/

https://api.jquery.com/category/selectors/jquery-selector-extensions/

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