JavaScript로 할 수 있는 사이트가 어떤 것이 있을까 검색을 해보다가
초보자를 위한 40가지의 자바스크립트 예제가 있어서 하루~일주일안에 1개씩 구현해볼까 한다
초보자를 위한 것이지만 하루만에 구현하기 어려운 것이 있을 수 있으므로 하루~일주일안으로 기한을 잡았다
버튼 클릭시 배경색상 랜덤으로 변경하기
querySelector, addEventListener, Math.floor(), Math.random()
<button class="color-change">🎨COLOR - CHANGE🎨</button>
index.html body에 버튼을 추가해준다
<script src="background.js"></script>
background.js파일을 추가하고 index.html body안 제일 아랫쪽에 script src='경로'를 추가한다
만약 head에 script src를 추가하려면 소스코드에 defer을 추가하면 된다
<script src="background.js" defer></script>
defer을 추가하는 이유는 코드는 위에서부터 아래로 읽어내려가는데 head쪽에 있으면 body가 구현되기 전에 background.js 안에 있는 함수들이 실행될 수 있기 때문에 함수처리를 body까지 구현되고 나서 실행하는 것으로 알고 있다
(아직 초보자라 확실하지 않을 수 있다)
const body = document.querySelector("body");
index.html의 body 부분을 querySelector로 가져온다
이 경우 body에 배경색상을 변경해주기 위해 가져온다
id를 지정해서 가져와도 된다 id로 가져올 때는 querySelector도 가능하고
getElementById로 가져와도 된다
(getElementById('지정해준id이름')
const colorChangeBtn = document.querySelector(".color-change");
index.html의 버튼도 가져온다
클릭 시 색상을 변경하는 함수를 지정해주기 위함이다
querySelector의 경우 선택자형식으로 가져오기 때문에 .color-change 로 CSS에 입력하는 방식으로 가져온다
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
랜덤 색상을 가져와야 하기 때문에 rgb(255, 255, 255)처럼 r, g, b를 각각 랜덤수 0~255까지 가져와야한다
Math.random()은 0과 1사이의 수를 생성한다
그래서 Math.floor()로 소수점 이하를 버려준다
0부터 시작이기 때문에 최대값 256? (255?)을 Math.random()에 곱해준다
만약 0부터 시작하지 않으려면 최대값 -1을 해주고 최소값을 더해주면 된다.
(사실 0부터 시작하지 않으려면 + 1을 해주는 것은 알겠는데 0부터 시작할 때 256인지 255인지 헷갈린다)
수정(새로 이해한 부분)
:floor, ceil, round의 개념을 이해한다면 최대값을 어떻게 지정해야하는지 알 수 있다.
floor는 소수점을 내림하는 것이고 ceil은 올림, round는 반올림 하는 것이다.
Math.random()함수를 쓰게되면 0~1사이의 랜덤 수를 가져오는데
최대값을 지정하지 않고 Math.floor(Math.random()) 을 하게되면 return값은 무조건 0이 된다.
최대값을 256으로 Math.random() * 256 하고 앞에 Math.floor로 감싸주게 되면 소수점은 버리기 때문에 0~255까지 나온다
만약 ceil을 하게되면 소수점을 무조건 올리기 때문에 1~256까지 return될 것이고
round를 쓰게 되면 0~256까지 출력될 것이다.
수정끝
// ex 1부터 시작하는 랜덤 수
let r = Math.floor(Math.random() * 255) + 1;
let color = `rgb(${r}, ${g}, ${b})`;
rgb 컬러가 랜덤이 되어야 하기 때문에 r, g, b를 같은 방법으로 각각 지정해주었다
그리고 color라는 변수에 백틱을 사용하여 rgb(${r}, ${g}, ${b} 로 각각 랜덤 숫자를 받게 지정했다
colorChangeBtn.addEventListener("click", () => {
// 실행할 내용(body 색상 변경하기)
}
index.html에서 가져온 버튼에 이벤트를 지정해준다 (arrow function 사용)
함수이름을 따로 지정해서 ('click',함수이름) 으로 지정해줄 수도 있다
원래 함수는 함수이름() 까지 괄호를 넣어야 실행되지만 이 경우 ()를 넣게 되면 무조건 실행되기 때문에 ()는 제외한다
click을 했을 때만 함수가 실행되게 하기 위함이다
body.style.backgroundColor = color;
body의 색상을 변경해주는 구문이다
index에서 가져온 body에 style을 변경해주는데 backgroundColor에 color를 할당하게 되면 rgb 랜덤 색상으로 변경된다
버튼 이벤트 함수안에 넣어준다
<body>
<button class="color-change">🎨COLOR - CHANGE🎨</button>
<script src="background.js"></script>
</body>
const body = document.querySelector("body");
const colorChangeBtn = document.querySelector(".color-change");
colorChangeBtn.addEventListener("click", () => {
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
let color = `rgb(${r}, ${g}, ${b})`;
body.style.backgroundColor = color;
});
일단 한번에 구현하지 못했다
새로고침했을 때 랜덤 배경색상 구현은 했지만 버튼을 만들고 버튼을 눌렀을 경우 한번만 랜덤색상으로 변경되었다
구현이 안되었을 때 밑에 코드처럼 r, g, b를 바깥쪽에 두었다
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
let color = `rgb(${r}, ${g}, ${b})`;
colorChangeBtn.addEventListener("click", () => {
body.style.backgroundColor = color;
});
최근에 혼공자에서 for, if문 배울 때 scope때문에 실행이 안되었었는데 같은 이슈였다
구현하기 위해 해본 것은 원래 color를 따로 지정해 주지 않고 body.style.backgroundColor에 백틱을 넣고 rgb(${r}, ${g}, ${b})를 썼는데 구현되지 않았다
당연하지... 변수가 밖에 지정되어 있으니...
{} 기준으로 생각해보면 된다고 하셨다
2번째로 let color를 지정해주고 body.style도 color로 변경했다
그래도 구현이 되지 않았다
당연하지... r,g,b가 여전히 밖에 있으니...
scope는 아직 헷갈린다
안에서 없으면 밖에 있는 변수를 사용한다고 생각했는데 지금 생각해보니 arrow function이라 변수가 안쪽에 같이 있어야 해당 변수를 찾아가는 것인가도 생각이 든다(this의 개념처럼)
순서만 바꾸면 되는데 나름 구글링을 해봤는데 rgb색상 랜덤으로 하는 건 못찾았고 배열에 랜덤 색상 몇가지를 넣어서 하는 방법들 뿐이었다
그렇게 몇분을 생각해보다 r,g,b 변수들을 안으로 넣으면 어떨까 하는 생각이 들어서 전체 코드처럼 colorChangeBtn.addEventListener 안으로 옮겼더니 랜덤색상이 출력되었다...
뿌듯하다 고생했다 이제 자러가야지