JavaScriptで「setTimeout(メソッド、時間)」の関数を使うと、記述したメソッドが指定した時間の経過後に実行されます。
これを例えば実行前、また実行中にキャンセルさせるためには「clearTimeout(setTimeoutの関数)」を記述する事で可能になります。
今回は、以前に作成したおみくじを例に、どういった挙動になるのか、またclearTimeout」の記述に関する注意点についてまとめようと思います。
※例で使うおみくじはこちらの記事のものになります。↓
目次
clearTimeoutを使わない場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
"use strict"; { const box = document.getElementById("box"); const box2= document.getElementById("box2"); const kuji = () => {box2.classList.add("kuji2")}; const kiti = ["キライ!", "普通!", "抱いて♡"]; box.addEventListener("click", () => { if(box.className === "") { box.classList.add("omi"); let n = Math.floor(Math.random() * 3); box2.textContent = kiti[n]; setTimeout(kuji, 3000); } else { box.classList.remove("omi"); box2.classList.remove("kuji2"); } }); } |
html/cssは冒頭の過去記事でまとめていますが、おみくじの箱をクリックするとイベント処理でCSSのアニメーションが3s実行されて左右に揺れるような動作をするようになっています。
その後のくじが出てくる挙動にするため、setTimeoutで3s後にCSSのclassを操作しています。
これが一連の流れになりますが、動画にあるとおり、setTimeoutの処理が完了する前にくじを中に戻すキャンセルの動作(else部分の処理)を行うと、その時点ではアニメーションは止まり、くじも中に入ったままになりますが、3s後にはくじが出てきてしまいます。
これはsetTimeoutの関数がキャンセル出来ていない為です。
clearTimeoutを使った場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
"use strict"; { const box = document.getElementById("box"); const box2 = document.getElementById("box2"); const kuji = () => {box2.classList.add("kuji2")}; const kiti = ["キライ!", "普通!", "抱いて♡"]; let re; box.addEventListener("click", () => { if(box.className === "") { box.classList.add("omi"); let n = Math.floor(Math.random() * 3); box2.textContent = kiti[n]; re = setTimeout(kuji, 3000); } else { box.classList.remove("omi"); box2.classList.remove("kuji2"); clearTimeout(re); } }); } |
動画の通り、2度目のクリックでsetTimeoutの処理がキャンセルされている事が分かります。
キャンセルの記述については、
①グローバル変数を宣言
②ローカルで①の変数にsetTomeoutの処理を代入
③clearTimeout()の引数に②の変数を渡す
でOKです。
clearTimeoutの注意点
グローバルで宣言した変数にsetTimeoutの処理を格納しない
どうやら「setTimeout()」の処理は、変数に代入する際にも実行される挙動を起こすみたいですので、グローバルで代入してしまうと意図しない動作になってしまいます。
かといってローカルで変数の宣言+関数の代入もしてはいけない
これするとうまく動作しませんでした。理由は不明ですが、どうやらグローバルで変数だけ宣言、ローカルでsetTimeout()の処理を代入しなければいけないみたいです。
clearTimeoutの引数には変数を渡す
変数ではなく、setTimeoutの関数をそのままclearTimeoutの引数に記述してもいけそうな気がしますが、何故かうまく動作しません。
setTimeoutの関数が代入された変数でなければうまくキャンセルの動作にならないみたいですので、前途したように「setTimeout()」の処理は、変数に代入しつつ実行させて、その時に代入された変数をclearTimeoutの引数に渡すのがポイントのような気がします。
定数は使えない
constは使えませんでした。