2021.04.30
rsp.html
1. style.background
2. setInterval()
3. 버그 해결
- 가정
- 해결 방법
$computer.style.background = `url(${IMG_URL}) 0 0`;
스타일의 background
는 이미지 X좌표 Y좌표값
을 입력할 수 있다.
const rspX = {
scissors: "0",
rock: "- 230px",
paper: "-440px",
};
위와 같이 공통된 속성을 지닌 변수의 모임은 객체로 묶어주는 것이 현명하다.
$computer.style.background = `url(${IMG_URL}) ${rspX[computerChoice]} 0`;
$computer.style.backgroundSize = "auto 200px";
rspX.computerChoice
하면 안된다. 왜냐하면 rspX객체엔 computerChoice
라는 문자열 속성이 없기 때문에 rspX[computerChoice]
로 선택해야 한다.
background
를 수정할 때마다 size도 초기화
되기 때문에 항상 background와 backgroundSize는 붙어있어야 한다.
setInterval
함수는 return
값이 존재한다. 그 값은 타이머에 대한 아이디(숫자)
로 해당 값을 사용하여 타이머를 제거할 수 있다.setInterval을 취소
할 수 있는 방법으로 clearInterval
을 제공한다. let ID= setInterval(함수,ms)
setTimeout
함수도 clearTimeout
으로 제거할 수 있지만 setTimeout
함수 내의 인수로 넣은 함수가 실행되기 전에 clearTimeout
을 호출해야 한다.const clickButton = () => {
//버튼을 눌렀을 때
clearInterval(intervalId); // 타이머 멈춤.
//점수 계산 및 화면 표시
setTimeout(() => {
intervalId = setInterval(changeComputerHand, 50); //타이머를 만들 때마다 변수에 저장한 후에 clearInterval해야 한다.
}, 1000); //1초 뒤에 다시 setInterval.
};
$rock.addEventListener("click", clickButton);
$scissors.addEventListener("click", clickButton);
$paper.addEventListener("click", clickButton);
setTimeout
설정값 1초 내에 여러 번 클릭하면 그림이 빠르게 돌아간다. 그 후에 버튼을 클릭하면 그림이 멈추지 않는다.setTimeout
타이머가 여러 개 실행되기 떄문이다.버튼클릭을 하면 clearInterval
을 수행하므로 문제없다고 생각할 수도 있다.
하지만 버튼은 setInterval
을 멈추는 clearInterval
을 수행할 뿐 setTimeout
을 멈추는 clearTimeout
을 수행하지는 않아서 버튼을 누른 횟수만큼 setTimeout타이머가 실행되고 각각1초 뒤에 setInterval을 하게 되어 그림이 빠르게 돌아가는거다.
clickButton
을 1초 내에 10번을 눌렀다.interval
의 ID인덱스로 따지면 10개가 생기지만 덮어씌우는 방식이기 때문에 마지막 인덱스를 intervalID변수
에 넣고 있다.clearInterval함수 한번 더 사용.
(추천)
clickButton
이 실행되는 최초에 한번 클리어하고
1초 뒤 실행되는 setTimeout
에 한번 더 클리어를 하면
1초루프동안마다 클리어가 반복되므로 해결됨.
const clickButton = () => {
clearInterval(intervalId);
setTimeout(() => {
clearInterval(intervalId); //추가.
intervalId = setInterval(changeComputerHand, 50);
}, 1000);
};
$rock.addEventListener("click", clickButton);
$scissors.addEventListener("click", clickButton);
$paper.addEventListener("click", clickButton);
removeEventListener메서드 사용(비추천: 실수하기 쉬움)
이유: func() !== func()
라는(객체 참조관계) 개념을 사용하여 addEventListener
와 removeEventListener
내의 해결 법: 함수가 같아야 제거가 되는데 같지 않기 때문에 제거가 안되는 점을 놓치기 때문.
func() === func()
값이 false
를 반환하기 때문에 객체(함수)를 번수에 넣으면 비교할 수 있다.
참고) 참조관계를 유지하고 싶으면 변수에 넣으면 된다!
const clickButton = () => {
$rock.removeEventListener("click", clickButton); //추가.
$scissors.removeEventListener("click", clickButton); //추가.
$paper.removeEventListener("click", clickButton); //추가.
//clickButton이 실행되는 최초에 한번 제거
setTimeout(() => {
$rock.addEventListener("click", clickButton); //추가.
$scissors.addEventListener("click", clickButton); //추가.
$paper.addEventListener("click", clickButton); //추가.
//1초 뒤 실행되는 setTimeout마다 실행
intervalId = setInterval(changeComputerHand, 50);
}, 1000);
};
$rock.addEventListener("click", clickButton);
$scissors.addEventListener("click", clickButton);
$paper.addEventListener("click", clickButton);
플레그 변수 사용
(추천)
let clickable = true; //추가.
const clickButton = () => {
if (clickable) {
clearInterval(intervalId);
clickable = false; //추가.
setTimeout(() => {
clickable = true; //추가.
intervalId = setInterval(changeComputerHand, 50);
}, 1000);
}
};
diff === '고양이' || diff === '사자' || diff === '강아지' || diff === '거북이'
['고양이','사자','강아지','거북이']. includes(diff)
['고양이','사자','강아지','거북이']. indexOf(diff) > -1