본문 바로가기

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

[2023 신입부원 심화 스터티] 박지민 #4주차 Part. 6 예제 만들기 (연습문제)

반응형

그동안 강의를 통해 배운 js를 이용하여 예제 만들기

 

1. 모달 만들기

👉 Click 버튼을 누르면 모달 내용만 보이고 Close 버튼 누르면 👉 Click 버튼만 보이기

 

- index.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" />
    <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>

 

- style.css

...
.container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: none; // 기본 container 클래스의 display는 none 속성 -> 첫 화면에 보임 X
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
...

 

- index.js

// 사용할 요소 가져오기
const openButton = document.querySelector(".open");
const container = document.querySelector(".container");
const closeButton = document.querySelector(".close");

// eventListener를 등록 -> 요소의 속성 변경 기능 구현
// 버튼 클릭 -> 모달 창의 영역인 container의 style 속성 조작 -> 모달 창 나타남
// 모달 창 열리면 open 버튼 사라짐 & 닫기 버튼 누르면 모달 창 사라지고 open 버튼 나타남
openButton.addEventListener("click", () => {
  container.style.display = "flex";
  openButton.style.display = "none";
});

// click 이벤트가 발생 -> container와 open 클래스의 display 속성 값을 반대로 지정
closeButton.addEventListener("click", () => {
  container.style.display = "none";
  openButton.style.display = "block";
});

 

2. 할 일 앱 만들기

폼에 텍스트를 입력하고 등록 또는 enter 눌렀을 때 입력 내용들을 모두 화면에 보이게 하기

 

- index.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" />
    <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>

 

- index.js

// eventListener를 event 종류를 폼을 제출될 때로 지정하기 때문에 폼으로 한 번만 등록 ->
// submit 이벤트 발생: 폼 내부의 input 위젯에서 enter를 입력 / submit 타입의 버튼 클릭
const form = document.querySelector("form");
const input = document.querySelector("input");
const ul = document.querySelector("ul"); // 아이템을 넣어야하기 때문

form.addEventListener("submit", (event) => {
  // 입력값을 제출할때 새로고침 -> 사용자가 입력한 값이 사용되지 X 문제를 해결
  event.preventDefault(); // event 객체가 가지고있는 preventDefault() 메소드 사용

  if (input.value != "") { // 사용자가 아무것도 입력하지 않고 제출했을 때
    const li = document.createElement("li"); // 리스트 생성
    li.innerText = input.value; // 리스트에 입력값 넣기
    ul.appendChild(li); // 리스트를 ul에 넣기 -> 화면에 li 내용들이 보임

    input.value = ""; // 입력 & 제출 후 입력란이 공백으로 돌아감
  }
});

 

3. 디지털 시계 만들기

date 객체 사용하여 00 텍스트를 현재 시간 초단위로 표현

 

- index.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" />
    <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>

 

- index.js

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

function clock() {
  const now = new Date(); // Date 객체 생성 -> 이 객체가 가지고 있는 메소드를 사용하여 현재 시,분,초 가져오기
  // 현재 시간 정보 가져와 각 요소 innerText에 해당 시간 정보 넣음 -> 아래 3개만 작성하면 시간을 딱 한번만 가져옴
  hour.innerText = now.getHours();
  min.innerText = now.getMinutes();
  sec.innerText = now.getSeconds();
}

// 1초에 한 번씩 반복 (밀리세컨즈) -> 초단위로 동작 -> setInterval 사용
// 일정한 시간마다 동일한 작업을 수행하기 위함 -> 첫 번째 인자로 반복해서 실행할 함수 두 번째 인자로 딜레이 시간 입력
setInterval(clock, 1000);

 

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

사용자가 가위, 바위, 보 중 하나를 선택 & 컴퓨터는 랜덤으로 하나를 선택 & 서로 비교하여 승패 출력

 

- index.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" />
    <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>

 

- index.js

const buttons = document.querySelectorAll("button"); // 가위, 바위, 보 3개의 버튼 가져와 리스트 형태로 받기
const computerChoice = document.querySelector(".computer-choice");
const userChoice = document.querySelector(".you-choice");
const winner = document.querySelector(".result");

// 컴퓨터에 랜덤으로 세 값중 하나 지정
const result = ["가위", "바위", "보"]; // 배열 생성 후 인덱스 값 랜덤으로 받아 값 지정

// 게임 결과 보여줌
function show(user, computer, message) {
  computerChoice.innerText = computer;
  userChoice.innerText = user;
  winner.innerText = message;
}

