[자바스크립트] 인프런 - 렛츠기릿 자바스크립트 - 8강

June·2021년 8월 5일
0

반응속도 체크 순서도 그리기

<!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안에서 작성하면 클릭시 서로 다른 계속 새롭게 되므로 두 개의 차를 구하지 못할 것이다.

평균 반응속도 구하기(reduce)

배열 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는 재할당은 불가능하지만, 내부 데이터 변경은 가능하다.

reduce

[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 = '클릭해서 시작하세요';
  }

0개의 댓글