본문 바로가기

WINK-(Web & App)/HTML & CSS & JS 스터디

[2023 신입부원 심화 스터디] 조현상 4주차 - Part 6

반응형

그동안 배운 js를 가지고 연습 문제들 만들어보기

<예제>

1.모달 만들기

2.할 일 앱 만들기

3.디지털 시계 만들기

4.가위바위보 게임 만들기

5.업그레이드 된 할 일 앱 만들기

 

 

 

 

1.모달 만들기

 

모달 만들기는 버튼을 통해서 내용이 보이고 안 보이는 기능을 만들어주는 예제였다.

<!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" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <button class="open">👉 Click</button>

    <div class="container">
      <div class="modal">
        <h2>Lorem, ipsum dolor.</h2>
        <p>
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Reiciendis,
          excepturi?
        </p>
        <button class="close">Close</button>
      </div>
    </div>

    <script src="./index.js"></script>
  </body>
</html>

우리는 open 클래스에 버튼을 통해서 container 클래스 속 내용들이 보여주고 안 보여주는 기능을 만들 것이다.

  .container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

최초 컨테이너는 display 가 none 속성으로 웹 페이지에 보이지 않는다.

const openButton = document.querySelector(".open");
const container = document.querySelector(".container");

const closeButton = document.querySelector(".close");

openButton.addEventListener("click", () => {
    container.style.display = "flex";
    openButton.style.display = "none";
});

그래서 우리는 js 를 통해서 querySelctor 로 open 과 container 를 받아왔고 

open 버튼을 addEventListener 과 연결해서 click event 가 발생했을 때 container 의 display 속성이 flex 로 보여지게 만들었다.

하지만 이렇게 될 경우 open 버튼이 화면에 보여져서 가려지기 때문에 open 버튼은 none 으로 안 보이게 해줬다.

 

closeButton.addEventListener("click", () =>{
    container.style.display = "none";
    openButton.style.display = "block";
})

그 다음 close 버튼도 addEventListener 과 연결해서 버튼을 눌렀을 때 container 가 사라지게 만들어주고 open 버튼이 다시 화면에 보이도록 만들었다.

 

 

 

 

2.할 일 앱 만들기

 

<!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" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <form>
      <input type="text" placeholder="할 일을 입력하세요." />
      <button>등록</button>
    </form> 

    <ul></ul>

    <script src="./index.js"></script>
  </body>
</html>

 

할 일 앱 만들기는 form 태그에서 input 태그를 통해 글을 입력했을 때 ul 태그에 입력된 글이 웹에서 보이도록 만들어 주는 기능이다.

 

const formSubmit = document.querySelector("form");
const input = document.querySelector("input");
const ul = document.querySelector("ul");


formSubmit.addEventListener("submit", (event) => {
    event.preventDefault();
    if(input.value != ""){
        const li = document.createElement("li");
        li.innerText = input.value;
        ul.appendChild(li);
        input.value = "";
    }
    
})

마찬가지로 querySelector 로 form 태그를 받아와서 addEventListener 과 연결시켰다.

여기서 중요한 점은 submit 을 연결시키면 form 태그 안에서 input 이 발생하는 이벤트를 event 로 가져올 수 있게 해준다.

 

우선 createElement 로 li 를 js 파일에서 생성시키고 li.innerText 를 통해서 input.value 값을 li 에 저장시켜준다.

그 다음 appendChild 를 통해 li 를 ul 태그에 넣어서 화면에 보여지도록 만든다.

 

event.preventDefault 는 event 가 초기화 되는 것을 없애주는 함수이고

input.value 는 이벤트가 끝나면 input 안에 값이 없어지게 해주는 것을 의미한다.

 

 

 

 

3.디지털 시계 만들기

<!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" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <div class="time hour">00</div>
    <div class="divider">:</div>
    <div class="time min">00</div>
    <div class="divider">:</div>
    <div class="time sec">00</div>

    <script src="./index.js"></script>
  </body>
</html>

디지털 시계만들기는 time hour , time min , time sec  클래스를 js 로 통해서 현재 시간으로 바꿔주면 된다.

