Smooth Scroll (スムーススクロール)、Androidで重い問題。
あけましておめでとうございます!
一発目の記事です。
ということで本記事のタイトル通り、【Smooth Scroll(スムーススクロール)、 Androidで重い問題】についてみていきたいと思います。
よろしくお願いします。
以下のサイトのソースを基にみていきたいと思います。
引用ソース
$(function(){ $('a[href^="#"]').click(function(){ var speed = 500; var href= $(this).attr("href"); var target = $(href == "#" || href == "" ? 'html' : href); var position = target.offset().top; $("html, body").animate({scrollTop:position}, speed, "swing"); return false; }); });
このままだと一部、Androidでスムーズに動かないことがあります。(iPhoneは比較的スムーズ)
例えば、画像リンク→ページ内遷移(スムーススクロール)→ページ下部へみたいな動きのときはもっさり感が半端ない。
原因と解決策
なぜこんなにもっさりしているのか...
それは..
Click イベントを使ってるから!
前も言ったかもしれませんが(言ってないかもしれません)モバイルブラウザにおけるclickイベントってかなり重いです。
理由は、Touchイベント,Mouseイベント,Keyboardイベントなど、これらのイベントをすべてclickイベントでは、網羅してしまっているからです。
結果、処理に時間がかかってしまうんですねー。
逆にアクセシビリティ対応をするのであれば、clickってかなり便利だったりするけど...。
(それぞれの処理に対してハックする必要がないので)
解決策ソース:モバイル向け!
$(function(){ // イベント登録 $('a[href^="#"]').on('touchstart touchmove touchend', function(event){ // タッチスタートでフラグを設定 if ('touchstart' == event.type){ $(this).attr('data-touchstarted', ''); return; } // タッチムーブが発生したら、フラグを消す。(タップと判定させない為) if ('touchmove' == event.type){ $(this).removeAttr('data-touchstarted'); return; } // タッチエンド時にフラグがあれば、タップと判定する。 if ('undefined' != typeof $(this).attr('data-touchstarted')){ var speed = 500; var href= $(this).attr("href"); var target = $(href == "#" || href == "" ? 'html' : href); var position = target.offset().top - 20; $("html, body").animate({scrollTop:position}, speed); // フラグを削除 $(this).removeAttr('data-touchstarted'); return false; } }); });
touchstart touchmove touchendをそれぞれバインドさせ、
タッチスタート=タッチエンドの時をユーザーがタップしたと判定させ動かしています。
結構、昔から使っている手法だけど、改めて共有ということで...。
PCに対応させたいときは、UA判定で分けてもいいかもですね。
それでは、この辺で。