<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>반응속도</title>
<style>
#screen {
width: 300px;
height: 200px;
text-align: center;
user-select: none;
}
#screen.waiting {
background-color: aqua;
}
#screen.ready {
background-color: red;
color: white;
}
#screen.now {
background-color: greenyellow;
}
</style>
</head>
<body>
<div id="screen" class="waiting">클릭해서 시작하세요</div>
<div id="result"></div>
</body>
</html>
CSS 에서 클래스 이름이 waiting 일때 파란색, ready 일때 빨간색, now 일때 초록색으로 변한다.
변수.classList.contains('클래스명');
을 사용하면 그 변수안에 '클래스명'이 존재하는지 판단하고 true/false 를 리턴한다.
document.addEventListener("DOMContentLoaded", () => {
const screen = document.querySelector("#screen");
const result = document.querySelector("#result");
screen.addEventListener("click", () => {
if (screen.classList.contains("waiting")) {
screen.classList.replace("waiting", "ready");
screen.textContent = "초록색이 되면 클릭하세요";
setTimeout(() => {
screen.classList.replace("ready", "now");
screen.textContent = "클릭 하세요!";
}, Math.floor(Math.random() * 1000) + 2000);
} else if (screen.classList.contains("ready")) {
} else if (screen.classList.contains("now")) {
}
});
});
처음 화면에는 파란색 화면을 띄웠다가 screen 을 클릭하는 순간 class명이 ready로 바뀌면서 빨간색으로 변화한다.
그리고 setTimeout 으로 인해 2~3초 사이에 랜덤으로 클래스명이 now로 바뀌면서 배경색이 초록색으로 변화한다.
시간을 측정하기 위해서는 new Date() 를 사용해야한다.
저렇게 Date 객체를 만들어주어서 date 를 출력하면 현재 시각이 나오는것을 확인할 수 있다.
document.addEventListener("DOMContentLoaded", () => {
const screen = document.querySelector("#screen");
const result = document.querySelector("#result");
let startTime; // 시작시간
let endTime; // 끝나는 시간
let responseTime; // 측정시간
screen.addEventListener("click", () => {
if (screen.classList.contains("waiting")) {
screen.classList.replace("waiting", "ready");
screen.textContent = "초록색이 되면 클릭하세요";
setTimeout(() => {
startTime = new Date();
screen.classList.replace("ready", "now");
screen.textContent = "클릭 하세요!";
}, Math.floor(Math.random() * 1000) + 2000);
} else if (screen.classList.contains("ready")) {
} else if (screen.classList.contains("now")) {
endTime = new Date();
responseTime = endTime - startTime; // 측정시간
result.textContent = responseTime + "ms";
screen.classList.replace("now", "waiting");
screen.textContent = "클릭해서 시작하세요";
}
});
});
이런식으로 시작 시간, 끝나는 시간, 측정 시간 변수를 하나씩 만들어주어서 Date 객체를 이용하여 시간을 측정했다.
평균을 구하려면 그 값들의 합을 먼저 구하는게 우선이다.
records 라는 빈 배열을 만들어주고 reduce 메서드를 이용하여 평균을 구해주었다.
<script>
document.addEventListener("DOMContentLoaded", () => {
const screen = document.querySelector("#screen");
const result = document.querySelector("#result");
let startTime; // 시작시간
let endTime; // 끝나는 시간
let responseTime; // 측정시간
let records = []; // 평균 반응 속도 구할 빈 배열
screen.addEventListener("click", () => {
if (screen.classList.contains("waiting")) {
screen.classList.replace("waiting", "ready");
screen.textContent = "초록색이 되면 클릭하세요";
setTimeout(() => {
startTime = new Date();
screen.classList.replace("ready", "now");
screen.textContent = "클릭 하세요!";
}, Math.floor(Math.random() * 1000) + 2000);
} else if (screen.classList.contains("ready")) {
} else if (screen.classList.contains("now")) {
endTime = new Date();
responseTime = endTime - startTime; // 측정시간
records.push(responseTime);
let Avg = records.reduce((acc, cur) => {return acc+cur}, 0) / records.length; // 평균 반응 속도
result.textContent = '현재 : ' + responseTime + " ms" + ' ' + '평균 속도 : ' + Avg;
// startTime = null;
// endTime = null; 여기서 null 이거 없어도 되지 않나?
screen.classList.replace("now", "waiting");
screen.textContent = "클릭해서 시작하세요";
}
});
});
</script>
빨간 화면이 등장 했을때는 대기 화면인건데, 이때 클릭을 누르면 성급하다는 메세지가 뜨면서 다시 파란화면으로 전환되도록 해야한다.
else if (screen.classList.contains("ready")) {
screen.textContent = '너무 성급합니다!';
screen.classList.replace('ready', 'waiting')
}
이렇게 작성을 하니 반복해서 계속 클릭을 할때, 대기중인 상태인데도 불구하고 계속 시간이 측정되에서 창에 띄어지는 문제가 발생했다.
저 setTimeout 함수가 계속 누적이 되어서 문제가 발생하는 것이었다.
그렇기 때문에 빨강 배경일때 클릭을 했을때 저 setTimeout 을 clearTimeout 을 동시에 해주어야지 오류가 발생하지 않았다.
else if (screen.classList.contains("ready")) {
clearTimeout(timeoutId);
screen.textContent = '너무 성급합니다!';
screen.classList.replace('ready', 'waiting')
}
정상적으로 잘 출력이 된다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>반응속도</title>
<style>
#screen {
width: 300px;
height: 200px;
text-align: center;
user-select: none;
}
#screen.waiting {
background-color: aqua;
}
#screen.ready {
background-color: red;
color: white;
}
#screen.now {
background-color: greenyellow;
}
</style>
</head>
<body>
<div id="screen" class="waiting">클릭해서 시작하세요</div>
<div id="result"></div>
</body>
<script>
document.addEventListener("DOMContentLoaded", () => {
const screen = document.querySelector("#screen");
const result = document.querySelector("#result");
let startTime; // 시작시간
let endTime; // 끝나는 시간
let responseTime; // 측정시간
let records = []; // 평균 반응 속도 구할 빈 배열
let timeoutId; // setTimeout 함수를 담을 변수
screen.addEventListener("click", () => {
if (screen.classList.contains("waiting")) {
screen.classList.replace("waiting", "ready");
screen.textContent = "초록색이 되면 클릭하세요";
timeoutId = setTimeout(() => {
startTime = new Date();
screen.classList.replace("ready", "now");
screen.textContent = "클릭 하세요!";
}, Math.floor(Math.random() * 1000) + 2000);
} else if (screen.classList.contains("ready")) {
clearTimeout(timeoutId);
screen.textContent = '너무 성급합니다!';
screen.classList.replace('ready', 'waiting')
} else if (screen.classList.contains("now")) {
endTime = new Date();
responseTime = endTime - startTime; // 측정시간
records.push(responseTime);
let Avg = records.reduce((acc, cur) => {return acc+cur}, 0) / records.length; // 평균 반응 속도
result.textContent = '현재 : ' + responseTime + " ms" + ' ' + '평균 속도 : ' + Avg;
// startTime = null;
// endTime = null; 여기서 null 이거 없어도 되지 않나?
screen.classList.replace("now", "waiting");
screen.textContent = "클릭해서 시작하세요";
}
});
});
</script>
</html>
안녕하세요 올려주신 소스코드를 사용하고 싶은데 혹시 가능하실가요?