터치 장치의 버튼에 끈적임 호버 효과를 방지하는 방법
나는 항상 보이는 이전 및 다음 버튼으로 회전 목마를 만들었습니다. 이 버튼은 호버 상태이며 파란색으로 바뀝니다. iPad와 같은 터치 장치에서는 호버 상태가 고정되어 있으므로 버튼을 탭한 후에도 파란색으로 유지됩니다. 나는 그것을 원하지 않습니다.
각 버튼에
no-hover
클래스ontouchend
를 추가하고 CSS를 다음과 같이 만들 수는button:not(.no-hover):hover { background-color: blue; }
있지만 성능에는 좋지 않을 수 있으며 크롬 북 픽셀 (터치 스크린과 마우스가 모두있는)과 같은 기기를 올바르게 처리하지 못합니다.touch
클래스를 추가하고documentElement
CSS를 다음과 같이 만들 수 있습니다 .html:not(.touch) button:hover { background-color: blue; }
그러나 터치와 마우스가 모두있는 장치에서는 제대로 작동하지 않습니다.
내가 선호하는 것은 호버 상태를 제거하는 것 ontouchend
입니다. 그러나 가능하지 않은 것 같습니다. 다른 요소에 초점을 맞추더라도 호버 상태가 제거되지 않습니다. 다른 요소를 수동으로 두드리는 것이 좋지만 JavaScript에서 트리거 할 수 없습니다.
내가 찾은 모든 솔루션이 불완전한 것처럼 보입니다. 완벽한 솔루션이 있습니까?
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>
일단 CSS 미디어 쿼리 레벨 4가 구현되어, 당신은이 작업을 수행 할 수 있습니다 :
@media (hover: hover) {
button:hover {
background-color: blue;
}
}
또는 영어로 : "브라우저가 올바른 / 진짜 / 실제 / 비 에뮬레이트 호버링을 지원하는 경우 (예 : 마우스와 같은 기본 입력 장치가있는 경우) button
마우스를 가리킬 때이 스타일을 적용하십시오 ."
Media Queries Level 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);
});
완벽한 솔루션이없는 일반적인 문제입니다. 호버 동작은 마우스에 유용하며 대부분 터치하면 해 롭습니다. 문제는 크롬 북 픽셀 및 표면과 같이 터치와 마우스를 동시에 지원하는 기기입니다.
내가 찾은 가장 깨끗한 솔루션은 장치가 터치 입력을 지원하지 않는 경우에만 호버 동작을 활성화하는 것입니다.
var isTouch = !!("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;
if( !isTouch ){
// add class which defines hover behavior
}
물론 지원할 수있는 장치에서 호버링을 잃게됩니다. 그러나 때로는 마우스 오버가 링크 자체보다 많은 영향을 미칩니다. 예를 들어 요소를 가리킬 때 메뉴를 표시하려고 할 수 있습니다. 이 방법을 사용하면 터치가 있는지 테스트하고 조건부로 다른 이벤트를 첨부 할 수 있습니다.
나는 이것을 iPhone, iPad, Chromebook Pixel, Surface 및 다양한 Android 기기에서 테스트했습니다. 일반적인 USB 터치 입력 (스타일러스 등)이 믹스에 추가 될 때 작동한다는 보장은 없습니다.
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
이 같은 모바일 및 데스크톱 모두에서 예상 작동하기 때문에.
$("#elementwithhover").click(function() {
// code that makes element or parent slide or otherwise move out from under mouse.
$(this).clone(true).insertAfter($(this));
$(this).remove();
});
에서 모바일에 스티커 가져가 처리하는 4 가지 방법 : 여기에 동적으로 추가하거나 "제거하는 방법 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>
내 솔루션을 게시하려고했지만 누군가가 이미 게시했는지 확인한 결과 @Rodney가 거의 수행했음을 알았습니다. 그러나 그는 적어도 내 경우에는 그것을 불편하게 만드는 마지막 결정을 놓쳤다. 나는 나도 같은했다, 의미 .fakeHover
를 통해 제거 / 클래스 추가 mouseenter
및 mouseleave
이벤트 감지,하지만 혼자 그 자체 "정품"와 같은 거의 정확하게 작동합니다 :hover
. 내 말은 : 당신이 당신의 테이블에있는 요소를 누를 때, 그것은 당신이 그것을 "잎"을 감지하지 않으므로 "가짜"상태를 유지합니다.
내가 한 것은 단순히 듣기 만 click
했기 때문에 버튼을 "탭"하면 수동으로을 실행합니다 mouseleave
.
Si 이것은 내 최종 코드입니다.
.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
. 클릭하고 버튼에서 포인터를 빠르게 가져간 경우와 유사합니다. 그러나 제 경우에는 그걸로 살 수 있습니다.
호버를 지원하지 않는 장치의 호버 효과를 무시할 수 있습니다. 처럼:
.my-thing {
color: #BADA55;
}
.my-thing:hover {
color: hotpink;
}
@media (hover: none) {
.my-thing {
color: #BADA55;
}
}
iOS 12에서 테스트 및 검증
이것을 지적하기위한 모자 팁 https://stackoverflow.com/a/50285058/178959
도움이되었습니다 : 링크
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");
}
}
}
}
}
}
이 JS 코드를 페이지에 추가하십시오.
document.body.className = 'ontouchstart' in document.documentElement ? '' : 'hover';
이제 모든 호버 전에 CSS에서 다음과 같이 호버 클래스를 추가하십시오.
.hover .foo:hover {}
장치가 터치되면 바디 클래스가 비어 있고 그렇지 않으면 클래스가 가리키고 규칙이 적용됩니다!
각 버튼마다 호버링 없음 클래스 ontouchend를 추가하고 CSS를 다음과 같이 만들 수 있습니다.> this : button : not (.no-hover) : hover {background-color : blue; }하지만 성능에 좋지 않을 수 있으며 Chromebook Pixel (터치 스크린과 마우스가 모두있는)과 같은 기기를 올바르게 처리하지 않습니다.
이것이 올바른 출발점입니다. 다음 단계 : 다음 이벤트에서 nohover 클래스 적용 / 제거 (jQuery를 사용한 데모)
buttonelement
.on("touchend touchcancel",function(){$(this).addClass("nohover")})
.on("touchstart mouseover",function({$(this).removeClass("nohover")});
주의 사항 : 다른 클래스를 buttonelement에 적용하려면 CSS의 : not (.nohover)가 더 이상 예상대로 작동하지 않습니다. 호버 스타일을 겹쳐 쓰려면 기본값과! important 태그를 사용하여 별도의 정의를 추가해야합니다. .nohover {background-color : white! important}
Chromebook Pixel (터치 스크린과 마우스 모두 포함)과 같은 기기도 올바르게 처리해야합니다. 그리고 나는 이것이 주요 성능 킬러라고 생각하지 않습니다 ...
나를 위해 일한 솔루션 :
html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
이 코드를 스타일 시트에 추가하십시오.
링크를 클릭하면 iOS Safari에 나타나는 회색 배경을 제거하고 싶었습니다. 그러나 더 많은 것으로 보입니다. 이제 :hover
의사 클래스가 있는 버튼을 클릭하면 바로 열립니다! 나는 iPad에서만 테스트했지만 다른 장치에서 작동하는지 모르겠습니다.
비슷한 문제에 대한 우아한 (최소 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>
그러나 이것은 스 와이프 또는 다른 터치와 같은 다른 터치 이벤트가 트리거 된 후에 만 요소에서 의사 호버 클래스를 제거합니다.
이것이 나머지 답변을 연구 한 후에 지금까지 생각해 낸 것입니다. 터치 전용, 마우스 전용 또는 하이브리드 사용자를 지원할 수 있어야합니다.
호버 효과에 대한 별도의 호버 클래스를 만듭니다. 기본적으로이 호버 클래스를 버튼에 추가하십시오.
우리는 터치 지원의 존재를 감지하고 처음부터 모든 호버 효과를 비활성화하고 싶지 않습니다. 다른 사람들이 언급했듯이 하이브리드 장치는 인기를 얻고 있습니다. 사람들은 터치 지원 기능을 가지고 있지만 마우스를 사용하고 싶거나 그 반대의 경우도 있습니다. 따라서 사용자가 실제로 버튼을 터치 한 경우 호버 클래스 만 제거하십시오.
다음 문제는 사용자가 버튼을 터치 한 후 마우스 사용으로 돌아가려면 어떻게해야합니까? 이를 해결하기 위해 제거한 호버 클래스를 다시 추가 할 수있는 적절한 순간을 찾아야합니다.
그러나 호버 상태가 여전히 활성 상태이므로 제거 후 즉시 다시 추가 할 수 없습니다. 우리는 전체 버튼을 파괴하고 다시 만들고 싶지 않을 수도 있습니다.
따라서 바쁜 대기 알고리즘 (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 내 에서 전화하는 것입니다. 버튼을 터치하면 호버 효과가 중지되는 것처럼 보이지만 버튼 클릭 애니메이션을 중지하고 버튼을 터치 할 때 온 클릭 기능이 호출되는 것을 방지하므로 ontouchstart 또는 ontouchend 핸들러에서 수동으로 호출해야합니다. 매우 깨끗한 해결책은 아닙니다.
:active
상태에 배경색을 설정하고 기본 배경을 줄 수 :focus
있습니다.
via-color via를 설정 onfocus/ontouch
하면 :focus
상태가 사라지면 색상 스타일이 유지 됩니다. 초점을 잃었을 때 defaut bg를 복원하려면
재설정해야합니다 onblur
.
이것은 나를 위해 일했습니다 : 호버 스타일을 새로운 수업에 넣으십시오.
.fakehover {background: red}
그런 다음 필요에 따라 클래스를 추가 / 제거하십시오
$(".someclass > li").on("mouseenter", function(e) {
$(this).addClass("fakehover");
});
$(".someclass > li").on("mouseleave", function(e) {
$(this).removeClass("fakehover");
});
터치 스타트 및 터치 엔드 이벤트에 대해 반복하십시오. 또는 원하는 결과를 얻으려는 이벤트가 무엇이든, 예를 들어 터치 스크린에서 호버 효과를 전환하고 싶었습니다.
Darren Cooks의 답변을 바탕으로 다른 요소 위로 손가락을 움직여도 작동합니다.
터치 엔드 이벤트 중 요소 손가락 찾기를 참조하십시오.
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);
}
});
이 방법으로 시도 할 수 있습니다.
자바 스크립트 :
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;
}
지금까지 프로젝트에서 수행 한 작업은 :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;
}
}
데모 목적으로 만 모든 클래스 이름과 명명 된 색상 ;-)
이것은 2 단계로 완벽하게 작동합니다.
바디 태그를 다음과 같이 설정하십시오
<body ontouchstart="">
. 나는이 "해킹"의 팬이 아니지만 iOS의 Safari가 터치에 즉시 반응 할 수 있습니다. 잘 모르겠지만 작동합니다.다음과 같이 터치 가능한 클래스를 설정하십시오.
// 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보다 약간 느린 것 같습니다.
또한 사용자가 수업을 터치하면서 페이지를 스크롤하면 활성 상태가 적용됩니다.
나는 공유하고 싶은 좋은 해결책이 있습니다. 먼저 다음과 같이 사용자가 모바일에 있는지 감지해야합니다.
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;
}
브라우저가 화면을 조작하려고 시도 :hover
:focus
:active
할 때 모바일 장치 의 고정 또는 멈춤 문제 중 일부 가 누락 될 수 있습니다 <meta name="viewport" content="width=device-width">
.
나는 비슷한 문제를 겪었고, 내 응용 프로그램은 모든 화면 크기와 호환되며 데스크탑 화면 크기 / 마우스 기반 장치 에서 많은 호버 효과가 있었고 나중에 터치 기반 장치가 끈적 거리는 것으로 알려진 상태를 유발한다는 것을 깨달았습니다. 터치 기반 장치 사용자에게 앱이 제대로 작동하는 데 장애물이되었습니다.
앱에서 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에서 볼 수 있듯이 아이콘 위에 마우스를 올려 놓으면 트리거되는 데 사용되었지만 터치 기반 장치에서는 스티커 호버 효과의 영향을 받아 @ 안에 배치했습니다. 호버를 지원 하는 장치에만 호버를 적용하려면 hover-support () 를 포함하십시오.
@include hover-support() {
.animate-icon {
-webkit-transition: all 0.2s;
transition: all 0.2s;
&:hover {
transform: scale(1.3);
filter: brightness(85%);
cursor: pointer;
}
}
}
'IT' 카테고리의 다른 글
요소가 페이지에 추가 될 때 알림을 받으려면 어떻게해야합니까? (0) | 2020.07.04 |
---|---|
신호와 신호의 차이점은 무엇입니까? (0) | 2020.07.04 |
Bootstrap은 왜 line-height 속성을 1.428571429로 설정합니까? (0) | 2020.07.04 |
ES6 즉시 화살표 기능을 호출 (0) | 2020.07.04 |
React.js : innerHTML 대 위험한 설정 (0) | 2020.07.04 |