Як запобігти липким ефектам наведення для кнопок на сенсорних пристроях


144

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

  • Я міг би додати no-hoverклас ontouchendдля кожної кнопки і зробити так, щоб мій CSS виглядав так: button:not(.no-hover):hover { background-color: blue; }але це, мабуть, досить погано, але він не обробляє пристрої, такі як Chromebook Pixel (на якому є сенсорний екран і миша) правильно.

  • Я можу додати touchклас до documentElementта зробити свій CSS таким чином: html:not(.touch) button:hover { background-color: blue; }Але це також не працює як на пристроях, так і мишкою.

Я б хотів зняти стан наведення ontouchend. Але здається, що це неможливо. Фокусування іншого елемента не усуває стан наведення. Натискання іншого елемента вручну, але я не можу викликати це в JavaScript.

Усі знайдені нами рішення здаються недосконалими. Чи є ідеальне рішення?

Відповіді:


55

Ви можете видалити наведення курсора, тимчасово видаливши посилання з DOM. Дивіться http://testbug.handcraft.com/ipad.html


У CSS у вас є:

:hover {background:red;}

У JS:

function fix()
{
    var el = this;
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    setTimeout(function() {par.insertBefore(el, next);}, 0)
}

І тоді у своєму HTML ви маєте:

<a href="#" ontouchend="this.onclick=fix">test</a>

3
@Chris Добре, я змінив приклад, щоб встановити обробник onclick у події ontouchend.
Sjoerd Visscher

4
Просимо додати до своєї відповіді мінімальний демонстративний код. Дякую! stackoverflow.com/help/how-to-answer
2540625

1
@SjoerdVisscher Я вставив його. StackOverflow сподобається, що код є у відповіді, оскільки посилання можуть переходити. (І в цьому випадку потрібно було не просто клацнути, а потім переглянути джерело та опрацювати, які біти - це техніка, про яку йдеться.)
Даррен Кук

2
@KevinBorders так, на деяких пристроях затримка часу між видаленням та повторним введенням елемента може бути дуже помітною. На жаль, я виявив на своєму пристрої Android 4.4, що це робити без setTimeout не вийшло.
Родні

1
Ідея цікава, але я виявив її трохи хиткою і не широко підтримується на всіх сенсорних пристроях. Я вважаю за краще менш інвазивне рішення, засноване на виявленні сенсорної підтримки та чистому CSS, як це stackoverflow.com/a/39787268/885464
Лоренцо Полідорі

83

Після впровадження медіа-запитів CSS рівня 4 , ви зможете зробити це:

@media (hover: hover) {
    button:hover {
        background-color: blue;
    }
}

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

Оскільки ця частина медіа-запитів рівня 4 до цих пір була реалізована лише у висококваліфікованому Chrome, я написав поліфайл, щоб вирішити це. Використовуючи його, ви можете перетворити вищезазначений футуристичний CSS в:

html.my-true-hover button:hover {
    background-color: blue;
}

(Варіант в .no-touchтехніці) А потім, використовуючи деякий JavaScript на стороні клієнта з тієї ж поліфіли, яка виявляє підтримку ширяння, ви можете відповідним чином переключити присутність my-true-hoverкласу:

$(document).on('mq4hsChange', function (e) {
    $(document.documentElement).toggleClass('my-true-hover', e.trueHover);
});

Дякую! З моїх цілей, здається, це підтримується в більшості браузерів caniuse.com/#search=media%20queries і працює чудово, дякую!
ragamufin

3
Вам потрібно подивитися на caniuse.com/#feat=css-media-interaction замість цього, і ви побачите, що це не підтримується в Firefox та IE11 :( значить, вам потрібна
polyfill

