터치 인 터치가 가능한 브라우저에서 마우스 오버를 어떻게 시뮬레이션합니까?


120

다음과 같은 HTML을 사용합니다.

<p>Some Text</p>

다음과 같은 CSS :

p {
  color:black;
}

p:hover {
  color:red;
}

터치 지원 장치에서 길게 터치하여 호버를 복제하려면 어떻게해야합니까? 마크 업을 변경하거나 JS 등을 사용할 수 있지만이 작업을 수행하는 쉬운 방법을 생각할 수 없습니다.


저는 특히 iPhone OS를 생각하고 있습니다. CSS 애니메이션 데모로 많은 사람들이 클릭하는 것보다 마우스 오버를 사용하여 시작하기 쉽습니다.
Rich Bradshaw

답변:


172

좋아, 내가 해냈어! CSS를 약간 변경하고 JS를 추가하는 작업이 포함됩니다.

jQuery를 사용하여 쉽게 만들기 :

$(document).ready(function() {
    $('.hover').on('touchstart touchend', function(e) {
        e.preventDefault();
        $(this).toggleClass('hover_effect');
    });
});

영어 : 터치를 시작하거나 종료 할 때 수업을 hover_effect켜거나 끕니다.

그런 다음 HTML에서이 작업을 수행하려는 모든 항목에 클래스 호버를 추가하십시오. CSS에서 다음 인스턴스를 교체합니다.

element:hover {
    rule:properties;
}

element:hover, element.hover_effect {
    rule:properties;
}

유용성을 높이기 위해 CSS에도 다음을 추가하십시오.

.hover {
-webkit-user-select: none;
-webkit-touch-callout: none;        
}

이미지를 복사 / 저장 / 선택하라는 브라우저를 중지하려면.

쉬운!


이것은 훌륭합니다. toggle사용자가 한 요소를 터치하고 다른 요소로 드래그하면 문제 가 발생 하기 때문에 domready 함수를 분할했습니다 (예 : 잘못된 항목을 터치하고 터치를 취소하려는 경우)
Jacksonkr

나는 제거 touchend하고 preventDefault()내 웹 사이트에서 잘 작동하지만 이제 메뉴가 대상에서 탭하여 자동으로 닫히지 않습니다.
Даниил Пронин 2014 년

또한 사용자가 다른 곳을 터치하거나 스크롤을 시작할 때 그러한 메뉴를 닫는 방법에 대한 조언을 원합니다. touchstart몸에 다른 청취자 가있을 수 있다고 생각 하지만 (또는 비슷한) 더 좋은 방법이 있는지 궁금했습니다. 감사!
Darryl Young

2
어쨌든 스크롤 제스처를 무시할 수 있습니까? 이것은 내가 필요한 것을 정확히 수행하지만 이제는이 효과가있는 콘텐츠를 위아래로 스크롤 할 수 없습니다.
alsobubbly

1
스크롤을 사용할 수 있기를 원했기 때문에 preventDefault를 제거했지만 touchstart 및 touchend에 대한 팁에 감사드립니다! 하나님은 이것이 모든 브라우저에서 안정적으로 작동하는 유일한 답변입니다.
Petraeus

54

당신이해야 할 일은 부모에게 touchstart를 바인딩하는 것입니다. 다음과 같이 작동합니다.

$('body').on('touchstart', function() {});

함수에서 아무것도 할 필요가 없으며 비워 두십시오. 이것은 호버링을하기에 충분하므로 터치는 : hover와 비슷하고 덜 : active처럼 작동합니다. iOS 마술.


2
이 솔루션을 사용하면 두 번째 탭에서 링크를 실행할 수 있습니까?
samuelkobe 2015 년

1
아니 그것은 여전히 ​​첫 번째 터치에 대한 클릭을 트리거합니다. 방금 테스트했습니다.
Jack

굉장한 솔루션! 빠르고 쉽습니다.
Hunter Turner

41

이 시도:

<script>
document.addEventListener("touchstart", function(){}, true);
</script>

그리고 CSS에서 :

element:hover, element:active {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none;
-webkit-touch-callout: none /*only to disable context menu on long press*/
}

이 코드를 사용하면 추가 .hover 클래스가 필요하지 않습니다!


