IT

iPhone/iPad 사용자에 대해 :hover 유사 클래스를 강제로 무시할 수 있습니까?

itgroup 2023. 8. 21. 21:05
반응형

iPhone/iPad 사용자에 대해 :hover 유사 클래스를 강제로 무시할 수 있습니까?

나는 내 사이트에 확장되는 몇몇 css 메뉴들이 있습니다.:hover 없음js 없음)

iDevices에서 깨지는 합니다. 를 들어 iDevices의 는이된방작다동니합로식이 됩니다. 예를 들어 탭을 누르면 활성화됩니다.:hover메뉴가 .:hover 요소 가 존재하는 :hover'ed, 링크를 활성화하려면 두 번 탭해야 합니다(첫 번째 탭 트리거).:hover두 번째 탭 트리거 링크).

나는 iphone에서 일을 잘 처리할 수 있도록 바인딩했습니다.touchstart이벤트

문제는 때때로 모바일 사파리가 여전히 트리거를 선택한다는 것입니다.:hover나의 것 대신에 css로부터 규칙.touchstart이벤트!

내가 모든 것을 비활성화할 때 이것이 문제라는 것을 알고 있습니다.:hoverCSS에서 수동으로 규칙, 모바일 사파리는 잘 작동합니다(그러나 일반 브라우저는 더 이상 작동하지 않습니다).

"취소"할 수 있는 ?:hover사용자가 모바일 사파리에 있을 때 특정 요소에 대한 규칙?

여기서 iOS 동작을 보고 비교하십시오. http://jsfiddle.net/74s35/3/ 참고: 일부 CSS 속성만이 두 번 클릭 동작을 트리거합니다. 예를 들어, display:display; background:red; 또는 text-decoration: 밑줄;

iPhone/iPad Safari에서는 ":hover"를 예측할 수 없습니다.때때로 요소를 누르면 해당 요소가 ":호버"가 되는 반면, 다른 요소로 이동합니다.

당분간은 그냥 몸에서 '노터치' 수업이 있어요.

<body class="yui3-skin-sam no-touch">
   ...
</body>

그리고 ":hover"가 ".no-touch" 아래에 있는 모든 CSS 규칙:

.no-touch my:hover{
   color: red;
}

페이지 어딘가에 본문에서 no-touch 클래스를 제거하는 Javascript가 있습니다.

if ('ontouchstart' in document) {
    Y.one('body').removeClass('no-touch');
}

완벽해 보이지는 않지만 어쨌든 효과가 있습니다.

:hover여기서 문제가 아닙니다.규칙을 .OS용 Safari는 매우 이상한 규칙을 따릅니다.은 발사합니다.mouseover그리고.mousemove된 사항이 하지 않습니다. 즉, '클릭', '클릭', '클릭'입니다.

Diagram of touch event in iOS

mouseenter그리고.mouseleave포함된 것으로 보이지만 차트에는 명시되어 있지 않습니다.

이러한 이벤트의 결과로 수정하면 클릭 이벤트가 실행되지 않습니다.여기에는 DOM 트리의 상위 항목이 포함됩니다.예를 들어, 이렇게 하면 jQuery를 사용하여 웹 사이트에서 한 번의 클릭으로 작업할 수 없습니다.

$(window).on('mousemove', function() {
    $('body').attr('rel', Math.random());
});

을 위해, : jQuery'shover에는 이트포함이 포함됩니다.mouseenter그리고.mouseleave이것들은 둘 다 예방할 것입니다.click내용이 변경된 경우

JS, CSS 클래스 및 뷰포트 검사 없이 더 나은 솔루션: 상호 작용 미디어 기능을 사용할 수 있습니다(미디어 쿼리 레벨 4).

다음과 같이:

@media (hover) {
  // properties
  my:hover {
    color: red;
  }
}

iOS Safari에서 지원합니다.

자세한 정보: https://www.jonathanfielding.com/an-introduction-to-interaction-media-features/