const hour = document.querySelector(".hour");
const min = document.querySelector(".min");
const sec = document.querySelector(".sec");



function clock() {
    const now = new Date();
    hour.innerText = now.getHours();
    min.innerText = now.getMinutes();
    sec.innerText = now.getSeconds();
}


setInterval(clock, 1000);

마찬가지로 querySelector 을 통해서 hour , min , sec 클래스를 가져와줬고 

new Date()를 통해서 시간 , 분 , 초 를 getHours(), getMinutes(), getSeconds() 로 받아줬다.

그 다음 받은 값들을 innerText 를 통해서 바꿔줬다.

 

하지만 이렇게 끝나면 함수가 1번 실행되고 끝나기 때문에

setInterval(clock , 1000) 을 통해서 clock 함수가 1초 마다 반복해서 실행해주도록 만들었다.

 

 

 

 

4.가위바위보 게임 만들기

<!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" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <div class="container">
      <div class="block">
        <h3>컴퓨터 선택 :</h3>
        <p class="computer-choice">??</p>
      </div>
      <div class="block">
        <h3>당신 선택 :</h3>
        <p class="you-choice">??</p>
      </div>
    </div>

    <div class="buttons">
      <button class="red">가위</button>
      <button class="blue">바위</button>
      <button class="green">보</button>
    </div>

    <div class="result">가위바위보!</div>

    <script src="./index.js"></script>
  </body>
</html>

computer-choice 클래스에서 컴퓨터가 선택한 가위바위보 결과를 받아주고

you-choice 클래스에서 유저가 선택한 가위바위보 결과를 받아주고

result 클래스에서 승패 결과를 받아주는 구현을 해주면 된다.

 

const buttons = document.querySelectorAll("button");
const computerChoice = document.querySelector(".computer-choice");
const userChoice = document.querySelector(".you-choice");
const winner = document.querySelector(".result");

우선 querySelctorAll 을 통해서 가위 , 바위 , 보 3 개의 버튼을 리스트 형태로 buttons 로 받아준다.

buttons 에는 가위 , 바위 , 보 가 리스트 형태로 들어있는 것이다.

그 다음은 위에 말한 세 개의 클래스를 받는 변수를 만들어준다.

 

const result = ["가위", "바위", "보"];


const play = (event) => {
    const user = event.target.innerText;
    const randomIndex = Math.floor(Math.random() * 3);
    const computer = result[randomIndex];
    game(user, computer);
};
buttons.forEach((button) => {
    button.addEventListener("click", play);
});

buttons 가 리스트 형태로 되어있기 때문에 forEach 문을 통해서 button 들 중 클릭이 되었을 때 play 객체를 실행하도록 하였다. 

여기서 event 는 클릭된 button을 의미하며 event.target.innerText 는 우리가 고른 버튼의 이름을 말한다.

컴퓨터도 가위, 바위 , 보 중에 골라줘야 하기 때문에 random() 을 통해서 숫자를 만들어줘서 구현을 하였다.

 

const show = (user , computer , result) => {
    computerChoice.innerText = computer;
    userChoice.innerText = user;
    winner.innerText = result;
}


const game = (user , computer ) => {
    let message;
    if(user == computer) console.log("무승부");
    else{
        switch(user + computer){
            case "가위보":
            case "보바위":
            case "바위가위":
                message = "사용자 승리!";
                break;
            case "보가위":
            case "바위보":
            case "가위바위":
                message = "컴퓨터 승리!";
                break;
            
        }
    }
    show(user, computer, message);
}

다음 유저가 선택한 패와 컴퓨터가 선택한 패를 game 에 받아줘서 switch 를 통해서 작동시키게 만들었다.

(강의 속에서는 비겼을 때를 다루지 않았다.)

마지막 결과를 show 로 가져가서 innerText 를 통해서 값을 출력해줬다.

 

 

 

 

5.업그레이드 된 할 일 앱 만들기

<!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" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <form>
      <input type="text" placeholder="할 일을 입력하세요." />
      <button>등록</button>
    </form>

    <ul></ul>

    <script src="./index.js"></script>
  </body>
