フロントエンジニアになるための練習問題 押すと色が変わるボタン7
前回の続きです。
課題
クライアントから追加の修正依頼がきました。
- 色を変える時は、一つ前の色以外の色にして欲しい
グレーからは、赤・青・黄のどれかにランダムで変わるようにしましたが、連続で同じ色になることを防いで欲しい、という内容です。
具体的にいうと以下のようなことを指します。
- グレーボタンをクリック
- 赤色になる
- 赤色のボタンをクリック
- グレーになる
- グレーボタンをクリック
- 赤色以外(つまり青色か黄色)の色になる
前提
- javascriptのループ処理を使える
30分から1時間程度。
実装の流れ
- 一つ前に使われた色を記憶しておく
- 色を取得する際には、一つ前に使われた色と違う色になるまで繰り返す
実装例
まずは、使われた色を記憶するために、適用したクラス名を保管する変数を定義し、クラスを適用した後にそのクラスを保管します。
prevColor という変数を宣言し、prevColor = applyClass; で適用したクラスをセットします。
//略
let prevColor = ''; //追加
//略
startButtonEl.addEventListener("click", () => {
// 略
if(startButtonEl.classList.contains("red-active") || startButtonEl.classList.contains("blue-active") || startButtonEl.classList.contains("yellow-active")){
startButtonEl.classList.remove("red-active", "blue-active", "yellow-active");
}else{
const value = getRandom(1, 3);
const applyClass = getClass(value);
startButtonEl.classList.add(applyClass);
prevColor = applyClass; //追加
}
});
続いて、色が異なるまでランダムに取得し続ける関数を作ります。
const getDifferentClass = (prev) => {
let result;
while(true){
result = getClass(getRandom(1, 3));
if(result !== prev) break;
}
return result
};
引数のprev には、前の色(クラス名)を渡します。
whileループはtrueなので無限にループし続けますが、ランダムで取得したクラス名とprevが異なれば break してループを抜けます。
全体のコードです。
const getRandom = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
const getClass = (value) => {
switch (value) {
case 1: {
return 'red-active';
}
case 2: {
return 'blue-active';
}
case 3: {
return 'yellow-active';
}
}
};
const getDifferentColor = (prev) => {
let result;
while(true){
result = getClass(getRandom(1, 3));
if(result !== prev) break;
}
return result;
};
let canClick = true;
let prevColor = '';
const startButtonEl = document.getElementById("start-button");
startButtonEl.addEventListener("click", () => {
const inactiveButton = () => {
canClick = false;
startButtonEl.innerText = '処理中...';
};
const activeButton = () => {
canClick = true;
startButtonEl.innerText = 'ボタン';
};
if(!canClick) return;
inactiveButton();
setTimeout(() => {
activeButton();
}, 5000);
if(startButtonEl.classList.contains("red-active") || startButtonEl.classList.contains("blue-active") || startButtonEl.classList.contains("yellow-active")){
startButtonEl.classList.remove("red-active", "blue-active", "yellow-active");
}else{
const applyClass = getDifferentColor(prevColor);
startButtonEl.classList.add(applyClass);
prevColor = applyClass;
}
});
最近のコメント