구현해야 할 것
<HTML>
1. 로또 번호가 출력되는 페이지를 만든다.
2. 누르면 이벤트가 발생하는 번호 생성 버튼을 만든다.
<Javascript>
1. 번호 생성 버튼을 눌리면 로또 번호가 보이게 한다.
2. 랜덤한 숫자를 뽑는다.
3. 각 요소에 뽑은 숫자를 넣어준다.
구현
아래와 같이 HTML 파일을 작성해 주자!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#lotto > li {
display: inline-block;
font-size: 40px;
width: 80px;
height: 80px;
border-radius: 40px;
text-align: center;
line-height: 80px;
margin: 30px;
box-shadow: 2px 2px 4px 1px rgba(0, 0, 0, 0.5);
}
#lotto.none {
display: none;
}
</style>
</head>
<body>
<h1>로또 번호 생성기</h1>
<ul id="lotto" class="none">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<button id="btn">번호 생성</button>
<script src="public/js/practice.js"></script>
</body>
</html>
번호 생성 버튼을 누르면 li 태그의 요소가 보이도록 Javascript 파일을 작성해보자!
const lottoElement = document.querySelector("#lotto");
const btnElement = document.querySelector("#btn");
function buttonEvent() {
lottoElement.className = "";
}
btnElement.addEventListener("click", buttonEvent);
1. querySelector를 이용해 id가 lotto인 요소를 lottoElement 변수에 담는다.
2. querySelector를 이용해 id가 btn인 요소를 btnElement 변수에 담는다.
3. 이벤트 핸들러에 전달할 buttonEvent 함수를 작성한다. 이 함수는 호출이 되면 lottoElement의 className을 빈 문자열로 수정해 준다.
4. btnElement에 click 이벤트를 등록해 준다. 만약 사용자가 번호 생성 버튼을 누르게 되면 buttonEvent 함수를 호출해 lottoElement의 className을 빈 문자열로 바꾸어 주게 되고 그러면 lottoElement는 class 속서에 none 값이 사라져 화면에 보이게 될 것이다.
이번에는 랜덤한 수를 생성하는 함수를 만들어 보자!
자바스크립트 내장 객체에 있는 Math 함수를 이용해서 랜덤 한 수를 생성해 보자!
Math.random()
이 함수는 0 이상 1 미만의 수를 랜덤하게 반환해 준다.
이 함수에 10을 곱해주면 0 이상 10 미만의 수를 랜덤 하게 반환해 준다.
Math.floor()
이 함수는 인자 값에 가우스 기호 씌워서 반환을 해준다고 볼 수 있다. 소수점을 버린다고 볼 수도 있다.
그럼 이번에는 두 함수를 이용해 1부터 45까지 숫자를 랜덤하게 생성하는 함수를 작성해 보자!
function randomNum() {
const ranNum = Math.floor(Math.random() * 45 + 1);
return ranNum;
}
1. Math.random 함수를 이용해 0부터 1미만의 수를 랜덤 하게 생성한다.
2. 그 값에 45를 곱해 0부터 45미만의 랜덤 한 수를 생성할 수 있도록 한다.
3. 그 값에 1을 더해 1부터 46미만의 수를 생성할 수 있도록 한다.
4. Math.floor 함수를 이용해 소수점을 버려 최종적으로 1부터 45까지의 수를 생성할 수 있도록 한다.
5. 이 값을 ranNum 변수에 담아 return해 준다.
이번에는 생성한 랜덤한 수를 li 태그 안에 넣어보자!
이전에 만들었던 buttonEvent 함수를 다음과 같이 수정해 주자!
const lottoElement = document.querySelector("#lotto");
const btnElement = document.querySelector("#btn");
const liList = document.querySelectorAll("#lotto > li"); // 추가
function buttonEvent() {
lottoElement.className = "";
// 추가
for (let i = 0; i < 6; i++) {
liList[i].innerHTML = randomNum();
}
}
btnElement.addEventListener("click", buttonEvent);
1. querySelectorAll로 li 요소들을 선택해 유사 배열 형태로 liList 변수에 담는다.
2. for문을 사용해 0번 인덱스 부터 5번 인덱스까지 liList 배열에 randomNum 함수를 호출한 결과를 innerHTML을 이용해 담는다.
일단은 구현하고자 하는 것은 다 구현이 되었다.
구현을 하고 보니 문제가 생겼다.
문제점
1. 진짜 로또 번호같은 색이 없음
2. 랜덤 번호에 중복값이 존재함
해결
이번에는 진짜 로또 번호 처럼 색을 입혀보자!
이전에 작성한 HTML 파일을 다음과 같이 수정해 주자!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#lotto > li {
display: inline-block;
font-size: 40px;
width: 80px;
height: 80px;
border-radius: 40px;
text-align: center;
line-height: 80px;
margin: 30px;
box-shadow: 2px 2px 4px 1px rgba(0, 0, 0, 0.5);
}
#lotto.none {
display: none;
}
/* 추가 */
/* 1~10 */
#lotto > li.a {
background: yellow;
}
/* 11~20 */
#lotto > li.b {
background: blue;
}
/* 21~30 */
#lotto > li.c {
background: red;
}
/* 31~40 */
#lotto > li.d {
background: gray;
}
/* 41~45 */
#lotto > li.e {
background: green;
}
/* 추가 */
</style>
</head>
<body>
<h1>로또 번호 생성기</h1>
<ul id="lotto" class="none">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<button id="btn">번호 생성</button>
<script src="public/js/practice.js"></script>
</body>
</html>
추가된 부분을 설명하면
1 ~ 10 : a라는 클래스명을 선택해 background를 노란색
11 ~ 20 : b라는 클래스명을 선택해 background를 파란색
21 ~ 30 : c라는 클래스명을 선택해 background를 빨간색
31 ~ 40 : d라는 클래스명을 선택해 background를 회색
41 ~ 45 : e라는 클래스명을 선택해 background를 녹색
으로 꾸며주는 코드이다.
그런데 꾸며야 할 li 태그 안에는 클래스가 존재하지 않는다.
그래서 자바스크립트를 이용해 번호에 맞게 클래스명을 넣어주어야 한다.
우선은 매개변수로 판별할 숫자와 범위를 받아서 그 숫자가 범위 안에 속하는지 판별하는 함수를 작성해 보자!
function betweenNum(num, min, max) {
if (num >= min && num <= max) {
return true;
}
return false;
}
1. num이라는 매개변수와 최소와 최대를 의미하는 min, max 매개변수를 받아 num 값이 min, max 사이 값이라면 true를 반환하고 그렇지 않다면 false를 반환해주는 함수이다.
우리는 li 태그에 클래스 속성을 적용해 주어야한다. 그러려면 생성된 랜덤 숫자가 어느 범위에 속하는지 판별을 해야 한다. 특정 범위에 속한다면 문자열을 리턴해주어서 그 값을 나중에 활용할 수 있는 함수를 작성해 보자!
function rangeNum(num) {
if (betweenNum(num, 1, 10)) {
return "a";
}
if (betweenNum(num, 11, 20)) {
return "b";
}
if (betweenNum(num, 21, 30)) {
return "c";
}
if (betweenNum(num, 31, 40)) {
return "d";
}
if (betweenNum(num, 41, 45)) {
return "e";
}
}
1. num이라는 매개변수를 받아서 그 값을 판별하기 위해 위에 작성한 betweenNum 함수를 이용하였다. 만약 num 값이 2라면 첫 번째 if문에 걸리게 되고 betweenNum함수를 호출하게 되는데 이때 매개변수로 받았던 2를 첫 번째 인자로 넣어주고 1~10 사이에 있는지 확인하고 싶기 때문에 두 번째 인자에는 1, 마지막 인자에는 10을 넣어주었다.
2. 만약 결과 값이 참이라면 문자열 a를 return하고 아니라면 다음 if 문으로 넘어가게 된다.
3. 우리는 이 값을 이용해 li 태그에 클래스 속성을 추가할 예정이다.
이제 li 태그에 클래스 속성을 추가해보자!
const lottoElement = document.querySelector("#lotto");
const btnElement = document.querySelector("#btn");
const liList = document.querySelectorAll("#lotto > li");
function buttonEvent() {
lottoElement.className = "";
for (let i = 0; i < 6; i++) {
const num = randomNum(); // 추가
liList[i].innerHTML = num; // 수정
liList[i].className = rangeNum(num); // 추가
}
}
btnElement.addEventListener("click", buttonEvent);
1. randomNum()에서 생성한 수를 여러번 사용하고 싶기 때문에 변수 num을 선언해 대입해 주었다.
2. liList에 innerHTML 속성에 num값을 대입해주었다.
3. liList에 className 속성에 rangeNum함수에 인자로 num을 넣어서 리턴된 값을 대입해 주었다.
위에 그림에서 보이는 것처럼 로또 번호에 중복 값이 존재 한다. 이 중복 값을 제거해 보자!
나는 처음에 아래 처럼 코드를 작성해 보았다. 아래 코드는 1부터 45의 랜덤 한 수를 중복 없이 6개 생성해 주는 함수이다.
function randomNumCreate() {
const randomNumArr = [randomNum()];
for (let i = 0; i < 5; i++) {
let temp = randomNum();
for (let j = 0; j < randomNumArr.length; j++) {
if (randomNumArr[j] === temp) {
randomNumArr.splice(j, 1);
i--;
}
}
randomNumArr.push(temp);
}
return randomNumArr;
}
1. 배열에 랜덤한 값이 1개 들어있는 randomNumArr이라는 변수에 대입한다.
2. 6개의 로또 번호 중 1개는 이미 만들어져 있기 때문에 for문을 5번만 반복시킨다.
3. temp라는 변수에 랜덤 한 값을 대입한다.
4. randomNumArr의 배열 길이만큼 내부 for문을 돌려서 배열 안에 있는 값이 위에서 생성한 랜덤 값과 같다면 그 값을 지우고 i의 값을 1 줄여주어서 상위에 있는 for문이 한번 더 돌 수 있도록 해준다.
5. 내부 for문이 끝나면 randomNumArr 배열에 위에서 생성한 랜덤값을 넣어준다.
6. 최종적으로는 길이가 6인 randomNumArr 배열을 return 한다.
이 함수를 이용하기 위해 buttonEvent 함수를 수정하자!
const lottoElement = document.querySelector("#lotto");
const btnElement = document.querySelector("#btn");
const liList = document.querySelectorAll("#lotto > li");
function buttonEvent() {
lottoElement.className = "";
const ranNum = randomNumCreate(); // 추가
for (let i = 0; i < 6; i++) {
liList[i].innerHTML = ranNum[i]; // 수정
liList[i].className = rangeNum(ranNum[i]); // 수정
}
}
btnElement.addEventListener("click", buttonEvent);
1. randomNumCreate 함수의 결과 값을 ranNum 변수에 대입한다.
2. ranNum의 i 번째 요소를 liList의 i 번째 요소의 innerHTML 속성에 대입한다.
3. rangeNum함수를 이용해 ranNum의 i 번째 요소가 어느 구간에 속하는지 판별한 뒤 결괏값을 liList의 i 번째 요소의 className 속성에 대입한다.
최종 코드
전체 코드를 보면 다음과 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#lotto > li {
display: inline-block;
font-size: 40px;
width: 80px;
height: 80px;
border-radius: 40px;
text-align: center;
line-height: 80px;
margin: 30px;
box-shadow: 2px 2px 4px 1px rgba(0, 0, 0, 0.5);
}
#lotto.none {
display: none;
}
/* 1~10 */
#lotto > li.a {
background: yellow;
}
/* 11~20 */
#lotto > li.b {
background: blue;
}
/* 21~30 */
#lotto > li.c {
background: red;
}
/* 31~40 */
#lotto > li.d {
background: gray;
}
/* 41~45 */
#lotto > li.e {
background: green;
}
</style>
</head>
<body>
<h1>로또 번호 생성기</h1>
<ul id="lotto" class="none">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<button id="btn">번호 생성</button>
<script src="public/js/practice.js"></script>
</body>
</html>
const lottoElement = document.querySelector("#lotto");
const btnElement = document.querySelector("#btn");
const liList = document.querySelectorAll("#lotto > li");
function randomNum() {
const ranNum = Math.floor(Math.random() * 45 + 1);
return ranNum;
}
function betweenNum(num, min, max) {
if (num >= min && num <= max) {
return true;
}
return false;
}
function rangeNum(num) {
if (betweenNum(num, 1, 10)) {
return "a";
}
if (betweenNum(num, 11, 20)) {
return "b";
}
if (betweenNum(num, 21, 30)) {
return "c";
}
if (betweenNum(num, 31, 40)) {
return "d";
}
if (betweenNum(num, 41, 45)) {
return "e";
}
}
function randomNumCreate() {
const randomNumArr = [randomNum()];
for (let i = 0; i < 5; i++) {
let temp = randomNum();
for (let j = 0; j < randomNumArr.length; j++) {
if (randomNumArr[j] === temp) {
randomNumArr.splice(j, 1);
i--;
}
}
randomNumArr.push(temp);
}
return randomNumArr;
}
function buttonEvent() {
lottoElement.className = "";
const ranNum = randomNumCreate();
for (let i = 0; i < 6; i++) {
liList[i].innerHTML = ranNum[i];
liList[i].className = rangeNum(ranNum[i]);
}
}
btnElement.addEventListener("click", buttonEvent);
마무리
추가적으로 정렬 기능이 필요할 것 같다. 그리고 randomNumCreate 함수도 조금 더 다듬으면 좋을 것 같다.
시간이 되면 수정한 결과물도 올릴 예정이다.
'Javascript' 카테고리의 다른 글
[Javascript] Event Object (0) | 2022.11.10 |
---|---|
[Javascript] Event (Add, Remove) (0) | 2022.11.09 |
[Javascript] DOM(Document Object Model) (0) | 2022.11.08 |
[Javascript] 객체 (0) | 2022.11.04 |
[Javascript] 피보나치 수열 - 알고리즘 (0) | 2022.11.03 |