브라우저 기능 감지 라이브러리 Modernizer에는 터치 이벤트에 대한 검사가 포함되어 있습니다.

기본 동작은 탐지되는 각 기능에 대해 HTML 요소에 클래스를 적용하는 것입니다.그런 다음 이 클래스를 사용하여 문서 스타일을 지정할 수 있습니다.

되지 않은 은 Modernizr의 할 수 .no-touch:

<html class="no-touch">

그런 다음 이 클래스를 사용하여 호버 스타일의 범위를 지정합니다.

.no-touch a:hover { /* hover styles here */ }

사용자 정의 Modernizr 빌드를 다운로드하여 필요한 만큼의 기능 탐지를 포함할 수 있습니다.

다음은 적용할 수 있는 일부 클래스의 예입니다.

<html class="js no-touch postmessage history multiplebgs
             boxshadow opacity cssanimations csscolumns cssgradients
             csstransforms csstransitions fontface localstorage sessionstorage
             svg inlinesvg no-blobbuilder blob bloburls download formdata">

일부 장치(다른 장치에서 말했듯이)에는 터치 및 마우스 이벤트가 모두 있습니다.예를 들어 Microsoft Surface에는 터치 스크린, 트랙패드 및 화면 위에 호버 이벤트를 실제로 발생시키는 스타일러스가 있습니다.

사용하지 않도록 설정하는 모든 솔루션:hover'터치' 이벤트의 존재에 따라 서피스 사용자(및 기타 유사한 장치)에게도 영향을 미칩니다.많은 새로운 노트북은 터치식이며 터치 이벤트에 반응하므로 호버링을 비활성화하는 것은 정말 나쁜 관행입니다.

이것은 사파리의 버그입니다. 이 끔찍한 행동에 대한 정당성은 전혀 없습니다.저는 iOS Safari의 버그 때문에 iOS 이외의 브라우저를 방해하는 것을 거부하고 있습니다.나는 그들이 다음 주에 iOS8을 위해 이것을 고쳤으면 정말 좋겠지만, 그 동안에...

솔루션:

일부에서는 이미 Modernizr을 사용할 것을 제안했지만, Modernizr을 사용하면 자신만의 테스트를 만들 수 있습니다. 있는 ▁that▁▁supports▁what▁'▁of것추입다ab▁the▁a▁idea▁is니▁doing는제가▁here'st▁i를 지원하는 브라우저의 아이디어를 '추상화'하는 것입니다.:hover하드 코딩 없이 코드 전체에서 사용할 수 있는 Modernizr 테스트로.if (iOS)내내.

 Modernizr.addTest('workinghover', function ()
 {
      // Safari doesn't 'announce' to the world that it behaves badly with :hover
      // so we have to check the userAgent  
      return navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? false : true;
 });

그러면 css는 이렇게 됩니다.

html.workinghover .rollover:hover 
{
    // rollover css
}

iOS에서만 이 테스트가 실패하고 롤오버가 비활성화됩니다.

이러한 추상화의 가장 좋은 점은 특정 안드로이드에서 고장이 나거나 iOS9에서 수정된 경우 테스트를 수정할 수 있다는 것입니다.

페이지에 FastClick 라이브러리를 추가하면 사용자가 클릭하는 위치에 관계없이 모바일 장치의 모든 탭이 클릭 이벤트로 전환되므로 모바일 장치의 호버 문제도 해결해야 합니다.예시로 당신의 바이올린을 편집했습니다: http://jsfiddle.net/FvACN/8/ .

페이지에 fastclick.min.js lib를 포함하고 다음을 통해 활성화합니다.

FastClick.attach(document.body);

부가적인 이점으로, 그것은 또한 모바일 장치가 겪는 클릭 지연의 성가신 300ms를 제거할 것입니다.


