Це те, що я придумав поки що після вивчення решти відповідей. Він повинен мати можливість підтримувати користувачів, які працюють лише на дотику, лише мишами або гібридами.
Створіть окремий клас наведення курсора для ефекту наведення. За замовчуванням додайте цей клавішу наведення в нашу кнопку.
Ми не хочемо виявляти наявність сенсорної підтримки та відключати всі ефекти, що наближаються, з самого початку. Як зазначають інші, гібридні пристрої набувають все більшої популярності; люди можуть мати підтримку дотику, але хочуть користуватися мишкою і навпаки. Тому видаляйте клавішу наведення лише тоді, коли користувач дійсно торкнеться кнопки.
Наступна проблема полягає в тому, що якщо користувач хоче повернутися до використання миші після натискання кнопки? Щоб вирішити це, нам потрібно знайти сприятливий момент, щоб додати назад клавішу наведення, яку ми видалили.
Однак ми не можемо додати його назад відразу після видалення, оскільки стан наведення курса все ще активний. Ми можемо не захотіти також знищувати та відтворювати всю кнопку.
Отже, я подумав використати алгоритм зайнятого очікування (використовуючи 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. Не дуже чисте рішення.