前提・実現したいこと
jQueryを使って1つのページにキッチンタイマーを4個作りたいと思っています。
(それぞれ6分、8分、10分、12分)
1つは動くモノを作成できたのですが、残り3つを動かすにはどのように実装すれば良いか分からず困っております。
該当のソースコード
html
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <link rel="stylesheet" href="style.css"> 7 <title>Timer</title> 8</head> 9<body> 10 <h1>タイマー</h1> 11 <div class="container"> 12 <div class="element"> 13 <div class="count" id="countBox"></div> 14 <button class="btn1" id="start">start</button> 15 <button class="btn2" id="stop">stop</button> 16 <button class="btn3" id="reset">reset</button> 17 </div> 18 </div> 19 <script src="libs/jquery-3.5.1.min.js"></script> 20 <script src="main.js"></script> 21</body> 22</html>
jQuery
1$(() => { 2 const countBox = $('#countBox'); 3 const start = $('#start'); 4 const stop = $('#stop'); 5 const reset = $('#reset'); 6 7 //タイマーの秒数 8 let setTime = 360; 9 //一時停止した時の秒数 10 let poseTime = setTime; 11 //残りの秒数 12 let timeLeft = setTime; 13 //setIntervalのための変数 14 let testTimer; 15 16 //残りの秒数を表示する関数 17 const displayText = () => { 18 countBox.text(timeLeft); 19 }; 20 21 //1ずつカウントダウンする関数 22 const countDown = () => { 23 timeLeft--; 24 poseTime = timeLeft; 25 displayText(); 26 }; 27 28 //カウントをストップする関数 29 const stopCount = () => { 30 clearInterval(testTimer); 31 }; 32 33 //1000ミリ秒ごとに処理を繰り返す関数 34 const timerStart = () => { 35 36 testTimer = setInterval(function () { 37 if (timeLeft <= 0) { 38 clearInterval(testTimer); 39 } 40 else { 41 countDown(); 42 } 43 }, 1000); 44 45 return; 46 }; 47 48 displayText(); 49 50 //ボタンを押したらカウントダウンスタート 51 start.on('click', () => { 52 stopCount(); 53 timeLeft = poseTime; 54 displayText(); 55 timerStart(); 56 }); 57 58 //ボタンを押したらカウントストップ 59 stop.on('click', () => { 60 stopCount(); 61 }); 62 63 //ボタンを押したらカウントリセット 64 reset.on('click', () => { 65 stopCount(); 66 timeLeft = poseTime = setTime; 67 displayText(); 68 }); 69 70}); 71
クラスやインスタンスを使って作成すれば良いのだろうなというところにはたどり着いたのですが、そこから上記で作ったコードをどのようにクラスに書き込めば良いのか分からない状態です、、、
初歩的な質問で大変申し訳ないのですが、お助けいただけると幸いです。
よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
念の為確認ですが6分、8分、10分、12分は別々の動作なのでしょうか、
それとも同時に(同じ開始タイミングで)動くのでしょうか?
別々の動作をするようにしたいと思っております!
説明不足でした!すみません????
2020/10/19 00:58
ということはstart/stop/resetもそれぞれのタイマーごとに必要ということですね?
はい!start/stop/resetのボタンもそれぞれのタイマーごとにつけて、
見た目は全く同じものを4つ作りたいと思っています!
カウントだけはそれぞれ別で動いてくれるイメージです????♂️
回答2件
0
ざっくりこんな感じでどうでしょう
投稿2020/10/19 02:11
編集2020/10/19 02:14総合スコア118264
//js
$(function(){
var times=[6,8,10,12];
var timerIDs=[null,null,null,null];
var rests=[0,0,0,0];
var startTime=[0,0,0,0];
$('.stop').prop('disabled',true);
$('.count').each(function(idx){
$('.start').eq(idx).on('click',function(){
$(this).prop('disabled',true);
$('.stop').eq(idx).prop('disabled',false);
startTime[idx]=new Date().getTime();
clearInterval(timerIDs[idx]);
timerIDs[idx]=setInterval(()=>{
var thistime=new Date().getTime();
rests[idx]-=(thistime-startTime[idx])/1000;
startTime[idx]=thistime;
if(rests[idx]<=0){
rests[idx]=0;
clearInterval(timerIDs[idx]);
}
$('.count').eq(idx).text(rests[idx]);
},100);
});
$('.stop').eq(idx).on('click',function(){
$(this).prop('disabled',true);
$('.start').eq(idx).prop('disabled',false);
clearInterval(timerIDs[idx]);
});
$('.reset').eq(idx).on('click',function(){
$('.start').eq(idx).prop('disabled',false);
$('.stop').eq(idx).prop('disabled',true);
clearInterval(timerIDs[idx]);
rests[idx]=times[idx]*60;
$('.count').eq(idx).text(rests[idx]);
}).trigger('click');
});
});
//html
<div>
<div class="count"></div>
<button class="start">start</button>
<button class="stop">stop</button>
<button class="reset">reset</button>
</div>
<div class="count"></div>
<button class="start">start</button>
<button class="stop">stop</button>
<button class="reset">reset</button>
</div>
<div class="count"></div>
<button class="start">start</button>
<button class="stop">stop</button>
<button class="reset">reset</button>
</div>
<div class="count"></div>
<button class="start">start</button>
<button class="stop">stop</button>
<button class="reset">reset</button>
</div>
codepenのsampleには時間表示を更かしておきました
ご回答頂きありがとうございます!
こんなにシンプルな書き方があるのですね????
eq(idx)など初見でしたのですごく勉強になります、、????
これから一度自分のエディタで実行してみます!本当にありがとうございます!
0
ベストアンサー
1つのファイルで作ったので見にくいかもしれませんけど
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> 7 <title>Timer</title> 8 </head> 9 <body> 10 <h1>タイマー</h1> 11 <div class="container"> 12 <div class="element"> 13 <div class="count" data-time="360"></div> 14 <button class="start-btn">start</button> 15 <button class="stop-btn">stop</button> 16 <button class="reset-btn">reset</button> 17 </div> 18 </div> 19 <div class="container"> 20 <div class="element"> 21 <div class="count" data-time="60"></div> 22 <button class="start-btn">start</button> 23 <button class="stop-btn">stop</button> 24 <button class="reset-btn">reset</button> 25 </div> 26 </div> 27 <div class="container"> 28 <div class="element"> 29 <div class="count" data-time="100"></div> 30 <button class="start-btn">start</button> 31 <button class="stop-btn">stop</button> 32 <button class="reset-btn">reset</button> 33 </div> 34 </div> 35 <script type="text/javascript"> 36 $(() => { 37 $(".element").each(function(){ 38 const countBox = $(this).children('.count'); 39 const start = $(this).children('.start-btn'); 40 const stop = $(this).children('.stop-btn'); 41 const reset = $(this).children('reset-btn'); 42 //タイマーの秒数 43 let setTime = $(this).children(".count").data("time"); 44 //一時停止した時の秒数 45 let poseTime = setTime; 46 //残りの秒数 47 let timeLeft = setTime; 48 //setIntervalのための変数 49 let testTimer; 50 //残りの秒数を表示する関数 51 const displayText = () => { 52 countBox.text(timeLeft); 53 }; 54 //1ずつカウントダウンする関数 55 const countDown = () => { 56 timeLeft--; 57 poseTime = timeLeft; 58 displayText(); 59 }; 60 //カウントをストップする関数 61 const stopCount = () => { 62 clearInterval(testTimer); 63 }; 64 //1000ミリ秒ごとに処理を繰り返す関数 65 const timerStart = () => { 66 testTimer = setInterval(function () { 67 if (timeLeft <= 0) 68 clearInterval(testTimer); 69 else 70 countDown(); 71 }, 1000); 72 return; 73 }; 74 displayText(); 75 //ボタンを押したらカウントダウンスタート 76 start.on('click', () => { 77 stopCount(); 78 timeLeft = poseTime; 79 displayText(); 80 timerStart(); 81 }); 82 //ボタンを押したらカウントストップ 83 stop.on('click', () => { 84 stopCount(); 85 }); 86 //ボタンを押したらカウントリセット 87 reset.on('click', () => { 88 stopCount(); 89 timeLeft = poseTime = setTime; 90 displayText(); 91 }); 92 }) 93 }); 94 </script> 95 </body> 96</html>
複数作る場合はid管理はダメなのでクラス管理にしました。
.countのdata-timeに秒数を指定することで、好きな時間で作成できます。
もう少しHTMLを省いて、エレメントを作成していくと
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> 7 <title>Timer</title> 8 </head> 9 <body> 10 <h1>タイマー</h1> 11 <div class="container" data-time="360"></div> 12 <div class="container" data-time="60"></div> 13 <div class="container" data-time="40"></div> 14 <script type="text/javascript"> 15 $(() => { 16 let a,b; 17 $(".container").each(function(){ 18 a = document.createElement("div"); 19 a.className = "element"; 20 b = document.createElement("div"); 21 b.className = "count"; 22 a.append(b); 23 b = document.createElement("button"); 24 b.className = "start-btn"; 25 b.textContent = "start"; 26 a.append(b); 27 b = document.createElement("button"); 28 b.className = "stop-btn"; 29 b.textContent = "stop"; 30 a.append(b); 31 b = document.createElement("button"); 32 b.className = "reset-btn"; 33 b.textContent = "reset"; 34 a.append(b); 35 $(this).append(a); 36 }) 37 $(".container").each(function(){ 38 const countBox = $(this).children().children('.count'); 39 const start = $(this).children().children('.start-btn'); 40 const stop = $(this).children().children('.stop-btn'); 41 const reset = $(this).children().children('reset-btn'); 42 //タイマーの秒数 43 let setTime = $(this).data("time"); 44 //一時停止した時の秒数 45 let poseTime = setTime; 46 //残りの秒数 47 let timeLeft = setTime; 48 //setIntervalのための変数 49 let testTimer; 50 //残りの秒数を表示する関数 51 const displayText = () => { 52 countBox.text(timeLeft); 53 }; 54 //1ずつカウントダウンする関数 55 const countDown = () => { 56 timeLeft--; 57 poseTime = timeLeft; 58 displayText(); 59 }; 60 //カウントをストップする関数 61 const stopCount = () => { 62 clearInterval(testTimer); 63 }; 64 //1000ミリ秒ごとに処理を繰り返す関数 65 const timerStart = () => { 66 testTimer = setInterval(function () { 67 if (timeLeft <= 0) 68 clearInterval(testTimer); 69 else 70 countDown(); 71 }, 1000); 72 return; 73 }; 74 displayText(); 75 //ボタンを押したらカウントダウンスタート 76 start.on('click', () => { 77 stopCount(); 78 timeLeft = poseTime; 79 displayText(); 80 timerStart(); 81 }); 82 //ボタンを押したらカウントストップ 83 stop.on('click', () => { 84 stopCount(); 85 }); 86 //ボタンを押したらカウントリセット 87 reset.on('click', () => { 88 stopCount(); 89 timeLeft = poseTime = setTime; 90 displayText(); 91 }); 92 }) 93 }); 94 </script> 95 </body> 96</html>
という感じですかね
投稿2020/10/18 16:51
編集2020/10/18 16:52総合スコア535
styleは持ってないので、削除して、
jqueryはCDNからダウンロードしてます。
コピペする際はご注意ください
2パターンもありがとうございます!
コピペしてやってみたところ動きました!!自分ではどうにもできなかったので感動しました!ありがとうございます????
また、「360」などの数字表記を「06:00」という風にそれぞれ変えたいと考えていてそちらも可能であればお聞きしたいのですが、それはまた別で質問した方が良いのでしょうか?(teratailが初めてで勝手がわかっておらずここで聞いてしまい申し訳ありません????)
私も初心者なので大丈夫ですよ
```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<title>Timer</title>
<!-- 追加 -->
<style media="screen">
.count{
display: none;
}
</style>
<!-- 追加 end -->
</head>
<body>
<h1>タイマー</h1>
<div class="container" data-time="360"></div>
<div class="container" data-time="60"></div>
<div class="container" data-time="40"></div>
<script type="text/javascript">
$(() => {
let a,b;
$(".container").each(function(){
a = document.createElement("div");
a.className = "element";
b = document.createElement("div");
b.className = "count";
a.append(b);
/* 追加 */
b = document.createElement("div");
b.className = "display";
a.append(b);
/* 追加 end */
b = document.createElement("button");
b.className = "start-btn";
b.textContent = "start";
a.append(b);
b = document.createElement("button");
b.className = "stop-btn";
b.textContent = "stop";
a.append(b);
b = document.createElement("button");
b.className = "reset-btn";
b.textContent = "reset";
a.append(b);
$(this).append(a);
})
$(".container").each(function(){
const countBox = $(this).children().children('.count');
const start = $(this).children().children('.start-btn');
const stop = $(this).children().children('.stop-btn');
const reset = $(this).children().children('.reset-btn');
/* 追加 */
const display = $(this).children().children('.display');
/* 追加 end */
//タイマーの秒数
let setTime = $(this).data("time");
//一時停止した時の秒数
let poseTime = setTime;
//残りの秒数
let timeLeft = setTime;
//setIntervalのための変数
let testTimer;
/* 追加 */
let minutes,seconds;
/* 追加 end */
//残りの秒数を表示する関数
const displayText = () => {
countBox.text(timeLeft);
/* 追加 */
minutes = Math.floor(timeLeft/60);
seconds = timeLeft % 60;
if(String(minutes).length == 1)
minutes = "0"+String(minutes)
if(String(seconds).length == 1)
seconds = "0"+String(seconds)
display.text(minutes+":"+seconds);
/* 追加 end */
};
//1ずつカウントダウンする関数
const countDown = () => {
timeLeft--;
poseTime = timeLeft;
displayText();
};
//カウントをストップする関数
const stopCount = () => {
clearInterval(testTimer);
};
//1000ミリ秒ごとに処理を繰り返す関数
const timerStart = () => {
testTimer = setInterval(function () {
if (timeLeft <= 0)
clearInterval(testTimer);
else
countDown();
}, 1000);
return;
};
displayText();
//ボタンを押したらカウントダウンスタート
start.on('click', () => {
stopCount();
timeLeft = poseTime;
displayText();
timerStart();
});
//ボタンを押したらカウントストップ
stop.on('click', () => {
stopCount();
});
//ボタンを押したらカウントリセット
reset.on('click', () => {
stopCount();
timeLeft = poseTime = setTime;
displayText();
});
})
});
</script>
</body>
</html>
```
こんな感じでしょうか。
`class="count"`は秒数のカウントがあるので`display:none`にして非表示に
`class="display"`というディスプレイのdiv要素を作成して、
分と秒を求めて描画するという感じです
ついでと言ってはなんですが、周期(1秒ごとや0.1秒、0.01秒毎)とかをプログラム側で選べるように`period`を定義しました
`period`の桁数から自動で0の追加とかを行えるので、
そう言った遊びを入れるのもありなのかなぁと((
勝手に遊んですみませんw
2つめのcontainerのeach文のみ表記しときますね
```JS
$(".container").each(function(){
const countBox = $(this).children().children('.count');
const start = $(this).children().children('.start-btn');
const stop = $(this).children().children('.stop-btn');
const reset = $(this).children().children('.reset-btn');
const display = $(this).children().children('.display');
const period = 0.01;//秒単位
//タイマーの秒数
let setTime = $(this).data("time");
//一時停止した時の秒数
let poseTime = setTime;
//残りの秒数
let timeLeft = setTime;
//setIntervalのための変数
let testTimer;
let minutes,seconds,micros,dumy;
//残りの秒数を表示する関数
const displayText = () => {
countBox.text(timeLeft);
minutes = Math.floor(timeLeft/60);
seconds = timeLeft % 60;
micros = String(seconds).split(".")[1];
seconds = String(seconds).split(".")[0];
if(micros == undefined){
micros = "";
for(let i = 0;i < String(period).split(".")[1].length;i++)
micros += "0";
}else{
dumy = micros;
micros = "";
for(let i = 0;i < String(period).split(".")[1].length;i++)
micros += dumy[i]
}
if(String(minutes).length == 1)
minutes = "0"+String(minutes);
if(String(seconds).length == 1)
seconds = "0"+String(seconds);
display.text(minutes+":"+seconds+"."+micros);
};
//1ずつカウントダウンする関数
const countDown = () => {
timeLeft -= period;
poseTime = timeLeft;
displayText();
};
//カウントをストップする関数
const stopCount = () => {
clearInterval(testTimer);
};
//1000ミリ秒ごとに処理を繰り返す関数
const timerStart = () => {
testTimer = setInterval(function () {
if (timeLeft <= 0)
clearInterval(testTimer);
else
countDown();
}, period*1000);
return;
};
displayText();
//ボタンを押したらカウントダウンスタート
start.on('click', () => {
stopCount();
timeLeft = poseTime;
displayText();
timerStart();
});
//ボタンを押したらカウントストップ
stop.on('click', () => {
stopCount();
});
//ボタンを押したらカウントリセット
reset.on('click', () => {
stopCount();
timeLeft = poseTime = setTime;
displayText();
});
})
```
優しいお言葉ありがとうございます????
そしてもう一つの質問にもお答えいただいてありがとうございます!
一つ目に教えていただいたやり方で数字表記の変更もうまくいきましたー!????
periodを使って表示を変えさせることもできるのですね、、!知らないことばかりですごく勉強になります!
ただHTMLを省いて作成して頂いたパターンの方がコピペしたのですがうまくいかなくて、、まだ自分の知識量ではその書き方への理解が足りていないのでなぜなのか分からず、、periodも含めてもう少し勉強させて頂きます????
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。