: 활성 가상 클래스가 모바일 사파리에서 작동하지 않습니다.


109

iPhone / iPad / iPod의 Webkit에서 <a>태그 의 : active 의사 클래스에 대한 스타일 지정 은 요소를 탭할 때 트리거되지 않습니다. 이것을 트리거하려면 어떻게해야합니까? 예제 코드 :

<style> 
a:active { 
    background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>

답변:


238
<body ontouchstart="">
    ...
</body>

모든 버튼 요소가 페이지의 모든 버튼을 수정하는 것과 달리 한 번만 적용되었습니다. 또는 ' Fastclick ' 이라는 작은 JS 라이브러리를 사용할 수 있습니다 . 터치 장치에서 클릭 이벤트 속도를 높이고이 문제도 처리합니다.


19
ontouchstart없이 단순히 추가하는 것으로 충분 하지 =""않습니까? (HTML5)
feklee

2
향후 독자를 위해 http://jsbin.com/EjiWILe/3/에 데모를 게시했습니다 . iOS 장치의 기능을 확인하십시오.
mhulse

6
왜 빈 청취자를 몸에 적용했는지 설명 할 수 있습니까? 어떻게 작동합니까?
Maurizio Battaghini 2014 년

2
나는 : focus를 사용하고 있었고 이것도 작동합니다. 매직에 감사드립니다.
TecBrat

이 방법을 사용하여 iOS 9.1 및 9.3에서 페이지 정지가 발생합니다. 해당 버전에는 js 버그가 있었지만 여전히 해당 OS에 0.5 %의 사용자가 있습니다
Ruskin

55

다른 답변에서 언급했듯이 iOS Safari는 :active터치 이벤트가 요소에 연결되지 않는 한 의사 클래스를 트리거하지 않지만 지금까지이 동작은 "마 법적"이었습니다. 나는 그것을 설명 하는 Safari 개발자 라이브러리 에서이 작은 설명을 발견했습니다 (강조).

또한 -webkit-tap-highlight-colorCSS 속성을 터치 이벤트 설정과 함께 사용하여 버튼이 데스크탑과 유사하게 작동하도록 구성 할 수 있습니다. iOS에서는 마우스 이벤트가 너무 빨리 전송되어 다운 또는 활성 상태가 수신되지 않습니다. 따라서 :active의사 상태는 HTML 요소에 터치 이벤트가 설정된 경우에만 트리거됩니다 (예 : 요소에 ontouchstart가 다음과 같이 설정된 경우).

<button class="action" ontouchstart=""
        style="-webkit-tap-highlight-color: rgba(0,0,0,0);">
    Testing Touch on iOS
</button>

이제 iOS에서 버튼을 누르고 있으면 주변의 투명한 회색 색상이 나타나지 않고 버튼이 지정된 색상으로 변경됩니다.

즉, ontouchstart이벤트를 설정하는 것은 (비어 있더라도) 브라우저가 터치 이벤트에 반응하도록 명시 적으로 지시하는 것입니다.

제 생각에는 이것은 결함이있는 행동이며, 아마도 "모바일"웹이 기본적으로 존재하지 않았던 때로 거슬러 올라갑니다 (링크 된 페이지의 스크린 샷을 보시고 제가 의미하는 바를 확인하십시오). 모든 것이 마우스 지향적이었습니다. Android와 같은 다른 최신 모바일 브라우저는 iOS에 필요한 것과 같은 해킹없이 터치시`: active '의사 상태를 잘 표시한다는 점이 흥미 롭습니다.

(참고 : iOS에서 사용자 지정 스타일을 사용하려는 경우 위의 동일한 링크 페이지에 설명 된대로 CSS 속성 :active을 사용하여 iOS에서 의사 상태 대신 사용하는 기본 회색 반투명 ​​상자를 비활성화 할 수도 있습니다. -webkit-tap-highlight-color.)


몇 가지 실험 후 모든 터치 이벤트가 버블 링 된 요소에 ontouchstart이벤트를 설정하는 예상 솔루션이 완전히 작동하지 않습니다. 페이지가로드 될 때 요소가 뷰포트에 표시되면 제대로 작동하지만 아래로 스크롤하여 뷰포트를 벗어난 요소를 탭해도 의사 상태가 트리거 되지 않습니다 . 그래서 대신<body>:active

<!DOCTYPE html>
<html><body ontouchstart></body></html>

본문에 버블 링되는 이벤트에 의존하는 대신 모든 요소에 이벤트를 첨부합니다 (jQuery 사용).

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

그러나 나는 이것의 성능 영향을 알지 못하므로 조심하십시오.


편집 : 이 솔루션에는 심각한 결함이 하나 있습니다. 페이지를 스크롤하는 동안 요소를 터치해도 :active의사 상태 가 활성화됩니다 . 감도가 너무 강합니다. Android는 상태가 표시되기 전에 매우 작은 지연을 도입하여이 문제를 해결합니다. 이는 페이지가 스크롤되면 취소됩니다. 이를 고려하여 선택한 요소에만 이것을 사용하는 것이 좋습니다. 제 경우에는 기본적으로 페이지를 탐색하고 작업을 제출하는 버튼 목록 인 현장에서 사용할 웹 앱을 개발 중입니다. 전체 페이지가 어떤 경우에는 거의 버튼이기 때문에 이것은 나를 위해 작동하지 않습니다. 그러나 :hover대신이를 채우기 위해 의사 상태를 설정할 수 있습니다 . 기본 회색 상자를 비활성화하면 완벽하게 작동합니다.


6
방법 뿐만 아니라 이유에 대한 훌륭한 설명 ! 감사!
coderfin 2016 년

6
단지 "마법"레시피가 아니라 개발자에게 이해를주기 위해 찬성했습니다. 이것은 다른 것보다 훨씬 더 많은 정보를 제공합니다. 이 글을 써 주셔서 감사합니다.
user508633

자세한 설명 +주의 사항을 위해 찬성했습니다. 정답이되어야합니다.
Master of Ducks

39

<a> 태그에 ontouchstart에 대한 이벤트 핸들러를 추가하십시오. 이로 인해 CSS가 마술처럼 작동합니다.

<a ontouchstart="">Click me</a>

3
죄송합니다. 이것은 오래된 답변이지만 왜 이것이 작동합니까? 나는 "마 법적으로"이유를 신경 쓰지 않지만 그것이 작동하는 이유를 설명 할 수 있다면 더 자세한 내용을 읽고 싶습니다.
mhulse 2013-08-12

1
@mhulse 나는 또한 이유를 알고 싶습니다.
Jesse Rusak 2013-08-13

하아! 우리는 같은 배에 있습니다. 나는 몇 가지 조사를하고 문제에 대한 (반) 공식 문서에 대한 링크를 여기에 게시하려고 노력할 것입니다. 이 기술이 효과가 있다는 것을 좋아합니다. 이유가 궁금합니다.
mhulse 2013-08-13

7

이것은 나를 위해 작동합니다.

document.addEventListener("touchstart", function() {},false);

참고 :이 트릭을 수행하는 경우 다음 CSS 규칙을 사용하여 Mobile Safari가 적용되는 기본 탭 강조 표시 색상을 제거하는 것도 좋습니다.

html {
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}

5

2016 년 12 월 8 일부터 수락 된 답변 ( <body ontouchstart="">...</body>)은 Safari 10 (iPhone 5s)에서 작동하지 않습니다.이 해킹은 페이지로드시 표시되는 요소에만 적용됩니다.

그러나 다음을 추가합니다.

<script type='application/javascript'>
  document.addEventListener("touchstart", function() {}, false);
</script>

는에 head이제 스크롤 동안 모든 터치 이벤트가 트리거된다는 단점과 함께, 내가 원하는 방식으로 작동하지 :active터치 된 요소에 의사 상태. (이게 문제인 경우 FighterJet의 :hover 해결 방법을 고려할 수 있습니다 .)


4
//hover for ios
-webkit-tap-highlight-color: #ccc;

이것은 나를 위해 작동합니다. 강조하려는 요소의 CSS에 추가하십시오.


3

모든 의사 클래스를 사용하고 있습니까? 아니면 하나만 사용하고 있습니까? 두 개 이상을 사용하는 경우 올바른 순서인지 확인하십시오.

a:link
a:visited
a:hover
a:active

..그와 같은 순서로. 또한 : active를 사용하는 경우 스타일을 지정하지 않더라도 a : link를 추가하십시오.


의사 클래스를 스타일링 할 때 순서가 중요하다는 좋은 팁.
brianarpie 2017-04-12

1

이 문제를 해결할 수있는 도구를 게시했습니다.

표면적으로는 문제가 간단 해 보이지만 실제로는 시간 초과 기능과 "링크 목록을 스크롤 할 때 발생하는 작업"또는 "링크를 누른 후 발생하는 작업"과 같은 작업을 포함하여 터치 & 클릭 동작을 상당히 광범위하게 사용자 지정해야합니다. 마우스 / 손가락을 활성 영역에서 멀리 이동 "

이 모든 것이 한 번에 해결됩니다 : https://www.npmjs.com/package/active-touch

: active 스타일을 .active 클래스에 할당하거나 자신의 클래스 이름을 선택해야합니다. 기본적으로 스크립트는 모든 링크 요소와 함께 작동하지만 자체 선택자 배열로 덮어 쓸 수 있습니다.

정직하고 유용한 피드백과 기여에 감사드립니다!


2
이 라이브러리는 모든 링크 요소에 9 개 (비 수동) 이벤트 리스너를 추가하지만 removeEventListener를 호출하지 않습니다. 이것은 단일 페이지 애플리케이션에 큰 결함이 될 것이라고 생각합니다
Drenai

1
감사합니다 Ryan. 1 년 넘게이 코드를 지원하거나 사용하지 않았습니다. 내가 내려 놓을 게. 몇 가지 생각과 실험을 한 후 브라우저에서 설명하거나 생각하지 않은 상호 작용을 강제하는 대신 앱의 디자인을 변경했습니다.
dmitrizzle

1

ontouchstart를 사용하지 않으려는 경우이 코드를 사용할 수 있습니다.

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

1

나는 이 대답 과 그 변형을 시도 했지만 어느 것도 안정적으로 작동하지 않는 것 같았다 (그리고 나는 이와 같은 것에 '마법'에 의존하는 것을 싫어한다). 그래서 대신 다음을 수행했습니다. 이는 Apple뿐 아니라 모든 플랫폼에서 완벽하게 작동합니다.

  1. 에 사용되었던 CSS 선언의 이름이 변경 :active되었습니다 .active.
  2. 영향을받는 모든 요소의 목록을 만들고 pointerdown/mousedown/touchstart이벤트 처리기를 추가 하여 .active클래스 를 적용 하고 pointerup/mouseup/touchend이벤트 처리기를 제거합니다. jQuery 사용 :

    let controlActivationEvents = window.PointerEvent ? "pointerdown" : "touchstart mousedown";
    let controlDeactivationEvents = window.PointerEvent ? "pointerup pointerleave" : "touchend mouseup mouseleave";
    
    let clickableThings = '<comma separated list of selectors>';
    $(clickableThings).on(controlActivationEvents,function (e) {
        $(this).addClass('active');
    }).on(controlDeactivationEvents, function (e) {
        $(this).removeClass('active');
    });

이것은 약간 지루했지만 이제 Apple OS 버전 간의 손상에 덜 취약한 솔루션이 있습니다. (그리고 누가 이런 속임수를 필요로합니까?)


나는 그것이 질문에 대한 답을 제공한다고 생각합니다. : active 가상 클래스를 모바일 Safari에서 작동시키는 신뢰할 수있는 방법이없는 것 같습니다. 그러나 이것은 내가 제공 한 솔루션을 사용하여 안정적으로 에뮬레이션 할 수 있습니다. 내 앱에서이 작업을 수행했으며 모든 플랫폼에서 완벽하게 작동합니다. 그리고 설명을 통해 코드를 추가했습니다.
daffinm

0

해결책은 다음 :target대신에 의존하는 것입니다 :active.

<style> 
a:target { 
    background-color: red;
}
</style>
<!-- snip -->
<a id="click-me" href="#click-me">Click me</a>

앵커가 현재 URL에 의해 타겟팅되면 스타일이 트리거되며 이는 모바일에서도 강력합니다. 단점은 URL에서 앵커를 지우려면 다른 링크가 필요하다는 것입니다. 완전한 예 :

a:target { 
    background-color: red;
}
<a id="click-me" href="#click-me">Click me</a>
<a id="clear" href="#">Clear</a>


-3

이 질문과 100 % 관련된 것은 아니지만 CSS 형제 해킹을 사용하여이 문제를 해결할 수도 있습니다.

HTML

<input tabindex="0" type="checkbox" id="145"/>
<label for="145"> info</label>
<span> sea</span>

SCSS

input {
    &:checked + label {
      background-color: red;
    }
  }

순수한 html / css 툴팁을 사용하려면

span {
  display: none;
}
input {
    &:checked ~ span {
      display: block;
    }
  }

-6
<!DOCTYPE html>

<html lang="en">

<head>
<meta charset="utf-8">

<title></title>

<style>
        a{color: red;}
        a:hover{color: blue;}
</style>
</head>

<body>

        <div class="main" role="main">
                <a href="#">Hover</a>
        </div>

</body>
</html>

1
FAQ에 따라 서명 및 자기 홍보는 허용되지 않습니다.
LittleBobbyTables-Au Revoir
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.