<!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>
const $screen = document.querySelector("#screen');
const $result = document.querySelector('#result');
$screen.addEventListener('click', (event) => {
if (event.target.classList.contains('waiting')) { //파랑
$screen.classList.remove('waiting');
$screen.classList.add('ready');
$screen.textContent = '초록색이 되면 클릭하세요';
setTimeout(function() {
$screen.classList.remove('ready');
$screen.classList.add('now');
$screen.textContent = '클릭하세요';
// 첫 시간 재기
}, Math.floot(Math.random() * 1000) + 2000); //2000~3000사이의 수
} else if (event.target.classList.contains('ready')) {//빨강
} else if (event.target.classList.contains('now')) {//파랑
// 끝 시간 재기
// 시간 차이 저장하기
}
}
const $screen = document.querySelector("#screen');
const $result = document.querySelector('#result');
let startTime;
let endTime;
$screen.addEventListener('click', (event) => {
if (event.target.classList.contains('waiting')) { //파랑
$screen.classList.remove('waiting');
$screen.classList.add('ready');
$screen.textContent = '초록색이 되면 클릭하세요';
setTimeout(function() {
startTime = new Date();
$screen.classList.remove('ready');
$screen.classList.add('now');
$screen.textContent = '클릭하세요';
// 첫 시간 재기
}, Math.floot(Math.random() * 1000) + 2000); //2000~3000사이의 수
} else if (event.target.classList.contains('ready')) {//빨강
} else if (event.target.classList.contains('now')) {//파랑
// 끝 시간 재기
endTime = new Date();
$result.textContent = '${endTime - startTime}ms';
$screen.classList.remove('now');
$screen.classList.add('waiting');
$screen.textContent = '클릭해서 시작하세요';
}
}
startTime과 endTime을 만약에 addEventListener안에서 작성하면 클릭시 서로 다른 계속 새롭게 되므로 두 개의 차를 구하지 못할 것이다.
배열 vs 객체 리터럴. 둘 다 여러개의 변수를 하나로 묶어 놓는 역할인데, 배열은 원소가 다 비슷한 성질을 가지고, 객체 리터럴은 다른 속성을 가진다.
const $screen = document.querySelector("#screen');
const $result = document.querySelector('#result');
let startTime;
let endTime;
const records = [];
$screen.addEventListener('click', (event) => {
if (event.target.classList.contains('waiting')) { //파랑
$screen.classList.remove('waiting');
$screen.classList.add('ready');
$screen.textContent = '초록색이 되면 클릭하세요';
setTimeout(function() {
startTime = new Date();
$screen.classList.remove('ready');
$screen.classList.add('now');
$screen.textContent = '클릭하세요';
// 첫 시간 재기
}, Math.floot(Math.random() * 1000) + 2000); //2000~3000사이의 수
} else if (event.target.classList.contains('ready')) {//빨강
} else if (event.target.classList.contains('now')) {//초록
endTime = new Date();
const current = endTime - startTime;
records.push(current);
const average = records.reduce((a,c) => a + c) / records.length;
$result.textContent = '현재 ${current}ms, 평균: ${average}ms';
startTime = null;
endTime = null;
$screen.classList.remove('now');
$screen.classList.add('waiting');
$screen.textContent = '클릭해서 시작하세요';
}
}
const는 재할당은 불가능하지만, 내부 데이터 변경은 가능하다.
[1,2,3,4].reduce((a,c) => (a+c))
> 10
reduce는 매개 변수 두 개를 받는데 앞에 것은 누적값, 뒤에 것은 현재 값이다.
['철수', '영희', '헌영', '한솔'].reduce((a,c,i) => {a[i] = c; return a}, {})
{0: "철수", 1: "영희", 2: "헌영", 3: "한솔"}
세 번째 인자는 인덱스다. reduce가 받는 두번째 인자는 초기값이다. 초기값을 안넣으면 첫 번째 값이 초기값이다.
$screen.addEventListener('click', (event) => {
if (event.target.classList.contains('waiting')) { //파랑
$screen.classList.remove('waiting');
$screen.classList.add('ready');
$screen.textContent = '초록색이 되면 클릭하세요';
timeoutId = setTimeout(function() {
startTime = new Date();
$screen.classList.remove('ready');
$screen.classList.add('now');
$screen.textContent = '클릭하세요';
// 첫 시간 재기
}, Math.floot(Math.random() * 1000) + 2000); //2000~3000사이의 수
} else if (event.target.classList.contains('ready')) {//빨강
clearTimeout(timeoutId);
$screen.classList.remove('ready');
$screen.classList.add('waiting');
$screen.textContent = '너무 성급하시군요!';
} else if (event.target.classList.contains('now')) {//초록
endTime = new Date();
const current = endTime - startTime;
records.push(current);
const average = records.reduce((a,c) => a + c) / records.length;
$result.textContent = '현재 ${current}ms, 평균: ${average}ms';
startTime = null;
endTime = null;
$screen.classList.remove('now');
$screen.classList.add('waiting');
$screen.textContent = '클릭해서 시작하세요';
}
}
타이머를 썼으면 필요없을 때는 확실하게 없애야 한다. 그래서 첫번째 else if 에서 제거하고 있다.
else if (event.target.classList.contains('now')) {//초록
endTime = new Date();
const current = endTime - startTime;
records.push(current);
const average = records.reduce((a,c) => a + c) / records.length;
$result.textContent = '현재 ${current}ms, 평균: ${average}ms';
const topFive = records.sort((p,c) => p - c).slice(0, 5);
topFive.forEach((top, index) => {
$result.append(
document.createElement('br'),
'${index + 1}위: %{top}ms',
);
});
startTime = null;
endTime = null;
$screen.classList.remove('now');
$screen.classList.add('waiting');
$screen.textContent = '클릭해서 시작하세요';
}