質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

1233閲覧

JSで指定した日時までカウントダウンする処理を画像で表示したい

niwaka_design

総合スコア9

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

1クリップ

投稿2018/12/05 21:25

編集2018/12/06 12:28

前提・実現したいこと

指定した日時までカウントダウンする処理を画像で表示するJSを実装しました。
参考サイト
http://cly7796.net/wp/javascript/countdown-image-timer/

下記のソースで1つはカウンターが設置されるのですが、別の日付をもう一つカウンターを表示させたいと思っています。
どのようにしたらもう一つ別の日付でカウンターが作れるでしょうか?

追記

日付の違う2つのイベントがあり、HPを開いたときに、それぞれのイベントまで●日というカウンターを出したいと思います。
時間・秒数は必要なく日付のみ表示させたいと思います。

Javascript

// 期限の設定 var gYear = 2020, // 年 gMonth = 7, // 月 gDay = 24, // 日 gHour = 0, // 時 gMinute = 0, // 分 gSecond = 0; // 秒 var goal = new Date(gYear, gMonth-1, gDay, gHour, gMinute, gSecond); // 画像の高さの設定 var numHeight = 22; // 使用する変数 var currentTime, period, cDay, cDayHundred, cDayTen, cDayOne, cHour, cHourTen, cHourOne, cMinute, cMinuteTen, cMinuteOne, cSecond, cSecondTen, cSecondOne, cFlame, cFlameTen, cFlameOne, insert = ""; // カウント用画像の指定 var dayThousand = document.getElementById('day-thousand'), dayHundred = document.getElementById('day-hundred'), dayTen = document.getElementById('day-ten'), dayOne = document.getElementById('day-one'), hourTen = document.getElementById('hour-ten'), hourOne = document.getElementById('hour-one'), minuteTen = document.getElementById('minute-ten'), minuteOne = document.getElementById('minute-one'), secondTen = document.getElementById('second-ten'), secondOne = document.getElementById('second-one'), flameTen = document.getElementById('flame-ten'), flameOne = document.getElementById('flame-one'); // カウントダウンの処理 function countdown() { // 現在から期限日までの差を取得 currentTime = new Date(); period = goal.getTime() - currentTime.getTime(); // 期限を過ぎていない時 if(period >= 0) { // 日数を取得 cDay = Math.floor(period / (1000 * 60 * 60 * 24)); period -= (cDay * (1000 * 60 * 60 * 24)); // 桁数を4桁に揃える cDay = String(cDay); while(cDay.length < 4) { cDay = '0' + cDay; } // 画像の切り替え dayThousand.style.top = (- cDay.substr(0, 1) * numHeight) + 'px'; dayHundred.style.top = (- cDay.substr(1, 1) * numHeight) + 'px'; dayTen.style.top = (- cDay.substr(2, 1) * numHeight) + 'px'; dayOne.style.top = (- cDay.substr(3, 1) * numHeight) + 'px'; // 時間を取得 cHour = Math.floor(period / (1000 * 60 * 60)); period -= (cHour * (1000 * 60 * 60)); // 桁数を2桁に揃える cHour = String(cHour); while(cHour.length < 2) { cHour = '0' + cHour; } // 画像の切り替え hourTen.style.top = (- cHour.substr(0, 1) * numHeight) + 'px'; hourOne.style.top = (- cHour.substr(1, 1) * numHeight) + 'px'; // 分を取得 cMinute = Math.floor(period / (1000 * 60)); period -= (cMinute * (1000 * 60)); // 桁数を2桁に揃える cMinute = String(cMinute); while(cMinute.length < 2) { cMinute = '0' + cMinute; } // 画像の切り替え minuteTen.style.top = (- cMinute.substr(0, 1) * numHeight) + 'px'; minuteOne.style.top = (- cMinute.substr(1, 1) * numHeight) + 'px'; // 秒を取得 cSecond = Math.floor(period / (1000)); period -= (cSecond * (1000)); // 桁数を2桁に揃える cSecond = String(cSecond); while(cSecond.length < 2) { cSecond = '0' + cSecond; } // 画像の切り替え secondTen.style.top = (- cSecond.substr(0, 1) * numHeight) + 'px'; secondOne.style.top = (- cSecond.substr(1, 1) * numHeight) + 'px'; // フレーム cFlame = Math.floor(period / (10)); // 桁数を2桁に揃える cFlame = String(cFlame); while(cFlame.length < 2) { cFlame = '0' + cFlame; } // 画像の切り替え flameTen.style.top = (- cFlame.substr(0, 1) * numHeight) + 'px'; flameOne.style.top = (- cFlame.substr(1, 1) * numHeight) + 'px'; // カウントダウンの処理を再実行 setTimeout(countdown, 10); // 期限を過ぎた時 } else { } } // 処理の実行 countdown();