Здається, полізаповнення більше не підтримується (
репортаж

Зараз це широко підтримується в мобільних браузерах і працює як шарм. Я думаю, що це має бути прийнята відповідь.
Тревор Бернхем

Це, безумовно, найпростіший в реалізації та найкращий варіант відповіді. Працює в Firefox на Android Mobile і ПК. Не впевнений у пристроях подвійного дотику та миші.
Півмісяця

28

Це поширена проблема, коли немає ідеального рішення. Поведінка курсора корисна мишкою і згубно впливає на дотик. Проблему ускладнюють такі пристрої, які підтримують сенсорне миші (одночасно, не менше!), Як Chromebook Pixel and Surface.

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

var isTouch =  !!("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;

if( !isTouch ){
    // add class which defines hover behavior
}

Звичайно, ви втрачаєте наведення на пристрої, які можуть його підтримувати. Однак іноді наведення курсору впливає більше, ніж саме посилання, наприклад, можливо, ви хочете показати меню, коли елемент завис. Такий підхід дозволяє перевірити наявність дотику і, можливо, умовно приєднати іншу подію.

Я тестував це на iPhone, iPad, Chromebook Pixel, Surface та різноманітних пристроях Android. Я не можу гарантувати, що він буде працювати, коли до суміші буде додано загальний USB-вхід (наприклад, стилус).


1
Чудово, це працювало для мене, на відміну від відповіді вікі / Даррен Кук.
Jannik

1
Хороша відповідь. Це схоже рішення: stackoverflow.com/a/39787268/885464
Лоренцо Полідорі

11

За допомогою Modernizr ви можете орієнтуватися на наведення курсорів спеціально для пристроїв без дотику:

(Примітка. Це не працює у фрагменті системи StackOverflow, замість цього перевірте jsfiddle )

/* this one is sticky */
#regular:hover, #regular:active {
  opacity: 0.5;
}

/* this one isn't */
html.no-touch #no-touch:hover, #no-touch:active {
  opacity: 0.5;
}

Зауважте, що на :activeце не потрібно орієнтуватися, .no-touchоскільки він працює, як очікувалося, і на мобільному, і на робочому столі.


Це найкраща відповідь ІМО, АЛЕ приклад невірний. Він показує однаковий стан наведення курсора для пристроїв, що торкаються та не торкаються. Він повинен застосовувати стан наведення курсора, лише якщо .no-touchвін присутній у htmlтезі. Інакше ця відповідь отримує мою печатку схвалення.
morrisbret

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

Я думаю, що одним із способів зробити це буде використання як Modernizr, так і бібліотеки, наприклад, mobile-detect.js, щоб переконатися, що це або телефон, або планшет.
Гевін

Ви людина-рятівник, яка дуже дякує, що це прекрасно працювало для мобільних пристроїв
Шивам

9

Ви можете змінити ефект наведення на пристрої, які не підтримують наведення. Подібно до:

.my-thing {
    color: #BADA55;
}

.my-thing:hover {
    color: hotpink;
}

@media (hover: none) {
    .my-thing {
        color: #BADA55;
    }
}

Тестовано та перевірено на iOS 12

Підказка на шапку https://stackoverflow.com/a/50285058/178959 для вказівки на це.


Це більш сучасне рішення, не потрібно маніпулювати JavaScript або DOM, має повну підтримку браузера (крім IE), і це має бути прийнятою відповіддю.
funkju

8
$("#elementwithhover").click(function() { 
  // code that makes element or parent slide or otherwise move out from under mouse. 

  $(this).clone(true).insertAfter($(this));
  $(this).remove();
});