1
이것은 나를 위해 작동합니다 .. 더 많은 도움이 될 수있는 다른 것들은 자바 스크립트를 추가하는 대신 다음과 같이하십시오. <body ontouchstart = ""> 그런 다음 css에 작은 타이머를 추가하십시오. : active 이벤트 : tr : active {background-color : # 118aab; 전환 : 모든 .2s 선형; -webkit-tap-highlight-color : rgba (0,0,0,0); -webkit-user-select : 없음; -webkit-터치 선 : 없음}
코지 (Kozy)

나를 위해 일했습니다. 고마워요 ... 단 한가지-약간 늦어집니다 ... 제 말은-눌러도 즉시로드되지 않습니다.
Roman Losev

fastclick.js를 사용하여 지연 제거
Anselm

25

주요 질문에 답하려면 "터치 인 터치 지원 브라우저에서 마우스 오버를 어떻게 시뮬레이션합니까?"

화면을 탭하여 요소를 '클릭'한 다음 hoverJavaScript를 사용 하여 이벤트를 트리거하기 만하면 됩니다.

var p = document.getElementsByTagName('p')[0];
p.onclick = function() {
 // Trigger the `hover` event on the paragraph
 p.onhover.call(p);
};

hover장치에 이벤트 가있는 한 작동 합니다 (일반적으로 사용되지 않더라도).

업데이트 : 방금 iPhone에서이 기술을 테스트했는데 제대로 작동하는 것 같습니다. 여기에서 시도해보세요 : http://jsfiddle.net/mathias/YS7ft/show/light/

대신 '긴 터치'를 사용하여 호버를 트리거하려면 위의 코드 스 니펫을 시작점으로 사용하고 타이머와 물건을 재미있게 사용할 수 있습니다.)


나는 그 onhover.call (p) 비트에 대해 몰랐습니다. 꽤 멋지네요. 그러나 오프 호버가 없습니다 ...
Rich Bradshaw

여러 요소와 긴 터치로 이것을 테스트 했습니까? 사용자가 화면에서 손가락을 움직여 각 요소에 대한 호버 스타일을 표시한다는 의미입니까?
Marcus

이미 jQuery를 사용하고 있다면 jQuery 자체로 hover 이벤트를 호출 할 수 있습니다. 예 : jQuery.hover (); 하지만 API가이를 지원하는지 확실하지 않습니다.
Kzqai 2011

죄송합니다. 실제로 jQuery를 사용하는 위의 게시물에 더 적용 할 수있는 댓글이었습니다.
Kzqai 2011

특별한 스크립팅이 필요하거나 함수를 호출해야합니까? 그것은 나를 위해 작동하지만 한 페이지에서만 작동하며 차이점이 무엇인지 모르겠습니다.
Richard Young

13

더욱 개선 된 솔루션

처음에는 Rich Bradshaw의 접근 방식을 따랐 지만 문제가 나타나기 시작했습니다. 수행하여 e.preventDefault을 ()'touchstart' 이벤트 페이지 더 이상 스크롤 및,도 긴 키를 눌러 옵션 메뉴도 더블 클릭 줌을 발사 할 수있는 실행을 완료 할 수 있습니다.

해결책은 어떤 이벤트가 호출되고 있는지 알아 내고 나중에 'touchend' 에서 e.preventDefault () 만 찾을 수 있습니다 . scroll의 'touchmove''touchend' 보다 먼저 나오므로 기본적으로 유지되며 'click' 도 모바일에 적용되는 이벤트 체인에서 뒤 따르기 때문에 다음 과 같이 금지됩니다.

// Binding to the '.static_parent' ensuring dynamic ajaxified content
$('.static_parent').on('touchstart touchend', '.link', function (e) {

    // If event is 'touchend' then...
    if (e.type == 'touchend') {
        // Ensuring we event prevent default in all major browsers
        e.preventDefault ? e.preventDefault() : e.returnValue = false;
    }

    // Add class responsible for :hover effect
    $(this).toggleClass('hover_effect');
});

그러나 옵션 메뉴가 나타나면 더 이상 'touchend' 가 실행되지 않습니다. 클래스를 토글하는 다음 번에는 호버 동작이 완전히 이 될 것입니다.

그런 다음 해결책은 조건부로 우리가 어떤 이벤트에 있는지 알아 내거나 별도의 이벤트를 수행하고 'touchstart''touchend' 에서 각각 addClass ()removeClass ()를 사용 하여 항상 시작하고 끝나도록하는 것입니다. 조건부로 결정하는 대신 각각 추가 및 제거합니다. 완료하기 위해 제거 콜백을 'focusout' 이벤트 유형에 바인딩하여 다음과 같이 유지되고 다시 방문하지 않을 수있는 링크의 호버 클래스를 지우는 책임을집니다.

$('.static_parent').on('touchstart', '.link', function (e) {
    $(this).addClass('hover_effect');
});

