少しスクロールするとふわっと表示されてクリックするとページ上部にひゅ〜んとスムーススクロールするボタンを実装する機会結構ありますよね?
で、jQueryで$(window).on('scroll', function〜
でスクロール量が○○以上になったらfadeInして〜とかやると思うのですが、何もしないとスクロールのたびにものすごい数処理が走ってしまいます。
なので、何らかの方法でスクロールイベントの負荷軽減をしつつ実装するかと思うのですが、その方法を少し比較しつつ実際に使えるコードとして残しておきたいと思います。
デモの右下に表示されているボタンがそれぞれ
(1) 負荷軽減なし
(2) setTimeout使う
(3) _.throttle関数使う
になっています。
setTimeoutを使う
var timer = null;
$(window).on('scroll',function() {
clearTimeout( timer );
timer = setTimeout(function() {
if ($(this).scrollTop() > 300) {
$('.pagetop2').fadeIn(200);
} else {
$('.pagetop2').fadeOut(200);
}
}, 200);
});
デモの(2)の動きです。setTimeoutで予約したミリ秒内経つまでは、clearTimeoutで予約取り消し続けて、指定ミリ秒立ったら中の処理が実行されるみたいな感じで負荷軽減するパターン。
今回の処理で使うとちょっと表示されるまでの時間がもっさりしすぎてる気がする。
lodash(プラグイン)の_.throttle関数使う
https://lodash.com/docs/4.17.4#throttle
scrollイベント中に一定間隔で処理を実行してくれるやつ
デモ(3)の動きです。
https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js
ヘッダーでlodash.min.jsを読み込んで配布先のDocumentationを参考に以下のように設定しました。
$(window).on('scroll', _.throttle(updatePosition, 250));
function updatePosition() {
if ($(this).scrollTop() > 300) {
$('.pagetop3').fadeIn(200);
} else {
$('.pagetop3').fadeOut(200);
}
}
アニメーションの動きはスムーズですね。
イベント発火回数を比較してみる
ウィンドウサイズを780px×588pxぐらいにして、一番下までスクロールしてまた上に戻るという動作で、
$(window).on('scroll', 〜
の中の「ボタン表示/非表示をスクロール量で判定する」イベントが何回呼ばれたかを、 console.count();
で比較してみました。
スクロールするスピード等で多少前後するとは思いますが、やはり何もしないとすごい回数呼ばれますね。
_.throttle関数を使ってスムーススクロールするボタンを実装してみる
比べてみた結果、lodashの_.throttle関数使う方法が負荷を軽減しつつストレスなく表示できそうなので、こちらを使ってページ上部にスムーススクロールするボタンを作りたいと思います。
<a class="pagetop" href="#" style="display:none;">↑</a>
こちらのaタグにイベントを当てます。
CSSのposition: fixed;
で画面の右下に配置して最初は非表示にしておきます。
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js'></script>
必要なjsを読み込みます。2つめのjquery.easing.min.jsはイージングのアニメーションに'easeOutExpo'
使いたかったので読み込んでますが、jQueryにもともと入ってるlinear
、swing
を使うのであれば読み込む必要ありません。
jsのコードは以下の様な感じです。
$(function() {
// 300px下にスクロールしたらボタンを表示する
function updatePosition() {
if ($(this).scrollTop() > 300) {
$('.pagetop').fadeIn(200);
} else {
$('.pagetop').fadeOut(200);
}
}
// スクロール中250ミリ秒ごとにupdatePosition実行
$(window).on('scroll', _.throttle(updatePosition, 250));
// .pagetpoを押すと上にスムーススクロールさせる
$('.pagetop').on('click', function(e){
e.preventDefault();
$('html, body').animate({
scrollTop: 0
}, 800, 'easeOutExpo');
});
});
lodashほかにも色々あるので勉強してみようと思います。