:active疑似クラスはモバイルサファリでは機能しません


109

iPhone / iPad / iPod上のWebkitでは、<a>タグを:active疑似クラスに指定しても、要素をタップしてもトリガーされません。これをトリガーするにはどうすればよいですか?コード例:

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

回答:


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

すべてのボタン要素がページ上のすべてのボタンを修正するようではなく、1回だけ適用されました。あるいは、「Fastclick」と呼ばれるこの小さなJSライブラリを使用することもできます。タッチデバイスでのクリックイベントを高速化し、この問題も処理します。


19
ontouchstartなしで単に追加するだけで十分ではない=""ですか?(HTML5)
feklee

2
今後の読者のために、私はここにデモを投稿しました:http : //jsbin.com/EjiWILe/3/。iOSデバイスの機能を確認します。
mhulse

6
空のリスナーをボディに適用した理由を説明できますか?どのように機能しますか?
Maurizio Battaghini 2014年

2
私は:focusを使用していましたが、これもそのように機能します。魔法をありがとう。
TecBrat 2015

この方法を使用してiOS 9.1および9.3でページがフリーズします...これらのバージョンにはjsバグがありましたが、それらのOSには0.5%のユーザーがいます
Ruskin

55

他の回答が述べているように、iOS Safariは:active、タッチイベントが要素にアタッチされていない限り、疑似クラスをトリガーしませんが、これまでのところ、この動作は「魔法」でした。私はそれを説明するSafari Developer Libraryでこの小さな言い回しに遭遇しました(強調は私のものです):

-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イベントが設定されている場合(それが空であっても)は、タッチイベントに反応するようブラウザに明示的に指示しています。

私の意見では、これは欠陥のある動作であり、おそらく「モバイル」Webが基本的に存在しなかったとき(リンクされたページのスクリーンショットを見て、私が何を意味するかを確認してください)に遡り、すべてがマウス指向でした。Androidなどの他の新しいモバイルブラウザーでは、タッチ時に「:active」疑似状態が正常に表示され、iOSに必要なハッキングのようなことはありません。

(補足:iOSで独自のカスタムスタイルを使用する場合は、上記の同じリンクされたページで説明されているように、CSSプロパティ:activeを使用して、iOSが疑似状態の代わりに使用するデフォルトの灰色の半透明ボックスを無効にすることもでき-webkit-tap-highlight-colorます。 。)


いくつかの実験の後、すべてのタッチイベントがバブルする要素にontouchstartイベントを設定するという予想されるソリューションは、完全には機能しません。ページの読み込み時に要素がビューポートに表示されている場合、要素は正常に機能しますが、ビューポートの外にある要素を下にスクロールしてタップしても、本来のように疑似状態がトリガーされませ。したがって、代わりに<body>:active

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

(jQueryを使用して)本体までバブリングするイベントに依存するのではなく、すべての要素にイベントをアタッチします。

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

ただし、これによるパフォーマンスへの影響は認識していません。注意してください。


編集:このソリューションには重大な欠陥が1つあります:active。ページのスクロール中に要素に触れても、疑似状態がアクティブになります。感度が強すぎる。Androidは、状態が表示される前に非常に小さな遅延を導入することでこれを解決します。状態が表示されると、ページがスクロールされるとキャンセルされます。これを踏まえて、私はこれを特定の要素でのみ使用することをお勧めします。私の場合、基本的にページをナビゲートしてアクションを送信するためのボタンのリストであるフィールドで使用するためのWebアプリを開発しています。場合によっては、ページ全体がほとんどボタンになるため、これは私にとっては機能しません。ただし、:hover代わりにこれを埋めるために疑似状態を設定できます。デフォルトの灰色のボックスを無効にすると、これは完全に機能します。


6
方法だけでなく、理由についての素晴らしい説明!ありがとう!
coderfin 2016年

6
単なる「魔法の」レシピではなく、開発者に理解を与えることに賛成。これは他のものより無限に有益です。これを書いてくれてありがとう。
user508633

詳細な説明と警告に賛成。これが正解です。
アヒルのマスター

39

<a>タグにontouchstartのイベントハンドラーを追加します。これにより、CSSは魔法のように動作します。

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

3
これは古い答えですが、なぜこれが機能するのですか?私は理由として「魔法のように」気にしませんが、それが機能する理由を説明できれば、詳細を読みたいと思います。
mhulse 2013

1
@mhulse私もその理由を知りたいです。
Jesse Rusak 2013

ハ!私たちは同じ船に乗っています。私はいくつかの調査を行い、この件に関する(半)公式ドキュメントへのリンクをここに投稿してみます。このテクニックがうまくいくのが大好きですが、なぜなのでしょうか。
mhulse 2013

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

疑似クラスをすべて使用していますか、それとも1つだけですか?2つ以上使用している場合は、それらが正しい順序になっているか、すべて壊れているかを確認してください。

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

..この順序で。また、単に:activeを使用している場合は、スタイルを設定していなくても、:: linkを追加します。


疑似クラスをスタイリングするときに順序が重要であるという素晴らしいヒント。
brianarpie 2017

1

この問題を解決するツールを公開しました。

表面的には問題は単純に見えますが、実際には、タイムアウト機能や「リンクのリストをスクロールしたときに何が起こるか」、「リンクを押してから何が起こったときに起こるか」など、タッチとクリックの動作をかなりカスタマイズする必要がありますマウス/指をアクティブ領域から離してください」

これは一度にそれをすべて解決するはずです:https : //www.npmjs.com/package/active-touch

:activeスタイルを.activeクラスに割り当てるか、独自のクラス名を選択する必要があります。デフォルトでは、スクリプトはすべてのリンク要素で機能しますが、独自のセレクター配列で上書きできます。

正直で役立つフィードバックと貢献に感謝します!


2
そのライブラリは、すべてのリンク要素に9(非パッシブ)イベントリスナーを追加しますが、removeEventListenerを呼び出しません。これは、単一ページアプリケーションの大きな欠陥になると思います
Drenai

1
ライアンに感謝します。私はこのコードを1年以上サポートまたは使用していません。落とします。いくつかの検討と実験を行った後、ブラウザーでは考慮されなかった、または考慮されなかった相互作用を強制するのではなく、アプリのデザインを変更しました。
dmitrizzle 2018年

1

ontouchstartを使いたくない人のために、あなたはこのコードを使うことができます

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

1

私はこの答えとその変形を試しましたが、確実に機能するようには見えませんでした(そして、私はこのようなもののために「魔法」に依存することを嫌います)。そこで、代わりに次のようにしました。これは、Appleだけでなく、すべてのプラットフォームで完全に機能します。

  1. 以前使用され:activeていたcss宣言の名前が変更されました.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 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.