FastClick을 사용하면 사이트에 문제가 될 수도 있고 문제가 되지 않을 수도 있는 몇 가지 사소한 결과가 있습니다.

  1. 페이지의 한 부분을 누르고 위로 스크롤하고 다시 아래로 스크롤한 다음 처음에 배치한 위치와 정확히 동일한 위치에서 손가락을 놓으면 FastClick이 "클릭"으로 해석합니다.적어도 제가 현재 사용하고 있는 FastClick 버전(1.0.0)에서는 그렇게 작동합니다.해당 버전 이후로 누군가 문제를 해결했을 수 있습니다.
  2. FastClick은 누군가가 "두 번 클릭"하는 기능을 제거합니다.

기본적으로 세 가지 시나리오가 있습니다.

  1. 사용자는 마우스/포인터 장치만 가지고 있으며 활성화할 수 있습니다.:hover
  2. 사용자는 터치 스크린만 가지고 있으며 활성화할 수 없습니다.:hover
  3. 사용자는 터치스크린과 포인터 장치를 모두 가지고 있습니다.

사용자가 포인터나 터치스크린을 가지고 있는 처음 두 시나리오만 가능한 경우에는 원래 승인된 답변이 잘 작동합니다.이것은 OP가 4년 전에 질문했을 때 흔했습니다.몇몇 사용자들은 Windows 8과 Surface 장치가 세 번째 시나리오를 더 가능성 있게 만들고 있다고 지적했습니다.

터치스크린 장치에 마우스를 올릴 수 없는 문제에 대한 iOS 솔루션(@Zenexer에서 자세히 설명함)은 영리하지만, OP에서 언급한 대로 간단한 코드가 잘못 작동할 수 있습니다.터치 스크린 장치에 대해서만 호버를 비활성화하면 터치 스크린에 친숙한 대안을 코딩해야 합니다.사용자가 포인터와 터치스크린을 모두 가지고 있을 때 감지하면 물이 더 흐려집니다(@Simon_Weaver 설명).

현 시점에서 가장 안전한 해결책은 사용을 피하는 것입니다.:hover사용자가 웹 사이트와 상호 작용할 수 있는 유일한 방법입니다.호버 효과는 링크 또는 단추가 작업 가능함을 나타내는 좋은 방법이지만 사용자가 웹 사이트에서 작업을 수행하기 위해 요소를 호버할 필요는 없습니다.

터치 스크린을 염두에 두고 "호버" 기능을 재고하는 것은 대안적인 UX 접근법에 대해 좋은 논의를 합니다.답변에서 제공하는 솔루션은 다음과 같습니다.

  • 호버 메뉴를 직접 수행으로 바꾸기(항상 표시되는 링크)
  • 온-호버 메뉴를 온-탭 메뉴로 바꾸기
  • 많은 양의 온호버 콘텐츠를 별도의 페이지로 이동

앞으로, 이것은 아마도 모든 새로운 프로젝트를 위한 최고의 솔루션이 될 것입니다.허용된 답변은 차선의 솔루션일 수 있지만 포인터 장치도 있는 장치를 고려해야 합니다.장치에 iOS를 사용하기 위한 터치스크린이 있을 때 기능이 제거되지 않도록 주의하십시오.:hover해킹하다

.css의 JQuery 버전은 .no-touch.my-element:hover를 사용합니다. 모든 호버 규칙에는 JQuery와 다음 스크립트가 포함됩니다.

function removeHoverState(){
    $("body").removeClass("no-touch");
}

그런 다음 본문 태그에서 touchstart="removeHoverState()"에 class="no-touch"를 추가합니다.

온터치 시작이 시작되면 즉시 모든 호버 상태에 대한 클래스가 제거됩니다.

터치를 위해 호버를 비활성화하는 것이 좋은 방법이라는 것에 동의합니다.

의 CSS를 그냥 것이나 .:hover@supports not (-webkit-overflow-scrolling: touch) {}

.hover, .hover-iOS {
  display:inline-block;
  font-family:arial;
  background:red;
  color:white;
  padding:5px;
}
.hover:hover {
  cursor:pointer;
  background:green;
}