HTML

<div id="countdown-unit"> <div><img src="num.gif" width="20" height="220" id="day-thousand"></div> <div><img src="num.gif" width="20" height="220" id="day-hundred"></div> <div><img src="num.gif" width="20" height="220" id="day-ten"></div> <div><img src="num.gif" width="20" height="220" id="day-one"></div> <div><img src="day.gif" width="20" height="22"></div> <div><img src="num.gif" width="20" height="220" id="hour-ten"></div> <div><img src="num.gif" width="20" height="220" id="hour-one"></div> <div><img src="time.gif" width="20" height="22"></div> <div><img src="num.gif" width="20" height="220" id="minute-ten"></div> <div><img src="num.gif" width="20" height="220" id="minute-one"></div> <div><img src="time.gif" width="20" height="22"></div> <div><img src="num.gif" width="20" height="220" id="second-ten"></div> <div><img src="num.gif" width="20" height="220" id="second-one"></div> <div><img src="time.gif" width="20" height="22"></div> <div><img src="num.gif" width="20" height="220" id="flame-ten"></div> <div><img src="num.gif" width="20" height="220" id="flame-one"></div> </div>

CSS

#countdown-unit div { position: relative; float: left; width: 20px; height: 22px; overflow: hidden; } #countdown-unit div img { position: absolute; top: 0; left: 0; }
petitplanet👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/12/05 21:28

