이번과제는 미리 생성된 버튼을 클릭하면 <body>
의 background 의 컬러가 변경되게 구현하는것이다.
그런데 그냥 단색이 아닌, 미리 주어져있는 컬러들이 담긴 배열을 이용해서 그 중에 두가지를 선택해
클릭할때마다 랜덤으로 출력하게끔 하는것이었다.
여기서 중요한건 랜덤으로 송출하는것이다. 자, 구현해 보자.
일단 버튼을 눌러서 컬러를 변경하는거니까, 버튼을 활성화 시켜보자.
이제 이건 눈감고도 하겠지?
btn.addEventListener("click", backColor);
html 에 있던 버튼 태그를 btn 이라는 이름으로 불러왔다, 그리고 backColor 라는 핸들러 함수를
만들것이고, 이 버튼을 클릭하는 이벤트를 줬을때, 핸들러함수가 실행되게끔 만들어 주었다.
그리고 console.log 를 이용해 텍스트가 출력되는지 확인해 보면, 무난하게 실행되는것을 확인할 수 있다.
그럼 이제 버튼의 활성화는 끝났고, 핸들러 함수 안에 body 태그의 backgound 컬러를 변경해주는
로직을 짠다면 문제없이 구현될것이다.
현재 주어진 컬러는 배열의 형태이다.
const colors = [
"#ef5777",
"#575fcf",
"#4bcffa",
.
.
.
"#ffa801",
"#ffd32a",
"#ff3f34"
];
이제 이 배열안의 인덱스들이 랜덤으로 찍히게 해주자, 어떻게 하면 될까?
Math.random()
메서드를 이용하자.
Math.random()
은 0과 1사이의 랜덤한 숫자를 출력해 준다, 그 의미는 좀 더 어렵지만
우리는 여기서 굳이 그 의미까지는 알 필요는 없고, 단순하게 0과 1 사이의 숫자를 "랜덤" 하게 출력한다는
것만 알면 될것 같다.
그런데 이것만 사용하면 안된다, 왜냐하면 0과 1사이의 숫자를 출력하기때문에 정수가 되지 않기 때문이다.
0.13232323, 0.444545354. 0.635656456 ... 이런 식으로 출력이 된다.
이 상태에서 우리가 원하는 값을 얻으려면 총 두번의 단계를 더 거쳐야 한다.
Math.random()
의 값이 1 이상이 되게 만든다.이제 이 두가지의 조건이 만족하게 하려면 어떻게 해야할까.
우리는 컬러가 담긴 배열을 랜덤으로 출력해야 한다, 배열의 인덱스는 colors[n]
로 나타낼 수 있겠다.
인덱스를 나타내는 n은 0부터 시작하는 정수의 상태이니까 우리는 저 1 아래의 상태에서
1 이상의 정수를 곱해주면 일단은 1이상의 숫자로 표현이 될것이다, 그리고 그 경우의 수는
배열의 길이로 표현해주면 된다, 배열의 길이 짧다면 하드하게 직접 개수를 곱해주면 되겠지만, 우리는 개발자
아닌가. 하나하나 세고있을 시간이 없으니 배열의 길이 .length
를 이용해서 수량을 곱해주자.
자, 이렇게 하면 우리는 0이상 colors.length 까지의 수를 얻었고 그것을 Math.random()
에
곱해줌으로써 2.13232323, 6.444545354. 3.635656456 ... 같은 결과를 얻어냈다.
하지만, 우리는 인덱스를 탐색할때 colors[2.13232323]
이런식으로 탐색하지 않는다.
소수점 뒤쪽의 숫자는 필요가 없다는 의미이다, 그리고 우리는 어떻게 해야할지 알고 있다.
Math.floor()
를 이용하는 것이다. Math.floor()
는 정수 부분의 숫자의 변화없이
소수점 아래의 숫자만 제거해주기때문에 사용하기 딱 적합하다.
자 그럼 모든것을 조합해보자.
const nowColor = colors[Math.floor(Math.random() * colors.length)];
이렇게 하면 colors 의 인덱스를 탐색하는데 그 값이 colors의 전체 인덱스 개수를 랜덤하게 송출할것이다.
이제 컬러를 랜덤하게 송출하는 변수도 만들으니 이제 다 끝났다.
아, 하나 남았다. 단색으로 출력하는게 아니라 그라데이션을 만들어야 한다.
그라데이션은 두개 이상의 컬러가 자연스럽게 섞이면서 변화하는 기법인데 처음에는 고민을 했다.
이걸 CSS에서 구현을 해야되나.. 그냥 JS 에서 구현할까..
CSS에서 구현하자니 뭔가 굉장히 복잡할거 같아서 그냥 JS 파일에서 해보기로 했다.
검색을 해보니, 충분히 가능하더라. 방법은 CSS 에서 작성하는 방법 그대로 사용하되
적는 방식만 좀 다른것 같았다.
CSS에서는
body {
background: linear-gradient(to right, blue, white);
}
이런식으로 구현이 가능하더라. JS도 크게 다르진 않다.
일단 그라데이션을 하려면 두가지의 컬러가 필요하다, 그건 어렵지 않다. 이미 하나를 만들었으니
쌍둥이 동생 하나를 더 만들어서 이름만 바꾸면 된다.
const nowColor1 = colors[Math.floor(Math.random() * colors.length)];
const nowColor2 = colors[Math.floor(Math.random() * colors.length)];
이제 이걸 그라데이션 구현 코드에 넣어놓으면 된다.
JS 내에서 <body>
를 가져오는것은 다른 id 나 class 를 가져오는것과는 조금 차이가 있다.
더 좋은 방법이 있는지는 모르겠지만 , 나는 일단 직관적으로 가져왔다.
document.body.style.background
를 입력하면 body 태그의 background를 수정할 수 있다.
그리고 아까 위에서 썻던 CSS 그라데이션 코드를 뒤쪽에 값으로 넣어준다.
document.body.style.background = `linear-gradient(to right, blue, white)`
대신 다른점이 있다면 값 부분을 백틱으로 감싸준다는 것, 그것만 다르고 나머지는 동일하다.
아 값을 = 로 표현한다는 것도, 이건 뭐.. 당연한가..
아무튼 이렇게 쓰고 나서 마지막으로 넣어줄것은 쌍둥이 컬러들이다.
저들은 변수의 성격을 띄고 있기때문에 단순한 text 의 형식이 아닌 리터럴의 형식으로 넣으면 된다.
document.body.style.background
= `linear-gradient(to right, ${nowColor1},${nowColor2})`
이렇게 하면 된다. 그리고 그 앞의 to right 는 그라데이션의 방향을 나타낸다, right니까 오른쪽으로
진행될거다. 맘대로 변화시키면 된다.
이제 정말 준비는 다 되었다, 모든 코드들을 핸들러 함수에 넣어서 버튼을 클릭했을때 변화하는지 확인하자.
잘 되었다면 잘한거고, 구현이 안된다면 어디에서 오류가 났는지 확인해 보자.
은근 되게 별거 아닌데서 틀린경우가 많으니 꼼꼼하게 살펴봐야 한다.
질문이있습니다. 첫 버튼 클릭에서는 정상적으로 배경 색상이 변경하는데 두 번째 클릭부터는 function이 작동을 안하는 것인지 아무변화가 없습니다... 어디가 잘못된 건지 아무리 구글링해도 저는 답을 찾기가 어려워서 댓글 남깁니다..