Ви можете покращити цю відповідь, використовуючи on () замість клацання (). Видаливши елемент з DOM і повторно приєднавши його, я втратив події клацання. Коли я переписав свою функцію на ввімкнений, прив’язуючи до елемента, потім видалення та додавання працював. Наприклад: `$ ('body'). On ('click', '# elementwithhover', function () {// клон, вставка, видалення}); Я проголосую за це, якщо ви внесете ці зміни.
Буде Ланні

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

дивовижний брато, 10х
Калоян Стаматов

Години пошуку виправлення, і це, нарешті, забезпечило. Завдяки мільйонів!
phil917

8

З чотирьох способів боротьби з клейким наведенням на мобільний телефон : Ось спосіб динамічно додати або видалити can touchклас " " до документа на основі поточного типу вводу користувача. Він також працює з гібридними пристроями, де користувач може перемикатися між сенсорним та мишею / трекпадом:

<script>

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")

    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }

    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }

    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

</script>

Це найкращий спосіб, який я знаходжу, плюс якщо ви збільшите таймер до 1000 мс, ви також можете охопити довге натискання, дивіться тут . Чудові речі!
lowtechsun

3

Я збирався опублікувати власне рішення, але перевіривши, чи хтось уже розмістив його, я виявив, що @Rodney майже це зробив. Однак він пропустив це одне останнє вирішальне значення, яке зробило його розумним, принаймні в моєму випадку. Я маю на увазі, що я теж взяв .fakeHoverдодавання / видалення того ж класу через mouseenterі mouseleaveвиявлення подій, але це само по собі діє майже так само, як "справжнє" :hover. Я маю на увазі: коли ви натискаєте на елемент своєї таблиці, він не виявить, що ви його "покинули" - таким чином зберігаючи стан "підробленого".

Те, що я робив, було просто слухати click, тому коли я "натискаю" кнопку, я вручну запускаю mouseleave.

Так це мій остаточний код:

.fakeHover {
    background-color: blue;
}


$(document).on('mouseenter', 'button.myButton',function(){
    $(this).addClass('fakeHover');
});

$(document).on('mouseleave', 'button.myButton',function(){
    $(this).removeClass('fakeHover');
});

$(document).on('button.myButton, 'click', function(){
    $(this).mouseleave();
});

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


2

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

Створіть окремий клас наведення курсора для ефекту наведення. За замовчуванням додайте цей клавішу наведення в нашу кнопку.

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

Наступна проблема полягає в тому, що якщо користувач хоче повернутися до використання миші після натискання кнопки? Щоб вирішити це, нам потрібно знайти сприятливий момент, щоб додати назад клавішу наведення, яку ми видалили.

Однак ми не можемо додати його назад відразу після видалення, оскільки стан наведення курса все ще активний. Ми можемо не захотіти також знищувати та відтворювати всю кнопку.

Отже, я подумав використати алгоритм зайнятого очікування (використовуючи setInterval) для перевірки стану наведення. Після відключення стану наведення ми можемо знову додати клас наведення курсора і зупинити зайняте очікування, повернувши нас до початкового стану, де користувач може використовувати мишу або торкнутись.

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

var button = document.getElementById('myButton');

button.ontouchstart = function(e) {
  console.log('ontouchstart');
  $('.button').removeClass('button-hover');
  startIntervalToResetHover();
};

button.onclick = function(e) {
  console.log('onclick');
}

var intervalId;

function startIntervalToResetHover() {
  // Clear the previous one, if any.
  if (intervalId) {
    clearInterval(intervalId);
  }
  
  intervalId = setInterval(function() {
    // Stop if the hover class already exists.
    if ($('.button').hasClass('button-hover')) {
      clearInterval(intervalId);
      intervalId = null;
      return;
    }
    
    // Checking of hover state from 
    // http://stackoverflow.com/a/8981521/2669960.
    var isHovered = !!$('.button').filter(function() {
      return $(this).is(":hover");
    }).length;
    
    if (isHovered) {
      console.log('Hover state is active');
    } else {
      console.log('Hover state is inactive');
      $('.button').addClass('button-hover');
      console.log('Added back the button-hover class');
      
      clearInterval(intervalId);
      intervalId = null;
    }
  }, 1000);
}
.button {
  color: green;
  border: none;
}

.button-hover:hover {
  background: yellow;
  border: none;
}

.button:active {
  border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='myButton' class='button button-hover'>Hello</button>

Редагувати: Ще один підхід, який я намагався, - зателефонувати e.preventDefault()в ontouchstart або ontouchend. Схоже, це зупиняє ефект наведення при дотику до кнопки, але він також зупиняє анімацію натискання кнопки і не дозволяє викликати функцію onclick при натисканні кнопки, тому вам доведеться викликати їх вручну в програмі ontouchstart або ontouchend. Не дуже чисте рішення.


1

Для мене це було корисно: посилання

function hoverTouchUnstick() {
    // Check if the device supports touch events
    if('ontouchstart' in document.documentElement) {
        // Loop through each stylesheet
        for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
            var sheet = document.styleSheets[sheetI];
            // Verify if cssRules exists in sheet
            if(sheet.cssRules) {
                // Loop through each rule in sheet
                for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
                    var rule = sheet.cssRules[ruleI];
                    // Verify rule has selector text
                    if(rule.selectorText) {
                        // Replace hover psuedo-class with active psuedo-class
                        rule.selectorText = rule.selectorText.replace(":hover", ":active");
                    }
                }
            }
        }
    }
}

Вам потрібно зателефонувати hoverTouchUnstick () один раз від глобального обробника подій ontouchstart. І це рішення спрацювало б чудово.
Jusid

1

Додайте цей JS-код на свою сторінку:

document.body.className = 'ontouchstart' in document.documentElement ? '' : 'hover';

тепер у своєму CSS перед кожним наведенням курсору додайте такий тип курсора:

.hover .foo:hover {}

Якщо пристрій сенсорний, клас кузова буде порожнім, інакше його клас буде навести курсор і застосувати правила!


Не працювало для мене, але це сталося:document.body.className = 'ontouchstart' in window ? '' : 'hover';
drskullster

1

Я можу додати клавішу без наведення курсору для кожної кнопки та зробити свій CSS таким чином> цей: кнопка: не (. No-hover): hover {фон-колір: синій; }, але це, мабуть, досить погано, і не обробляє> пристрої, такі як Chromebook Pixel (на якому є сенсорний екран і миша)> правильно.

Це правильна відправна точка. Наступний крок: застосувати / видалити nohover клас для наступних подій (демонстрація з jQuery)

buttonelement
 .on("touchend touchcancel",function(){$(this).addClass("nohover")})
 .on("touchstart mouseover",function({$(this).removeClass("nohover")});   

Примітка: Якщо ви хочете застосувати інші класи до buttonelement, то: not (.nohover) у CSS більше не працюватиме, як очікувалося. Тоді Вам замість цього слід додати окреме визначення зі значенням за замовчуванням та! Важливим тегом, щоб замінити стиль наведення курсора: .nohover {background-color: white! Важливо}

З цим навіть слід правильно керувати пристроями, такими як Chromebook Pixel (на якому є сенсорний екран і миша)! І я не думаю, що це головний вбивця продуктивності ...


1

Рішення, яке працювало для мене:

html {
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

Додайте цей код до таблиці стилів.

Я хотів позбутися сірого фону, який з’являється на iOS Safari, коли натискається посилання. Але, схоже, зробити більше. Тепер натискання кнопки (з :hoverпсевдокласом!) Відкривається відразу! Я тестував його лише на iPad, не знаю, чи буде він працювати на інших пристроях.


1

Я думаю, що я знайшов елегантне (мінімум js) рішення для подібної проблеми:

Використовуючи jQuery, ви можете запустити наведення на корпус (або будь-який інший елемент), використовуючи .mouseover()

Тому я просто додаю цей обробник до ontouchendподії елемента так:

var unhover = function() {
  $("body").mousover();  
};
.hoverable {
  width: 100px;
  height: 100px;
  background: teal;
  cursor: pointer;
}

.hoverable:hover {
  background: pink;
}
<div class="hoverable" ontouchend={unhover}></div>

Це, однак, лише видаляє: наведіть курсор псевдокласу з елемента після запуску іншої сенсорної події, наприклад, пальцем чи іншим дотиком


1
Для фрагмента вашого коду квадрат залишається рожевим після того, як я торкнувся його. Напевно, ти насправді не вирішив задану в цьому питанні проблему?
Кевін Лі

Це рішення не працює. По-перше, ви використовували неправильний метод для виклику події, ви повинні використовувати .trigger () . По-друге, жоден спосіб не працює на мобільному сафарі.
xHocquet

1

У мене є гарне рішення, яким я хотів би поділитися. Спочатку потрібно виявити, чи користувач перебуває на такому мобільному телефоні:

var touchDevice = /ipad|iphone|android|windows phone|blackberry/i.test(navigator.userAgent.toLowerCase());

Потім просто додайте:

if (!touchDevice) {
    $(".navbar-ul").addClass("hoverable");
}

І в CSS:

.navbar-ul.hoverable li a:hover {
    color: #fff;
}

2
Не працює на гібридних пристроях, наприклад, на ПК із сенсорним екраном Windows.
cspolton

1

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

Ми використовували SCSS у нашому додатку. і я визначив міксин, щоб піклуватися про сенсорний пристрій.

@mixin hover-support {
  @media not all and (pointer: coarse) {
    &:hover {
      @content;
    }
  }
}

а потім я розмістив усі свої класи css під згаданим фрагментом нижче.

   @include hover-support() {
    // Your css-classes or css that you want to apply on those devices that support hover.
   }

Наприклад, у нас був клас з анімації піктограми, який використовувався для запуску, коли ми наводимо курсор на значок, як ви бачите його з css, але на пристрої на основі дотику це вплинуло на липкий ефект наведення, а потім я помістив його всередину @ включіть підтримку наведення () , щоб переконатися, що наведення курсора застосовується лише до тих пристроїв, які підтримують наведення.

@include hover-support() {
  .animate-icon {
    -webkit-transition: all 0.2s;
    transition: all 0.2s;
    &:hover {
      transform: scale(1.3);
      filter: brightness(85%);
      cursor: pointer;
    }
  }
}

1

Ось простий код JavaScript, який не вимагає від розробника редагувати CSS або писати нові правила CSS. Я написав це для кнопок Bootstrap class="btn", але він буде працювати з будь-якою кнопкою, яка має конкретну назву класу.

Етапи:

  1. визначте, чи це сенсорний пристрій
  2. якщо він є, повторіть кожне правило CSS в document.styleSheets
  3. видалити будь-яке правило, що містить і .btnі, і:hover

Усунення всіх .btn :hoverправил CSS забезпечує відсутність візуального ефекту наведення на кнопку.

Крок 1: Визначте сенсорний пристрій

Перевірте медіа-запит на наявність (hover: none):

    const hasMatchMedia = typeof window.matchMedia !== 'undefined';
    /**
     * determine if device is touch-capable
     * true - device is touch-capable
     * false - device is not touch-capable
     * null - unable to determine touch capability
     * @return {null|boolean}
     */
    const hasTouch = () => {
      if (hasMatchMedia) {
        return window.matchMedia('(hover: none)').matches;
      }
      return null;
    };

Крок 2: Видаліть правила CSS, що містять `btn` та`: hover`

    /**
     * remove all CSS rules contaning both '.btn' and ':hover'
     * @return {number} count of rules deleted
     */
    function removeBtnHovers () {

      let rulesDeleted = 0;

      // recursively delete '.btn:hover' rules
      function recursiveDelete (rules, styleSheet) {

        if (typeof rules === 'undefined' ||
          typeof rules.length === 'undefined' ||
          rules.length <= 0) {
          return;
        }

        // iterate in reverse order,
        // deleting any rule containing both '.btn' and ':hover'
        const ruleLen = rules.length;
        for (let i = ruleLen - 1; i >= 0; i--) {
          const rule = rules[i];
          if (typeof rule.cssRules === 'undefined') {
            // a standard rule, evaluate it
            const cssText = rule.cssText;
            if (typeof cssText === 'string' &&
              cssText.includes('.btn') &&
              cssText.includes(':hover')) {
              styleSheet.deleteRule(i);
              rulesDeleted++;
            }
          } else {
            // rule contains cssRules, iterate over them
            recursiveDelete(rule.cssRules, rule);
          }
        }
      }

      // iterate over all style sheets in document
      for (const styleSheet of document.styleSheets) {
        let rules = styleSheet.cssRules;
        if (!rules) { continue; }
        recursiveDelete(rules, styleSheet);
      }
      return rulesDeleted;
    }

Повний код знаходиться на GitHub та npm .

Демонстрація демонстрації на сайті terrymorse.com .


Чи це також не знімає ефект наведення курсора для пристроїв із сенсорним екраном із мишею / трекпад?
Jensei

@Jensei Можливо. Наведення курсора видаляється, якщо пристрій відповідає @media (hover:none)або коли користувач вперше торкнеться екрана. Ви можете спробувати це на демонстраційній сторінці в прямому ефірі, щоб бути впевненим.
terrymorse

0

Ви можете встановити колір тла на :activeстан і надати :focus дефолтний фон.

якщо встановити колір фону через onfocus/ontouch, стиль кольору залишається, коли :focusстан перейшов.
Вам також потрібно скинути onblur, щоб відновити дефолт bg, коли фокус втрачено.


Але я хотів би зберегти ефект наведення для користувачів миші.
Кріс

: наведіть курсор і: active може отримувати той самий CSS, саме на: фокус у вас проблема. Насправді, якщо встановити колір тла за допомогою фокуса, стиль кольору залишається, коли фокус піде. вам також потрібно скинути на onlur, щоб відновити дефолт bg
G-Cyrillus

0

Це працювало для мене: ставимо курсор на клавіатуру в новому класі

.fakehover {background: red}

Потім додайте / видаліть клас як і коли потрібно

$(".someclass > li").on("mouseenter", function(e) {
  $(this).addClass("fakehover");
});
$(".someclass > li").on("mouseleave", function(e) {
  $(this).removeClass("fakehover");
});

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


0

На основі відповіді Даррена Кукса, який також працює, якщо ви перевели пальцем на інший елемент.

Див. Розділ Пошук пальця елементів увімкнено під час події в дотику

jQuery(function() {
    FastClick.attach(document.body);
});
// Prevent sticky hover effects for buttons on touch devices
// From https://stackoverflow.com/a/17234319
//
//
// Usage:
// <a href="..." touch-focus-fix>..</a>
//
// Refactored from a directive for better performance and compability
jQuery(document.documentElement).on('touchend', function(event) {
  'use strict';

  function fix(sourceElement) {
    var el = $(sourceElement).closest('[touch-focus-fix]')[0];
    if (!el) {
      return;
    }
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    par.insertBefore(el, next);
  }

  fix(event.target);
  var changedTouch = event.originalEvent.changedTouches[0];
  // http://www.w3.org/TR/2011/WD-touch-events-20110505/#the-touchend-event
  if (!changedTouch) {
    return;
  }
  var touchTarget = document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);
  if (touchTarget && touchTarget !== event.target) {
    fix(touchTarget);
  }
});

Codepen Demo


0

Можна спробувати таким чином.

javascript:

var isEventSupported = function (eventName, elementName) {
    var el = elementName ? document.createElement(elementName) : window;
    eventName = 'on' + eventName;
    var isSupported = (eventName in el);
    if (!isSupported && el.setAttribute) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
    }
    el = null;
    return isSupported;
};

if (!isEventSupported('touchstart')) {
    $('a').addClass('with-hover');
}

css:

a.with-hover:hover {
  color: #fafafa;
}

0

Що я до цього часу робив у своїх проектах, це повернути :hoverзміни на сенсорних пристроях:

.myhoveredclass {
    background-color:green;
}
.myhoveredclass:hover {
    background-color:red;
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
    .myhoveredclass:hover, .myhoveredclass:active, .myhoveredclass:focus {
        background-color:green;
    }
}

Усі назви класів та названі кольори лише для демонстраційних цілей ;-)


0

Це чудово працює в 2 етапи.

  1. Встановіть тег тіла таким чином <body ontouchstart="">. Я не прихильник цього "хаку", але це дозволяє Safari на iOS миттєво реагувати на дотики. Не впевнений як, але це працює.

  2. Налаштуйте свій дотичний клас так:

    // I did this in SASS, but this should work with normal CSS as well
    
    // Touchable class
    .example {
    
        // Default styles
        background: green;
    
        // Default hover styles 
        // (Think of this as Desktop and larger)
        &:hover {
            background: yellow;
        }
    
        // Default active styles
        &:active {
            background: red;
        }
    
        // Setup breakpoint for smaller device widths
        @media only screen and (max-width: 1048px) {
    
            // Important!
            // Reset touchable hover styles
            // You may want to use the same exact styles as the Default styles
            &:hover {
                background: green;
            }
    
            // Important!
            // Touchable active styles
            &:active {
                background: red;
            }
        }
    }

Ви також можете видалити будь-яку анімацію з вашого дотичного класу. Android Chrome, здається, трохи повільніше, ніж iOS.

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


0

Деякі проблеми з липкою або застряглими :hover :focus :activeна мобільних пристроях можуть бути спричинені відсутністю, <meta name="viewport" content="width=device-width">оскільки браузери намагаються маніпулювати екраном.


0

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

    let cloneNode = originNode.cloneNode( true );
    originNode.parentNode.replaceChild( cloneNode, originNode );

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

0

Це можна досягти, замінивши клас HTML. Він повинен бути менш схильним до збоїв, ніж видалення всього елемента, особливо з великими посиланнями на зображення тощо.

Ми також можемо вирішити, чи хочемо ми спрацьовувати наведення курсорів під час прокрутки з дотиком (touchmove) або навіть додати тайм-аут, щоб затримати їх.

Єдиною суттєвою зміною нашого коду буде використання додаткового класу HTML, наприклад, <a class='hover'></a>щодо елементів, що реалізують нову поведінку.

HTML

<a class='my-link hover' href='#'>
    Test
</a>

CSS

.my-link:active, // :active can be turned off to disable hover state on 'touchmove'
.my-link.hover:hover {

    border: 2px dotted grey;
}

JS (з jQuery)

$('.hover').bind('touchstart', function () {

   var $el;
   $el = $(this);
   $el.removeClass('hover'); 

   $el.hover(null, function () {
      $el.addClass('hover');
   });
});

Приклад

https://codepen.io/mattrcouk/pen/VweajZv

-

Я не маю жодного пристрою з мишею та сенсорним, щоб перевірити його належним чином.


0

З 2020 року ви можете додавати стилі наведення курсора у медіа-запит

@media (hover: hover) and (pointer: fine) {
    /* css hover class/style */
}

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

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