.hover-iOS {
  background:grey;
}

@supports not (-webkit-overflow-scrolling: touch) {
  .hover-iOS:hover {
    cursor:pointer;
    background:blue;
  }

}
<input type="text" class="hover" placeholder="Hover over me" />

<input type="text" class="hover-iOS" placeholder="Hover over me (iOS)" />

터치를 사용할 수 없을 때만 호버 효과를 갖는 대신 터치 이벤트를 처리하는 시스템을 개발하여 문제를 해결했습니다.먼저 "탭"("클릭"에 해당) 이벤트를 테스트하기 위한 개체를 정의했습니다.

touchTester = 
{
    touchStarted: false
   ,moveLimit:    5
   ,moveCount:    null
   ,isSupported:  'ontouchend' in document

   ,isTap: function(event)
   {
      if (!this.isSupported) {
         return true;
      }

      switch (event.originalEvent.type) {
         case 'touchstart':
            this.touchStarted = true;
            this.moveCount    = 0;
            return false;
         case 'touchmove':
            this.moveCount++;
            this.touchStarted = (this.moveCount <= this.moveLimit);
            return false;
         case 'touchend':
            var isTap         = this.touchStarted;
            this.touchStarted = false;
            return isTap;
         default:
            return true;
      }
   }
};

그런 다음 이벤트 핸들러에서 다음과 같은 작업을 수행합니다.

$('#nav').on('click touchstart touchmove touchend', 'ul > li > a'
            ,function handleClick(event) {
               if (!touchTester.isTap(event)) {
                  return true;
               }

               // touch was click or touch equivalent
               // nromal handling goes here.
            });

답변에 대해 @Morgan Cheng에게 감사하지만 "터치스타트"(@Timothy Perez 답변에서 가져온 코드)를 얻기 위해 JS 기능을 약간 수정했습니다. 하지만 이를 위해서는 jQuery 1.7+가 필요합니다.

  $(document).on({ 'touchstart' : function(){
      //do whatever you want here
    } });

Zenexer에서 제공하는 응답을 고려할 때 추가 HTML 태그가 필요 없는 패턴은 다음과 같습니다.

jQuery('a').on('mouseover', function(event) {
    event.preventDefault();
    // Show and hide your drop down nav or other elem
});
jQuery('a').on('click', function(event) {
    if (jQuery(event.target).children('.dropdown').is(':visible') {
        // Hide your dropdown nav here to unstick
    }
});

이 방법은 마우스 오버를 먼저 실행한 후 클릭합니다.

인 비활성화 합니다.:hoverSafari의 Safari의 입니다.:hover사용자가 피하는 장치의 화면 너비 위에 있는 이벤트.예:

@media only screen and (min-width: 1024px) {
  .my-div:hover { // will only work on devices larger than iOS touch-enabled devices. Will still work on touch-enabled PCs etc.
    background-color: red;
  }
}

아직 해결책을 찾고 있는 사람은 위의 것들 중 하나라도 효과가 없다면,

이거 해봐요.

@media (hover: hover)
{
    .Link:hover
    {
        color:#00d8fe;
    }
}

이 호버 유사는 포인터가 있는 장치에만 적용되며 .active 클래스만 있는 터치 장치에서는 정상적으로 작동합니다.

화면 크기를 보세요.

@media (min-width: 550px) {
    .menu ul li:hover > ul {
    display: block;
}
}

배치할 코드가 여기 있습니다.

// a function to parse the user agent string; useful for 
// detecting lots of browsers, not just the iPad.
function checkUserAgent(vs) {
    var pattern = new RegExp(vs, 'i');
    return !!pattern.test(navigator.userAgent);
}
if ( checkUserAgent('iPad') ) {
    // iPad specific stuff here
}

언급URL : https://stackoverflow.com/questions/2741816/is-it-possible-to-force-ignore-the-hover-pseudoclass-for-iphone-ipad-users

반응형