Đây là những gì tôi đã đưa ra cho đến nay sau khi nghiên cứu phần còn lại của câu trả lời. Nó có thể hỗ trợ người dùng chỉ cảm ứng, chỉ chuột hoặc lai.
Tạo một lớp di chuột riêng cho hiệu ứng di chuột. Theo mặc định, thêm lớp di chuột này vào nút của chúng tôi.
Chúng tôi không muốn phát hiện sự hiện diện của hỗ trợ cảm ứng và vô hiệu hóa tất cả các hiệu ứng di chuột ngay từ đầu. Như đã đề cập bởi những người khác, các thiết bị lai đang trở nên phổ biến; mọi người có thể có hỗ trợ cảm ứng nhưng muốn sử dụng chuột và ngược lại. Do đó, chỉ loại bỏ lớp di chuột khi người dùng thực sự chạm vào nút.
Vấn đề tiếp theo là, nếu người dùng muốn quay lại sử dụng chuột sau khi chạm vào nút thì sao? Để giải quyết điều đó, chúng ta cần tìm một thời điểm thích hợp để thêm lại lớp di chuột mà chúng ta đã loại bỏ.
Tuy nhiên, chúng tôi không thể thêm lại ngay sau khi gỡ bỏ, vì trạng thái di chuột vẫn còn hoạt động. Chúng tôi có thể không muốn phá hủy và tạo lại toàn bộ nút.
Vì vậy, tôi đã nghĩ đến việc sử dụng thuật toán chờ bận (sử dụng setInterval) để kiểm tra trạng thái di chuột. Khi trạng thái di chuột bị vô hiệu hóa, chúng ta có thể thêm lại lớp di chuột và dừng chờ đợi bận, đưa chúng ta trở lại trạng thái ban đầu nơi người dùng có thể sử dụng chuột hoặc chạm.
Tôi biết chờ đợi bận rộn không phải là tuyệt vời nhưng tôi không chắc có một sự kiện thích hợp. Tôi đã xem xét để thêm nó trở lại trong sự kiện mouseleave, nhưng nó không mạnh mẽ lắm. Ví dụ: khi cảnh báo bật lên sau khi chạm vào nút, vị trí chuột sẽ dịch chuyển nhưng sự kiện mouseleave không được kích hoạt.
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>
Chỉnh sửa: Một cách tiếp cận khác mà tôi đã thử là gọi e.preventDefault()
trong ontouchstart hoặc ontouchend. Nó dường như dừng hiệu ứng di chuột khi chạm vào nút, nhưng nó cũng dừng hoạt hình nhấp vào nút và ngăn chức năng onclick được gọi khi chạm vào nút, do đó bạn phải gọi thủ công trong trình xử lý ontouchstart hoặc ontouchend. Không phải là một giải pháp rất sạch sẽ.