</html>

2. 에서 했던 할 일 앱에서 글을 삭제해주는 기능과 웹페이지를 초기화 해도 이전 값들을 받아와서 출력해주는 기능을 구현하는 것이다.

const addItem = (todo) =>{
    if (todo.text !== '') {
        const li = document.createElement('li');
        const button = document.createElement("button");
        const span = document.createElement("span");

        span.innerText = todo.text;
        button.innerText = "삭제";
        button.addEventListener("click",delItem);
        li.appendChild(span);
        li.appendChild(button);
        ul.appendChild(li);

    }
};

우선 글을 올렸을 때 삭제해야되는 버튼을 만들어줘야 되기 때문에 createElement를 통해서 span 과 button 을 li 태그에 넣어서 ul 태그에 보내준다. 

이전에는 li 태그에 input.value 를 넣어서 바로 ul 에 보내줬는데

이번에는 span 태그에 text를 받아와서 삭제 버튼을 함께 li 태그로 보내주는 형식이다.

 

const delItem = (event) => {
    const target = event.target.parentElement;

    todos = todos.filter( (todo) => todo.id != target.id);
    save();
    target.remove();
}

삭제 버튼이 눌러지면 delItem 이 실행되고 event.target.parentElement 를 통해서 부모의 이름과 같은 id 는 삭제해주고 다른 id는 살아남을 수 있게 filter 를 통해서 구현했다.

 

 

전과 다른 점은 전에는 input.value 를 통해서 바로 추가해주었지만 이제는 이전 내용이 기록에 남아야 됨으로써 내용들을 리스트에 저장해놓고 리스트에 추가해주면서 화면에 출력해주도록 바꾸었다.

let todos = [];

일단 내용들을 저장시킬 todos 리스트를 만들었고

const save = () =>{
    localStorage.setItem("todos", JSON.stringify(todos));
}

save 를 통해서 save 가 호출되면 초기화 되어도 내용을 저장할 수 있는 localStorage 를 통해 todos 를 저장하도록 구현하였다.

하지만 todos 를 바로 넣으면 내용이 정확히 저장이 안되기 때문에 JSON.stringify( ) 로 todos 를 감싸서 저장하도록 하였다.

 

const form = document.querySelector('form');
const input = document.querySelector('input');
const ul = document.querySelector('ul');

const handler = (event) => {
    event.preventDefault();

    const todo = {
        id: Date.now(),
        text: input.value,
    };
    todos.push(todo);
    save();

    addItem(todo);
    input.value = "";
};

form.addEventListener('submit', handler);

 이제 input.value 를 todo로 감싸서 todos 리스트에 넣어줬고

 그 후 save 를 불러서 todos 리스트 내용이 추가되었을 때 storage 에도 최신화 되게 구현하였다.

 그리고 handler 함수에서 addItem 을 불러와서 화면에 출력하는 기능까지 넣어주었다.

 

 

const init = () => {
    const userTodos = JSON.parse(localStorage.getItem("todos"));
    if(userTodos){
        userTodos.forEach((todo) => {
            addItem(todo);
        });
        todos = userTodos;
    }
    
}

init();

 마지막으로 화면을 새로고침 하여도 init() 을 통해서

localStorage에 저장되있는 값들을 가져와서

forEach 를 통해서 값들을 addItem 에 넣어서 화면에 출력해주도록 만들었다.

 

 

 

이번 강의에서 어려웠던 점들은 

const delItem = (event) => {
    const target = event.target.parentElement;

    todos = todos.filter( (todo) => todo.id != target.id);
    save();
    target.remove();
}


const handler = (event) => {
    event.preventDefault();

    const todo = {
        id: Date.now(),
        text: input.value,
    };
    todos.push(todo);
    save();

    addItem(todo);
    input.value = "";
};

등장하는 event 객체 들이 직관적이지 않아서 이해하는데 어려움이 있었고 

기존 언어와는 다른 자바스크립트 만에 자유로운 느낌의 문법이 어려웠다..

반응형