// 승,무,패 정하기
const game = (user, computer) => {
  let message;

  if (user === computer) {
    message = "무승부";
  } else {
    switch (user + computer) { // 더하기 연산은 숫자끼리 하면 숫자의 덧셈, 텍스트 값이 하나라도 있으면 두 피연산자를 붙인 텍스트를 만듦
      // 가위바위, 바위보, 보가위 -> 컴퓨터 승
      case "가위바위":
      case "바위보":
      case "보가위":
        message = "컴퓨터 승리!";
        break;
      // 가위보, 바위가위, 보바위 -> 유저 승
      case "가위보":
      case "바위가위":
      case "보바위":
        message = "당신 승리!";
        break;
    }
  }
  show(user, computer, message);
};

// 사용자에게 클릭한 버튼 값 할당, 컴퓨터에게 랜덤 값 할당
const play = (event) => {
  const user = event.target.innerText;
  const randomIndex = Math.floor(Math.random() * 3); // 0~2 중 하나의 난수 생성
  const computer = result[randomIndex]; // 0~1사이에 있는 부동소수점 난수 생성
  game(user, computer);
};

// 가위, 바위, 보 세 버튼중 하나 클릭 -> 랜덤으로 세 버튼 중 하나의 값을 컴퓨터에 전달
buttons.forEach((button) => {
  button.addEventListener("click", play);
});

 

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

두 번째 실습에서 더 나아가기 -> 할 일 삭제 & 웹페이지를 초기화해도 화면에 이전 값들 보여주기

 

- index.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" />
    <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>

 

- index.js

  • 삭제 버튼을 추가 및 기능 구현
  • 추가 아이템 저장 -> web storage 사용
  • 삭제 버튼 -> 저장된 데이터 업데이트
const form = document.querySelector("form");
const input = document.querySelector("input");
const ul = document.querySelector("ul");

let todos = []; // 데이터 저장 배열

// 새로고침 -> 요소 사라짐 -> 사라지지 않게 현재 화면에 있는 값들을 저장
function save() {
  localStorage.setItem("todos", JSON.stringify(todos)); // 변화된 todos 값을 문자열로 변환 -> 이전 todos에 초기화
}

// 값 삭제 기능
function delItem(event) {
  const target = event.target.parentElement; // 지워야 하는 요소

  // 필터링 -> todo의 id가 삭제하려는 id와 같이 않으면 삭제, 같지 않은 원소들만 모아서 다시 저장
  todos = todos.filter((todo) => todo.id !== parseInt(target.id)); // todo.id !== target.id :: target.id가 문자열이라 원하는 대로 되지 않음
  // 해결책 : 1. != 내용물만 비교 2. todo.id !== parseInt(target.id)
  save();
  target.remove(); // 삭제 버튼 누른 것만 사라짐
}

// 값 추가 기능
function addItem(todo) {
  if (todo.text !== "") {
    const li = document.createElement("li");
    const button = document.createElement("button");
    const span = document.createElement("span"); // span 태그를 이용 -> 입력 값과 삭제 버튼을 함께 li 태그로 보냄

    button.innerText = "삭제"; // 버튼 텍스트
    button.addEventListener("click", delItem);
    span.innerText = todo.text;

    // 여러 개의 요소 추가 위해 append 메소드 사용 가능
    li.appendChild(span);
    li.appendChild(button);
    ul.appendChild(li);
    li.id = todo.id; // li id와 todo id 같게 하기 -> 삭제 원소 구분 목적
  }
}

// 제출 누르면 입력 값들 화면에 추가
const handler = (event) => {
  event.preventDefault(); // 제출할 때 페이지 새로고침 X

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

  todos.push(todo); // 배열에 집합 형태로 원소를 추가
  addItem(todo);
  save();
  input.value = "";
};

// 창을 껐다 킴 / 새로고침 -> 로컬 스토리지에 정보가 있다면 해당 정보를 알아서 생성 (이벤트 발생과는 무관)
function init() {
  const userTodos = JSON.parse(localStorage.getItem("todos")); // 저장된 데이터 가져와 객체로 파싱

  if (userTodos) {
    // 존재할 때만
    userTodos.forEach((todo) => addItem(todo)); // 데이터들 자동으로 화면에 추가
    todos = userTodos; // 배열에 넣어줌
  }
}

init();
form.addEventListener("submit", handler);
반응형