htmlのほうもコードブロック ``` で囲ってJavaScriptのコードを同じようにしていただけますか?
m.ts10806

2018/12/05 21:35

やりたいこととしては「いきなり同時にカウントダウンを開始」でしょうか。それとも何かしらボタンなど押して押したほうだけ・指定したほうだけをカウントダウンでしょうか。もう少し用途(要件・仕様)を明確にしていただけますか?
niwaka_design

2018/12/05 21:42

ありがとうございます。2つのイベントまでの日数までのカウントなので、時間・秒数は必要なく、あと●●日という表示があればよい仕様です。ボタンを押してカウントされるのではなく、ページを開いたときに別々の日付のイベントがそれぞれあと●日という風にしたいと思います。
m.ts10806

2018/12/05 21:47

質問は編集できるので適宜(最初のコードブロックも含めて)追記・編集してください。
m.ts10806

2018/12/05 23:25

ヒント回答のみだと一言ですがそれではなく具体的にコードと解説も必要ですか?
niwaka_design

2018/12/05 23:29

お返事ありがとうございます。できれば解説をいただけるとありがたいです。
m.ts10806

2018/12/05 23:57

了解です。ただ、本当に全てそのままコピペで動くコードを提示してしまうと質問者さんのためにもなりませんし、ヒント回答にコードと解説をつけるような形で提示しようと思います。(ロジック部分はある程度使いまわせるかなあと)
niwaka_design

2018/12/05 23:59

ありがとうございます。しっかり勉強いたします!
m.ts10806

2018/12/06 01:30

あとすみません。回答はしているのですが、「初心者」は要件とも違いますし、質問編集画面から「初心者アイコン」がつけられるので、それだけにとどめていただけますか?
guest

回答2

0

ざっくりした回答
命題:カウンタで1箇所書き換えていたものを2箇所書き換えにしたい

対策としては3つの内のどれかでやればよいでしょう

  • ほぼ同じ内容の関数を2つ作ってそれぞれ回転させる
  • 1つの関数の中に2箇所書き換える処理をいれる
  • 1つの関数を使うが引数を指定して2回まわす

投稿2018/12/06 03:49

yambejp

総合スコア114767

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

niwaka_design

2018/12/06 10:25

ありがとうございます。やってみますね。
guest

0

ちょっとコードの調整と文章の準備に時間がかかってしまいましたが、回答します。

まず元々のコードについて。

「画像の使い方」はCSSスプライトと言う技法を用いています。(リンク先参照)
ざっくり言うと画像を個数分用意するのではなく1つにまとめ、必要な領域だけをCSSで制御して表示させる技法ですね。
今回は全て数字で0から始まっていて1つ1つの高さ・幅が決まっているので
あてられた数字が決まればその画像の最上部から何pxの位置から表示させればいいか決まるので、その分styleのtopの位置をずらして数字がさも入れ替わったように見せています。

あと、複数設置したい場合ですが、
同じHTML内に同じIDは1つのみというルールがあります(idはidentification の略。つまり唯一であることが証明されている情報と言うことです)
そのためには「HTML構造はそのままで別IDを用意する」が一点。

また、getElementById()でそれぞれを取得してきて変数におさめていますが、
これも「別の変数を用意する」必要が出てきますね。
「別の変数を用意する」となると、countdown()の中で使われている変数は全て最初のものですから、処理も倍用意する必要が出てきます。

つまり、速攻で実現したいのでしたら
「HTMLも処理も倍準備する」という風になります。

コメントで「ヒント回答のみだと一言」というのは上記のように単純に実現したいならHTMLも処理も倍準備するということになります。

でもちょっと待ってください。

処理内容はほぼ同じ内容で、結局違うのは「止めたい位置(今回は日付)」だけですよね。
もしこれで何個もカウントダウンタイマーを設置したいとなったら何個もHTMLと処理を用意しなければならないのか、それって増えれば増えるほど重たくなるじゃん!
となれば、実はそこからがスタートです。

JavaScriptにはcreateElementというものがあり、HTMLタグを生成する機能があります。
配列や配列のループで同じ内容の処理を別の値に対して行うこともできます。

つまり、JavaScriptで配列をループさせて動的にHTMLを作るようにし、countdown()処理もループで処理すれば、何個に増えたとしても対応可能ということになります。

下記、日付ではありませんが、別々の開始点を以て、数字をカウントダウンさせる処理をざっと作ってみました。
配列部分の数値をかえたり要素を追加すれば、とりあえず何個でも何桁でも関係なくできるようになっています。
0になったら「完」と表示してそれ以上カウントダウンしないようにしてあります。
参考にしてみてください。

html

1<div id="countdown_timer"></div>

css

1div#countdown_timer div div { 2 position: relative; 3 float: left; 4 width: 20px; 5 height: 22px; 6 overflow: hidden; 7} 8div#countdown_timer div div img { 9 position: absolute; 10 top: 0; 11 left: 0; 12}

js

1var countdown_timer = document.getElementById("countdown_timer"); 2 3//タイマー用 4var timer_set = [10,26,349]; 5// 画像の高さの設定 6var numHeight = 22; 7 8//画面load時にタイマーを設置 9window.onload = function(){ 10 for(var i=0;i<timer_set.length;i++){//タイマー設定分ループ 11 var timer_div = document.createElement("div"); 12 timer_div.setAttribute("id","countdown-unit_"+i); 13 timer_div.setAttribute("data-seconds",timer_set[i]);//現在の秒数を保管 14 timer_div.style.clear = "both"; //タイマーごとに改行 15 16 var set_timer_arr = String(timer_set[i]).split(''); //設定値を分割してimg作る 17 for(set_i=0;set_i<set_timer_arr.length;set_i++){ 18 var timer_img_div = document.createElement("div");//画像を生成 19 var timer_img = document.createElement("img");//画像を生成 20 timer_img.setAttribute("id","unit_"+i+"_"+set_i);//画像のラッパー 21 timer_img.setAttribute("width","20px"); 22 timer_img.setAttribute("height","220px"); 23 timer_img.src = "num.gif"; 24 timer_img.style.top = -(numHeight*parseInt(set_timer_arr[set_i]))+"px";//表示位置 25 26 //タイマーimg追記 27 timer_img_div.appendChild(timer_img); 28 timer_div.appendChild(timer_img_div); 29 } 30 //タイマーi生成 31 countdown_timer.appendChild(timer_div); 32 } 33 // 処理の実行 34 countdown(); 35}; 36// カウントダウンの処理 37function countdown() { 38 for(var i=0;i<timer_set.length;i++){//タイマー設定分ループ 39 var timer_div = document.getElementById("countdown-unit_"+i); 40 var timer_seconds = timer_div.dataset.seconds; 41 if(parseInt(timer_div.dataset.seconds) != 0){//完了していないタイマーのみ処理を行う 42 var count_down_seconds = parseInt(timer_div.dataset.seconds) - 1; 43 timer_div.dataset.seconds = count_down_seconds; 44 timer_div.innerHTML = "";//いったんクリア 45 var set_timer_arr = String(count_down_seconds).split(''); //設定値を分割してimg作る 46 for(set_i=0;set_i<set_timer_arr.length;set_i++){ 47 var timer_img_div = document.createElement("div");//画像を生成 48 var timer_img = document.createElement("img");//画像を生成 49 timer_img.setAttribute("id","unit_"+i+"_"+set_i);//画像のラッパー 50 timer_img.setAttribute("width","20px"); 51 timer_img.setAttribute("height","220px"); 52 timer_img.src = "num.gif"; 53 timer_img.style.top = -(numHeight*parseInt(set_timer_arr[set_i]))+"px";//表示位置 54 55 //タイマーimg追記 56 timer_img_div.appendChild(timer_img); 57 timer_div.appendChild(timer_img_div); 58 } 59 if(count_down_seconds === 0){ //0の場合は完了 60 var timer_end_div = document.createElement("div");//画像を生成 61 timer_end_div.innerHTML = "完"; 62 timer_div.appendChild(timer_end_div); 63 } 64 } 65 } 66 setTimeout(countdown, 1000);//毎秒実行 67} 68

補足

setTimeout()の第2引数はミリ秒で指定します。1000で1秒です。
10ということは1/100秒ですね。
日付のみのカウントダウンにするのであれば、1/100秒毎に実行する意味あまりないように思います。
TWENTY FOURみたいにするのであれば1/100秒でも見栄えがしますが、数字が切り替わるのが日付の切り替わりと同時なので1秒(設定値:1000)で充分かなと。

「時間・秒数は必要なく日付のみ」なのであれば時・分・秒に関するHTMLとJavaScriptの記述を削除するだけすね。これは自分でもやってみてください。

つまり、実現のためのステップが必要になります。

  1. 質問に提示されている単体のタイマーから時分秒を取り除いた状態のものを作って動作確認
  2. 1.のHTML部分をcreateElementで生成するように修正する
  3. 2.の状態でタイマーが動くか動作確認
  4. 配列で日付を定義してループし、HTMLを生成するように修正する(タイマーはまだ仕掛けない)
  5. タイマーで配列で定義した日付をループし、それぞれカウントダウンを行う

※日付のカウントダウンですが、1日毎にしかカウントダウンを確認できないので、動作確認のため秒の部分は残しておいて出来上がったあとに削除のほうが良いかも・・・。

参考:

蛇足:
日付を扱うのであればmoment.jsというのが非常に楽です。

投稿2018/12/06 01:26

編集2018/12/06 01:33
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

niwaka_design

2018/12/06 10:24

丁寧に解説いただきありがとうございました!1個づつやってみます。
m.ts10806

2018/12/06 11:09

私の視点での手順なのでイメージ難しいところありましたらもう少し細分化してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問