JavaScriptを使ったカウントダウンタイマー。
基本的な作り方や設定や終了後のメッセージの表示
通販サイトや各サービスサイト、ランディングページなどで、キャンペーンを開催する時によく残りあと○日○時間○分○秒といったタイマーを動かせることで心理的にユーザーに申込みをしてもらうための施策を取る事があります。
これらはカウントダウンタイマーと呼ばれる事が多いですが、意外とやってみるとそこまで難しいものではなく、ほとんどコピペに近い形でJavaScriptのコードを使えば、あとはhtmlとcss側でデザインを調整するだけで使う事が可能になります。
今回はそんなカウントダウンタイマーを、実践でも使えるようにタイマー時刻が終了したら終了メッセージが表示できる仕様で解説していきたいと思います。
実際のカウントダウンタイマーのコード
では、いつもと同じように実際のコードを見ていきましょう。
htmlとcssはほとんどなく、表示と装飾によるものになり、大切なのはJavaScriptのコードになります。
まずは素のままのカウントダウンタイマーとして見ていきましょう。
htmlのコード
<span id="countdown"></span>
たったこれだけです。span
としていますが、ここは別になんでも問題ありません。p
タグでもdiv
タグでも問題ないですが、CSSの装飾などによってインライン要素の方が良いというケースも多いのでspan
タグにしています。
大事なのは、IDのcountdownとしているところで、これがJavaScriptと連動している必要があります。
これだけだと、本当にカウントダウンタイマーのみの表示になるため、実際に使う際には枠で囲ったりなどレイアウトの調整は必要になってきます。
JavaScriptのコード
こちらが本命というか今回の中心になってくるところです。
const target = new Date("2029/12/31 23:59:59");
const message = "終了しました。"
const elmid = document.getElementById( "countdown" );
const timer = setInterval(function() {
const now = new Date();
const diff = target - now;
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
elmid.innerHTML = days + "日" + hours + "時間" + minutes + "分" + seconds + "秒";
if (diff < 0) {
clearInterval(timer);
elmid.innerHTML = message;
}
}, 1000);
素のカウントダウンタイマーにはなりますが、このコードをコピペすれば、そのまま使えるようになっています。
コードの解説
では、コードをそれぞれ見ていってみましょう。
const target = new Date("2029/12/31 23:59:59");
const message = "終了しました。"
const elmid = document.getElementById( "countdown" );
ここが、期限、終了時のメッセージ、HTMLで使うID名の指定になります。
1行目ではtargetという変数にカウントダウンタイマーの締め切り日を入れ、2行目でタイマー時刻を過ぎ去った場合に表示するメッセージを入れています。
実際に時刻が過ぎたらどういう感じの動きになるかは下記にそれ専用のデモページを作ったのでご確認いただけます。(期限を2020年12月31日に指定しています。)
3行目が、HTMLのID名と連動するところになりますので、先ほどのHTMLのIDとここは統一するようにしましょう。
const timer = setInterval(function() {
const now = new Date();
const diff = target - now;
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
elmid.innerHTML = days + "日" + hours + "時間" + minutes + "分" + seconds + "秒";
ここがカウントダウンタイマーの処理と計算になっています。
1行目のsetIntervalというのが、一定の間隔を置いて繰り返し呼び出したり処理をするものになります。
これを使う事で、毎秒この中の処理を行い続けることでカウントダウンタイマーを表示しているという仕組みになります。
2行目以降がその処理になり、2行目でまず今現在の日時を取得し、それをnowという変数に入れています。
そして、先ほど指定したtargetというタイマーの設定した締切日時から、nowの今の日時までの差を計算してその値をdiffという変数に入れています。この差はミリ秒という単位になります。
その次がそれぞれ出てきた差のミリ秒が、何日、何時、何分、何秒になるのかとい計算をしている箇所になり、その計算した値を、それぞれdays、hours、minutes、secondsの変数に入れています。
ちなみにこのミリ秒から日時や諸々を逆算する計算式はほぼコピペで通じるものになります。(詳しく知りたい方は調べれば多数ミリ秒から逆算して計算する方法などたくさん出てくるかと思います)
それぞれの日、時、分、秒の計算が終われば、最後の行で、HTML側に書き込む処理をしています。elmidというのは、最初で設定したHTML側のIDを取得したものになっています。
innnerHTML
というのが、簡単に言えば指定したhtmlの要素を取得したり書き換えたりする事が可能で、今回はHTMLから取得したcountdownというID名の要素を、=の右側の内容に書き換えるという処理を行っています。
これによって、先ほど計算した残りの日、時、分、秒というのをHTML側に表示することが可能になります。
if (diff < 0) {
clearInterval(timer);
elmid.innerHTML = message;
}
ただこれだけだと、カウントダウンをしてもずっと繰り返されます。
残り1秒、0秒となった後、そのまま放っておくと-1秒、-2秒と進んでしまい、ずっと放置しておくと、最終的には-15日-12時間-35分-53秒といったような逆カウントダウンがずっと進んでしまいます。
そのため、diffの締め切り日時から今の日時の差が0未満となりタイマー時刻を過ぎた時の処理をここで設定します。timerという先ほど設定しているカウントダウンタイマーの処理を停止して、カウントダウンタイマーを表示していたHTMLを、最初に設定した終了した時のmessageに入れた内容を表示する設定にしています。
これによって、残り0秒になるまではカウントダウンを行いつつ、0秒になった際には終了メッセージが表示できるようになります。
}, 1000);
最後のここが、最初のconst timer = setInterval(function() {
という箇所と対になるところですが、この1000という数値が、setInterval
をどの間隔(ミリ秒単位)で繰り返し処理するかを指定します。
上記のコードでは「1000」と指定しているため、1000ミリ秒=1秒ごとに繰り返し処理をするという設定になりますので、毎秒ごとに残り時間が計算され、それをHTMLで表示するという処理が繰り返されるため、見た目上ではカウントダウンが進んでいるように見えるという仕組みになっています。
先ほどのデモページと同じになりますが、このコードで動いているのが下記のデモページのカウントダウンタイマーのページとなります。(cssで多少装飾はしています)
カウントダウンらしくミリ秒まで表示する場合
今までのデモだと秒単位でカウントされていきます。
これでもそのまま使えるのですが、せっかくカウントダウンタイマーを使うのであれば、よりカウントされてる感じを出したく、数字が素早く動くようにしたいというシーンもあります。
そういう場合はミリ秒まで表示する設定をすることでよりカウントが減っていく雰囲気のタイマーにする事が可能です。
ミリ秒まで表示するJavaScript
では実際のコードを見ておきましょう。
const target = new Date("2029/12/31 23:59:59");
const message = "終了しました。"
const elmid = document.getElementById( "countdown" );
const timer = setInterval(function() {
const now = new Date();
const diff = target - now;
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
const miliseconds = diff < 0 ? 0 :Math.floor( diff % 1000);
elmid.innerHTML = days + "日" + hours + "時間" + minutes + "分" + seconds + "." + miliseconds + "秒";
if (diff < 0) {
clearInterval(timer);
elmid.innerHTML = message;
}
}, 10);
変化しているところは背景色が付いたところになり、ミリ秒の計算、htmlへのその表示、最後のところで、この処理を1秒単位だったところを、ミリ秒単位で繰り返し処理をしていくという形になります。
実際は1でも10でも、見た目上の切り替わりは変わらず見えるため、少しでも負荷が少ないように10ミリ秒単位での設定にしています。
そのデモが下記になります。
ただ見て分かるように、ミリ秒というのは000~999まであるため、桁数が変わると表示が1桁~3桁まであり、数字の幅が凄まじいスピードで動いていく形になってしまいます。
当然これだと見ていると目がチカチカするため、これを修正する必要があります。
桁数が足りない時に0を付けて桁数を揃える
実は上記の設定では、桁数を揃えていないため、時、分、秒も同様に1桁のときと2桁のときで0が付く、付かないというのが分かれています。これをJavaScript上の設定で、桁数を指定して、足りなければ0を付けて表示するという設定が可能です。
const target = new Date("2029/12/31 23:59:59");
const message = "終了しました。"
const elmid = document.getElementById( "countdown" );
const timer = setInterval(function() {
const now = new Date();
const diff = target - now;
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
const miliseconds = diff < 0 ? 0 :Math.floor( diff % 1000);
elmid.innerHTML = `${ days }日${ String( hours ).padStart( 2, "0" ) }時間${ String( minutes ).padStart( 2, "0" ) }分${ String( seconds ).padStart( 2, "0" ) }.${ String( miliseconds ).padStart( 3, "0" ) }秒`;
if (diff < 0) {
clearInterval(timer);
elmid.innerHTML = message;
}
}, 1);
変化したのは14行目で、ガラッと変わっていますが、padStartというのが桁数を0が指定して足りなければ何を表示するかという指示になるため、時間、分、秒は2桁のため2,ミリ秒のみ3桁のため3を指定して、桁が不足する場合は0を表示するという指定をしています。
また、この書き方に変えるにあたって、= の右側を囲うのが、「`」というバッククオートと呼ばれるものに変わっていて、これによって文字列の中でも変数を埋め込めるようになり、「Shift+@」にて表示できます。
この設定をすることで、桁が違う影響で画面がチカチカすることなどもなく、桁数が足りなければ0がしっかり付くミリ秒単位でのカウントダウンをする事が可能になります。
下記がそのデモページとなり、見やすくなっているのが確認できます。
まとめ
ランディングページや通販キャンペーンなどでよく使われるカウントダウンタイマーについてまとめてみました。
意外とカウントダウンタイマーは、実践でもクライアントから使いたいというシーンもあったりするので、自分の中でコードセットとして使い方を身に付けて持っておくと時短になって便利です。
使い方や設定などは色々あったりするのですが、一番オーソドックスとなるであろう使い方についてまとめています。ただし、今回はIDでの設定を使っているため同一ページ内では1つしか設定・表示が行えませんので注意が必要です。
もしページの上部と下部などのように複数回、同じカウントダウンタイマーを設置したいという場合は下記も合わせてご確認ください。
- カウントダウンタイマーを複数設置するための設定とコード集【コピペOK】
- 以前にカウントダウンタイマーを設置する方法やコードなどを解説しましたが、カウントダウンタイマーが使われる主なケースというのは主に2パターンあり、 ペー...
最終的にはカウントダウンをする際にミリ秒まで表示して使う必要があるかどうかで使い方も多少は変わってくるかとは思いますが、実際にはほとんどはコピペで少しの修正で使えるものになりますので、使い方を覚えてキャンペーン系のページやランディングページなどで使うというシーンに備えておきましょう。
記事のシェアにご協力お願いします