$('.static_parent').on('touchend focusout', '.link', function (e) {
    // Think double click zoom still fails here
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
    $(this).removeClass('hover_effect');
});

주의 : 일부 버그는 이전의 두 솔루션에서 여전히 발생하며 테스트되지 않은 두 번 클릭 확대 / 축소도 여전히 실패한다고 생각합니다.

깔끔하고 희망적으로 버그가없는 (아님 :)) 자바 스크립트 솔루션

이제 두 번째로 깔끔하고 깔끔하며 반응이 빠른 방법으로 자바 스크립트 (.hover 클래스와 의사 : hover를 혼합하지 않음)를 사용하고 범용 (모바일 및 데스크톱) '클릭' 이벤트 에서 ajax 동작을 직접 호출 할 수있는 방법을 사용합니다. , 필연적으로 이벤트 체인에서 서로의 콜백을 변경하지 않고도 터치 및 마우스 이벤트를 함께 혼합 할 수있는 방법을 마침내 이해 한 꽤 잘 대답 된 질문 을 찾았 습니다. 방법은 다음과 같습니다.

$('.static_parent').on('touchstart mouseenter', '.link', function (e) {
    $(this).addClass('hover_effect');
});

$('.static_parent').on('mouseleave touchmove click', '.link', function (e) {
    $(this).removeClass('hover_effect');

    // As it's the chain's last event we only prevent it from making HTTP request
    if (e.type == 'click') {
        e.preventDefault ? e.preventDefault() : e.returnValue = false;

        // Ajax behavior here!
    }
});

3

hover터치 장치에서는 마우스 효과를 구현할 수 없습니다. 내가 CSS에서 safari ios사용 :active했던 것과 같은 상황으로 나타 났을 때 효과를 내었다.

즉.

p:active {
  color:red;
}

제 경우에는 작동합니다. 이것은 자바 스크립트를 사용하여 사용할 수있는 경우 일 수도 있습니다. 시도해보세요.


2

이 코드를 추가 한 다음 이러한 방식으로 작업하려는 요소에 "tapHover"클래스를 설정합니다. 요소를 처음 탭하면 가상 클래스 ": hover"및 클래스 "tapped"가 생성됩니다. 클릭 이벤트가 차단됩니다. 두 번째로 동일한 요소를 탭하면 클릭 이벤트가 발생합니다.

// Activate only in devices with touch screen
if('ontouchstart' in window)
{
    // this will make touch event add hover pseudoclass
    document.addEventListener('touchstart', function(e) {}, true);

    // modify click event
    document.addEventListener('click', function(e) {
        // get .tapHover element under cursor
        var el = jQuery(e.target).hasClass('tapHover')
            ? jQuery(e.target)
            : jQuery(e.target).closest('.tapHover');

        if(!el.length)
            return;

        // remove tapped class from old ones
        jQuery('.tapHover.tapped').each(function() {
            if(this != el.get(0))
                jQuery(this).removeClass('tapped');
        });

        if(!el.hasClass('tapped'))
        {
            // this is the first tap
            el.addClass('tapped');
            e.preventDefault();
            return false;
        }
        else
        {
            // second tap
            return true;
        }
    }, true);
}
.box {
	float:		left;
	
	display:	inline-block;
	margin:		50px 0 0 50px;
	width:		100px;
	height:		100px;
	overflow:	hidden;
	
	font-size:	20px;
	
	border:		solid 1px black;
}
.box.tapHover {
	background:	yellow;
}
.box.tapped {
	border:		solid 3px red;
}
.box:hover {
	background:	red;
}
<div class="box" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
<div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
<div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div>


1

장치 (또는 브라우저) 특정 JS가 없으면 운이 좋지 않을 것입니다.

편집 : 질문을 다시 읽을 때까지 피하고 싶다고 생각했습니다. Mobile Safari의 경우 등록하여 기본 UIView-s로 할 수있는 것과 유사한 모든 터치 이벤트를 얻을 수 있습니다. 지금 문서를 찾을 수 없습니다. 그래도 시도 할 것입니다.


1

이를 수행하는 한 가지 방법은 터치가 시작될 때 호버 효과를 수행 한 다음 터치가 움직이거나 끝날 때 호버 효과를 제거하는 것입니다.

이것은 당신이 iPhone을 언급했기 때문에 Apple이 일반적인 터치 핸들링 에 대해 말한 것 입니다.


링크 내용이 지금도 여전히 관련이 있습니까?
의 Flavien Volken

1

