<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=902661326467941&ev=PageView&noscript=1" />

スクロールイベントやマウスホイールイベントをlodashのthrottleで間引いていい感じにしよう

まろ


スクロールイベントやマウスホイールイベントをlodashのthrottleで間引いていい感じにしよう

こんにちは、まろCです。

今日は、スクロールでギュインギュイン動くサイトを作るときに、そのイベントの制御をうまいことやってみようという記事になります。

※以降イベントはスクロールインベントまたはマウスホイールイベントとして記述していきます。

▼目次

イベントの問題点

通常、scrollやmousewheelをaddEventListenerすると、そのイベントごとに処理が走ります。デュルルルって移動させると、そのデュルルルの間に20回くらい処理が走ることになります。

それはブラウザにとって負担になりますし、処理自体が何度も走ることで意図しない動きが発生します。つまり、バグってるなと思われて、ディレクターやデザイナー、そのサイトを見ている全ての人々に“伝わらないサイト”として認定されてしまします。

そうなったら悲しみです。得るはずだった喜びが全て深い深い闇に消え、それを救い出す方法さえも見つけられないまま過ごす日々に生きがいを見出すことができるのでしょうか?

throttle

あなたの素晴らしい日々を救い出す方法を紹介しましょう。

イベントをひとつにする、throttle というワードです。連続して起こるイベントを制御して、たとえば最初の1回処理を走らせたら、あるいは走らせている間は、次に発生する同じ処理を実行しないということです。

これを「間引く」といいます。イベントを間引くことで闇を光に変える手助けができるわけです。

lodashのthrottleが有能

「間引く」には、lodashのthrottle関数が超有能です。イベントで起こる処理を何秒間引く、ということを簡単に制御できるからです。

ここからダウンロードしましょう。
https://lodash.com/

1
2
3
4
5
6
7
8
9
10
11
this.$container = document.getElementById('js-main');
        this.$container.addEventListener('mousewheel', _.throttle((e)=&amp;gt;{
            e.preventDefault();
            //ブラウザ固有のイベント名称は省略しております。
            if(e.deltaY &amp;lt; 0) {
                console.log('scroll up', e);
            } else if(e.deltaY &amp;gt; 0) {
                console.log('scroll down', e);
            }
            return false;
        }, 2000, { trailing: false, leading: true }));

これがコードになります。

スクロールすると次のシーンに行く、全画面のサイトをイメージしてください。一度イベントを実行すると、2000ミリ秒は同じ処理は走らない、というコードになります。

闇に堕ちるコード

スクリーンショット 2017-10-07 11.18.02

こちらの画像のように、下にスクロールしようとすると、連続して処理が走ります。

光が射し込むコード

スクリーンショット 2017-10-07 11.17.03

こちらの画像のように、下にスクロールしようとすると、一度だけ処理が走っています。これで、コードのように2000ミリ秒はイベントが発生しても何も起こらないで、次のシーンにいくアニメーションに専念できるわけです。

1
{ trailing: false, leading: true }

処理を最初に行って、時間まで間引くなら上記のオプションが調子いいです。

1
{ trailing: true, leading: false }

時間まで間引いたあと、処理を行うなら、上記のオプションで調子があがります。

まとめ

いかがでしたか。
あなたが闇に堕ちる前にこの記事に出合っていただけたのであれば、幸いです。
それでは。

まろ
この記事を書いた人
まろ

フロントエンドエンジニア