29
NOVEMBER
ウェブTUESDAY 2016 / 11 / 29
iOSでは:hoverがかかっている要素へのリンクを開くのに2タップ要する問題への解決法
Text by Hiroyuki Matsumoto
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システムの開発・運用を担当。
WordPressの実績多数。表面的な使用方法を把握するだけでなく、WordPressのソースコードを読み解いて対応できます。
国家資格の応用情報処理技術者をなんとなくとりました。