2021.04.30rsp.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