제 개인적인 취향은 다음과 같이 :hover스타일을 :focus주에 부여하는 것입니다.

p {
    color: red;
}

p:hover, p:focus {
    color: blue;
}

그런 다음 다음 HTML을 사용합니다.

<p id="some-p-tag" tabindex="-1">WOOOO</p>

그리고 다음 JavaScript :

$("#some-p-tag").on("touchstart", function(e){
    e.preventDefault();
    var $elem = $(this);

    if($elem.is(":focus")) {
        //this can be registered as a "click" on a mobile device, as it's a double tap
        $elem.blur()
    }
    else {
        $elem.focus();
    }
});

1

해결 된 2019-Hover on Touch

이제 일반적으로 iOS 또는 터치와 함께 호버를 사용하지 않는 것이 가장 좋습니다. 아래 코드는 터치가 유지되고 다른 iOS 플라이 아웃없이 CSS를 적용합니다. 이 작업을 수행;

  1. Jquery 추가 : $ ( "p"). on ( "touchstart", function (e) {$ (this) .focus (); e.preventDefault ();});

  2. CSS : p : hover를 p : focus로 바꾸고 p : active 추가

옵션;

  • jquery p 선택기를 모든 클래스 등으로 교체

  • 효과를 유지하려면 p : hover도 유지하고 body {cursor : ponter;}를 추가하여 아무 곳이나 탭하면 끝납니다.

  • 동일한 코드에서 클릭 및 마우스 오버 이벤트와 터치 스타트를 시도합니다 (테스트되지 않음).

  • 제거 e.preventDefault (); 사용자가 iOS 플라이 아웃 (예 : 복사)을 활용할 수 있도록하기 위해

노트

  • 텍스트 요소에 대해서만 테스트되었으며 iOS는 입력 등을 다르게 처리 할 수 ​​있습니다.

  • Safari 또는 Chrome을 사용하여 iphone XR ios 12.1.12 및 ipad 3 ios 9.3.5에서만 테스트되었습니다.


0

네이티브 자바 스크립트와 jQuery의 혼합 :

var gFireEvent = function (oElem,sEvent) 
{
 try {
 if( typeof sEvent == 'string' && o.isDOM( oElem ))
 {
  var b = !!(document.createEvent),
     evt = b?document.createEvent("HTMLEvents"):document.createEventObject();
  if( b )    
  {  evt.initEvent(sEvent, true, true ); 
    return !oElem.dispatchEvent(evt);
  }
  return oElem.fireEvent('on'+sEvent,evt);
 }
 } catch(e) {}
 return false;
};


// Next you can do is (bIsMob etc you have to determine yourself):

   if( <<< bIsMob || bIsTab || bisTouch >>> )
   {
     $(document).on('mousedown', function(e)
     {
       gFireEvent(e.target,'mouseover' );
     }).on('mouseup', function(e)
     {
       gFireEvent(e.target,'mouseout' );
     });
   }

1
현학적으로 미안하지만 jquery는 javacript입니다
matpol

2
@matpol : jQuery는 javascript이지만 javascript는 jQuery가 아닙니다. 당신을 위해 특별한 단어 '순수', 순수 자바 스크립트를 추가합니다. 만족하십니까?
Codebeat 2013

'순수한'자바 스크립트를 사용하지 않고는 jquery를 사용할 수 없습니다. 나는 자주하는 사람들이 이것을 알지 못하는 것처럼 보이기 때문에 요점을 지적합니다.
matpol

5
네이티브 자바 스크립트와 jQuery의 혼합, 만족하십니까?
Codebeat 2013

0

내가 찾은 가장 쉬운 해결책 : : hover css 규칙이있는 <span> 태그가 있습니다. <a href = "javascript : void (0)"> 및 voilà로 전환했습니다. iOS의 호버 스타일이 작동하기 시작했습니다.


0

CSS를 사용하여 숨겨진 링크에 포커스 및 활성 (IE7 이하의 경우)을 추가 할 수도 있습니다. 클래스 메뉴가있는 div 내부의 ul 메뉴 예 :

.menu ul ul {display:none; position:absolute; left:100%; top:0; padding:0;}
.menu ul ul ul {display:none; position:absolute; top:0; left:100%;}
.menu ul ul a, .menu ul ul a:focus, .menu ul ul a:active { width:170px; padding:4px 4%; background:#e77776; color:#fff; margin-left:-15px; }
.menu ul li:hover > ul { display:block; }
.menu ul li ul li {margin:0;}

늦고 테스트되지 않았으며 작동해야합니다 ;-)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.