jquery.slim版のために、ネイティブJSで動く自動スクロールを作ってみた

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、現在はReactJSなどの出現によって少し人気を落としていると思われるjQueryですが、開発は継続中で現在の最新バージョンは3.3.1(2018/03/27現在)となっています。

しかも、バージョンが3.0からは必要最低限の機能だけを使えるjquery.slimバージョンも公開されていて、SEOに重要と言われる表示速度の高速化に有効な手段となっています。

ちなみに、このslimバージョン。何が違うかというと、通常版にある以下2つが使えなくなっています。

  • ajax ・・・ そのままajax通信
  • effects ・・・ 移動とか透明とかのエフェクト

正直なところ、現在私の開発ではメインJSは「vue」に置き換わってしまってますし、ajaxは「axios」なので、もうjquery自体を使わない方向に向かってはいます。だけど、やっぱりbootstrap(jquery必須)が使いたい場面が多いので、せめてjquery.slimバージョンに置き換えてみることにしました。

bootstrap(ver 4.0)でやってみたところ、嬉しいことにnavbarやcollapseなどはjquery.slimで動くようでしたが、一点だけどうしても使いたい機能を失っていることに気がつきました。

それが、

$.animate();

です。

これは、他のサイトでもよく実装されているクリックすると自動で一番上までスクロールしてくれるボタンなどに利用されてる便利な関数です。

でも、これは「effects」の機能なのでslim版には入っていません。
ということで、この部分だけはなんとかネイティブJavaScriptで実装することにしました。

以下は、vue.js版ですけど、moveToTop()を抜き出せばどんな環境でも動くと思います。

※ちなみにアロー関数を使ってるのでIEとかは微妙かもしれません。functionを使うことも考えましたけど、開発者としては、こうやって一刻も早くIEを駆逐したいんです(笑)

<html>
<body>
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<div id="app">
    <div v-for="i in 100" v-text="i"></div>
    <button style="position:fixed;right:15px;bottom:15px;" class="btn btn-primary" @click="moveToTop(500)">上へ</button>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.min.js"></script>
<script>

    new Vue({
        el: '#app',
        methods: {
            moveToTop(duration) {
                let interval = 10;
                let scrollX = window.scrollX;
                let scrollY = window.scrollY;
                let step = Math.ceil(scrollY / (duration / interval));
                let timer = setInterval(() => {

                    if(window.scrollY > 0) {

                        scrollY -= step;
                        window.scrollTo(scrollX, scrollY);

                    } else {

                        clearInterval(timer);

                    }

                }, interval);
            }
        }
    });

</script>
</body>
</html>

関数版はこちら。

moveToTop(duration) {
    let interval = 10;
    let scrollX = window.scrollX;
    let scrollY = window.scrollY;
    let step = Math.ceil(scrollY / (duration / interval));
    let timer = setInterval(() => {

        if(window.scrollY > 0) {

            scrollY -= step;
            window.scrollTo(scrollX, scrollY);

        } else {

            clearInterval(timer);

        }

    }, interval);
}

あと、もしもっと負荷を軽減したい場合は、intervalのミリ秒を増やしてみて下さい。どれほど効果があるかは分かりませんけど多少はマシになるかもです。

終わりに

bootstrapをvueに移植したBootstrap + Vueというパッケージもあるんですけど、できれば本家でもやってほしいですね。でもやるとしても、ReactJSかangularが先なのかな。

これからももっとvueJSの人気が上がってくれることを期待したいと思います。

ではでは〜。

このエントリーをはてなブックマークに追加       follow us in feedly  
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