js・jquery

jquery-numerator.jsで、スクロールするとカウントアップが一瞬止まるのを解消

jquery-numerator.jsって使ったことありますか?

Git hubのページはこれ

使い方は下記のページとかが参考になると思います。調べれば使い方はたくさん出てくるのでそこは問題ないかなと。

https://junpei-sugiyama.com/jquery-numerator-js

少しのコードを書くだけで簡単にカウントアップが実装できるので、会社概要ページとかでよく使ってます。

ただ、「スクロールで要素が表示されたときにカウントアップを開始する」という実装をしたときに、スクロールに合わせて一瞬カウントアップが止まってしまうことがあり、それを解消するコードを書きましたので備忘録。

最初に書いていたコードは下記です。

See the Pen jquery-numerator.js 失敗ver by 東野江里 (@anyxfbuk-the-scripter) on CodePen.

少しわかりずらいかもしれないですが、スクロールに合わせて若干カウントアップがかくつき(止まり)ますね。

これはjquery-numerator.jsのせいではなく、「スクロールで要素が表示されたときにカウントアップ」という部分のjsの書き方に問題があったのですが…

解決するコードを見ていきましょう!

まずはコードから

See the Pen CodePen Home jquery-numerator.js 成功ver by 東野江里 (@anyxfbuk-the-scripter) on CodePen.

  • スクロールする際のカウントアップのカクツキをなくす
  • カウントアップの秒数を各要素のdata-durationで管理する

の2点を改修しました。

解説

html

<p class="js-count">
    <span class="js-num" data-num="1000" data-duration="1000"></span>円ほしい
</p>

js-countクラスが付与されている要素を、JavaScript内で操作対象として指定しています。

<span class="js-num" data-num="1000" data-duration="1000">:
js-numクラスが付与された<span>要素には、カウントアップ対象の数値が記載されています。
data-num="1000"でカウントアップ後の値が1000であることを示し、data-duration="1000"でカウントアップのアニメーション時間が1000ミリ秒(1秒)であることを指定しています。

ちなみに、今回のコードであれば、data-durationは指定しなくても大丈夫です。

js

$(function () {
    $(window).on("load scroll", function () {
        $(".js-count").each(function () {
            var $this = $(this); // 各".js-count"要素を変数に保存
            var txtPos = $this.offset().top; // ".js-count"の位置を取得
            var scroll = $(window).scrollTop(); // 現在のスクロール位置を取得
            var windowHeight = $(window).height(); // ブラウザの高さを取得

            // スクロール位置が指定要素の上に達し、カウントアップがまだ始まっていない場合
            if (scroll > txtPos - windowHeight && !$this.hasClass("counted")) {
                var rounding = $(".js-num", this).attr("data-num").indexOf(".") > -1 ? 1 : 0;
                var duration = $this.attr("data-duration") ? $this.attr("data-duration") : 800;

                // カウントアップの実行
                $(".js-num", this).numerator({
                    easing: "linear", // アニメーションのイージング効果
                    duration: parseInt(duration), // アニメーションの持続時間
                    toValue: $(".js-num", this).attr("data-num"), // カウントアップする最終的な数値
                    rounding: rounding, // 小数点以下の処理(1なら小数点付き、0なら整数)
                });

                // カウントアップが完了したことを示すクラス"counted"を追加
                $this.addClass("counted");
            }
        });
    });
});

1.スクロールイベントの監視:

ページロード時とスクロール時にイベントが発生します。

2.各.js-count要素の位置と状態確認:

  • .js-count要素の位置(txtPos)とウィンドウのスクロール位置(scroll)を比較し、カウントアップが始めるべき位置にスクロールされているかを確認します。
  • 同時に、その要素に既にcountedクラスが付与されているかを確認し、既にカウントアップを行った要素に再度処理が行われないようにしています。

3.カウントアップ処理:

  • まだカウントアップしていない場合、js-num要素のdata-num属性から最終的なカウントアップの値を取得します。
  • data-numの値に小数点が含まれている場合はrounding1に設定し、小数点以下を保持します。そうでない場合はrounding0に設定し、整数値としてカウントアップします。
  • data-durationが指定されている場合はその値を使用し、ない場合はデフォルトの800ミリ秒でアニメーションが行われます。

4.処理完了の記録:

カウントアップが完了すると、countedクラスがjs-count要素に追加されます。これにより、同じ要素に対して二度とカウントアップ処理が実行されないようにしています。

このcountedクラスが指定されることで、同じ要素に対して二度とカウントアップ処理が起こらないので、カクツキを解消することができました。

まとめ

jquery-numerator.jsを使用して、スクロールで要素が表示されたときにカウントアップを開始する、というコードを組む時のカクツキ解消コードを解説しました。

とても便利で実用性のあるライブラリなので、ぜひ使ってみてください。

もしわからないことあれば質問ください!

記事にしてほしい・解説してほしい内容のリクエストもお待ちしています。

プログラミングに興味がある方へ

プログラミングに興味があるけど踏み出すのに勇気がいる…
始めてみたけど進め方がわからない、誰かに質問したい…
ネットの教材は高くて手が出ない…
案件を取ってみたけど納品までたどり着けない…

家庭教師の経験を活かし、そんな方のお手伝いをしたいと思っています。

30万もする悪質で高額なコンテンツマーケティングに騙される前に、相談してみませんか?
相談はもちろん無料です。

こちらから、ぜひお気軽にお問い合わせください。
お仕事のご相談や記事にしてほしい内容のリクエストもお待ちしています!

-js・jquery