• カミナリツイッターカミナリtwitter
  • カミナリフェイスブックカミナリfacebook
  • カミナリインスタグラムカミナリinstagram

山陰の情報を発信するカミナリ

ナビ

29

NOVEMBER

ウェブTUESDAY 2016 / 11 / 29

iOSでは:hoverがかかっている要素へのリンクを開くのに2タップ要する問題への解決法

iOSのブラウザ(Safari および Chrome)なのですが、マウスカーソルが重なった際の擬似クラス :hover と、その際のエフェクトで透過をかける opacityプロパティの組み合わせを使用すると、

 1回目のタップ: opacityの透過効果が表示
 2回目のタップ: リンク先にジャンプ

といった動作になります。
(実はこのサイトもそうなのですが、そうしないとスマホからいいねの数がわからないのであえて残しています)

 

で、iOS9以降「直った!」という声がウェブ上では散見されるのですが、ボクのiPhone6で試したところ、最新の iOS10 でもこの症状が発生し続けています。

どうも単純な構成の場合は直っているようなのですが、ちょっと複雑な構成に :hover を付与すると症状が発生するようです。

 

対応策として下記のような JavaScript のコードを書きました(要jQuery)。

(function($){
  // 1回のタップでリンクが開けない問題への対応
  var $w = $(window), $target = $('a');
  $target.on('touchstart', function(){
    var $this = $(this), isScrolling = false;
    $w.on('scroll', function(){
      isScrolling = true;
    });
    $this.on('touchend', function(){
      if(!isScrolling){
        var url = $this.find('a').attr('href');
        if(url){
          window.location.href = url;
        }
      }
      isScrolling = false;
      $this.off('touchend');
    });
  });
})(jQuery);

何をしているかというと、タップした!、というイベント情報が正しく取得できないためこの症状が起きていますので、代わりに
 touchstart : 画面に指を置いたよ!、というイベント
 touchend  : 画面から指を離したよ!、というイベント
の2つを用いて判断しています。

 

touchstart から touchend の間に画面がスクロールしたのであれば、

「あ、この操作は画面をスクロールさせたかったのであって、タップしたのではないんだな」

と判断してリンク先は開きません。

 

スクロールせずに同じところで touchstart と touchend が発生したのであれば、

「あ、この操作はタップしたいということなんだな」

ということでリンク先を開きます。

※ 実際に使用する際は, $target = $(‘a’) となっている箇所で、もうちょい範囲を絞ったセレクタにしてください。

 

このコードはキッチンおかださんの商品一覧ページで使用しています。

 

松本博之隠しプロフィール画像

TEXT by

松本 博之まつもとひろゆき)

1978年、鳥取県米子市生まれ。
株式会社マジックワード WEBシステムの開発・運用を担当。

この人が書いた他の記事を読む