23일차[객체 응용 문제 / 실습 예제]

진하의 메모장·2025년 2월 7일
3

공부일기

목록 보기
29/66
post-thumbnail

2025 / 02 / 07

오늘 수업 시간에는 지금까지 배운 내용을 활용해서 문제를 풀어보는 시간을 가졌습니다.
다른 때와 다르게 이번에는 HTML과 CSS부분도 신경쓰고 객체와 DOM을 활용해서 자바스크립트를 동적으로 사용해보았습니다.



💌 응용 문제

동적 리스트 생성 예제

  • HTML 구조를 정의합니다.
  • CSS 스타일을 적용합니다.
  • JavaScript로 데이터를 준비합니다.
  • HTML 요소를 가져옵니다.
  • 동적으로 리스트 항목을 생성해줍니다.
  • 결과를 출력합니다.

1) HTML 구조 정의

HTML 구조를 정의합니다.

  • <h1> 태그로 환영 문구를 표시하고, <div><ul>을 통해 각각 인사 메시지와 동적으로 추가할 목록을 준비합니다.
  • <h1 class="title">은 '환영합니다.'라는 텍스트를 제목으로 표시합니다.
  • <div id="greet">는 인사 메시지가 담긴 div 태그. 나중에 JavaScript로 메시지를 동적으로 변경할 수 있습니다.
  • <ul>은 동적으로 생성되는 리스트 항목을 삽입할 ul 태그입니다.
<h1 class="title">환영합니다.</h1>
<div id="greet">good morning</div>
<ul></ul>


2) CSS 스타일 적용

CSS 스타일을 적용합니다.

  • 간단한 CSS를 사용해 페이지의 디자인을 정의합니다.
  • 각 요소에 색상을 지정하고, 기본 스타일을 설정합니다.
#greet{
    color: blue;
}

ul{
    color: red;
}

.title{
    color: seagreen;
}


3) JavaScript로 데이터 준비

JavaScript로 데이터를 준비합니다.

  • JavaScript에서 동적으로 출력할 데이터를 객체 형태로 정의합니다.
  • 각 시간대별로 해야 할 일을 배열로 만들어 data 객체에 저장합니다.
  • morning, afternoon, evening 배열은 각각 아침, 점심, 저녁에 해야 할 일을 나타냅니다.
const data = {
    morning : ["1. DOM 복습", "2. 문제 풀기"],
    afternoon : ["1. 점심먹기", "2. 잠자기"],
    evening : ["1. 오늘한 것 복습하기", "2. 내일할 것 예습하기"],
}


4) HTML 요소 가져오기

HTML 요소를 가져옵니다.

  • JavaScript로 조작할 HTML 요소를 가져옵니다.
  • getElementById와 querySelector를 사용하여 필요한 요소를 선택합니다.
  • id="greet"인 div 요소를 가져와 이곳에 인사 메시지를 동적으로 업데이트합니다.
  • ul 태그를 선택하여 동적으로 생성되는 리스트 항목을 추가합니다.
let div = document.getElementById("greet");
let ul = document.querySelector("ul");


5) 리스트 항목 생성

동적으로 리스트 항목을 생성해줍니다.

  • data.morning 배열에 저장된 항목들을 ul 태그에 동적으로 삽입합니다.
  • for 반복문을 사용해 배열의 각 항목을 <li> 태그로 만들어 ul에 추가합니다.
  • document.createElement("li") - 새로운 li 태그를 만듭니다.
  • newLi.innerHTML = data.morning[i] - li 태그 안에 data.morning[i] 값을 넣습니다.
  • ul.appendChild(newLi) - 만들어진 li 태그를 ul에 자식 요소로 추가합니다.
  • data.morning 배열에 있는 각 항목에 대해 반복적으로 수행됩니다.
for(let i = 0; i < data.morning.length; i++){
    let newLi =  document.createElement("li");
    newLi.innerHTML = data.morning[i];
    console.log(newLi); // 출력 : 1. DOM 복습

    ul.appendChild(newLi);
}


6) 결과 출력

결과를 출력합니다.

  • 스크립트가 실행되면 greet라는 div 태그에 있는 텍스트는 그대로 "good morning"으로 유지되고, ul 태그에는 data.morning 배열에 있는 두 항목—"1. DOM 복습", "2. 문제 풀기"—이 각각 <li> 태그로 추가됩니다.


💌 전체 코드

  • 위의 코드를 하나로 합쳐놓은 것입니다.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #greet{
            color: blue;
        }

        ul{
            color: red;
        }

        .title{
            color: seagreen;
        }
    </style>
</head>
<body>
    <h1 class="title">환영합니다.</h1>
    <div id="greet">good morning</div>
    <ul></ul>
    <script>
        // 사용할 데이터를 객체화하기
        const data = {
            morning : ["1. DOM 복습", "2. 문제 풀기"],
            afternoon : ["1. 점심먹기", "2. 잠자기"],
            evening : ["1. 오늘한 것 복습하기", "2. 내일할 것 예습하기"],
        }

        // 현재 HTML 태그를 객체화
        document;


        // 가지고 오고 싶은 아이디를 문자열 형태로 적습니다.
        let div = document.getElementById("greet");
        console.log(div); // 출력 : <div id="greet">good morning</div>


        // // 조건에 따라 출력 되는 문구 수정하기
        // if(아침){
        //     div.innerHTML= "good morning";
        // }else if(점심){
        //     div.innerHTML= "good afternoon";
        // }else{
        //     // 문자열 안에 태그를 인식한다.
        //     div.innerHTML = "<p style = 'color = red;'> good evening </p>";

        //     // 문자열 안에 태그를 인식하지 않는다.
        //     div.textContent = "<p style = 'color = red;'> good evening </p>";
        // }


        // 태그(요소) 생성하기

        // 만든 태그를 넣어줄 부모 태그(요소) 가져오기
        let ul = document.querySelector("ul");

        for(let i = 0; i < data.morning.length; i++){

            // 만들고 싶은 태그의 이름을 안에 작성합니다.
            let newLi =  document.createElement("li");
            newLi.innerHTML = data.morning[i];
            console.log(newLi); // 출력 : 1. DOM 복습

            // 부모요소를 담은 변수에 만들어 둔 li를 넣어줍니다.
            ul.appendChild(newLi);
        }
    </script>
</body>
</html>


💌 실습 예제

랜덤 명언 생성기 만들기

  • HTML 구조를 정의합니다.
  • CSS로 스타일링을 진행합니다.
  • javascript 객체로 데이터를 저장합니다.
  • 랜덤 명언 출력 함수를 생성합니다.
  • 명언의 리스트를 볼 수 있도록 해줍니다.(다이얼로그 사용)
  • 명언을 추가할 수 있는 기능을 만듭니다.

1) HTML 구조 정의

HTML 구조를 정의합니다.

  • HTML은 만들고자 하는 프로그램의 뼈대 역할을 합니다.
  • 명언을 보여주고, 명언을 추가할 수 있는 입력창과 버튼을 제공합니다.

랜덤 명언 보기 버튼

  • 클릭 시 random( ) 함수가 실행되어 새로운 명언을 화면에 출력합니다.

명언 리스트 보기 버튼

  • 클릭 시 dialog 창을 열어 모든 명언 리스트를 보여줍니다.

명언 추가 박스

  • 사용자가 새로운 명언과 사람 이름을 입력하고 '추가하기' 버튼을 클릭하여 목록에 추가할 수 있습니다.
<div class="box">
  <h1>💌 랜덤 명언 생성기</h1>
  <div class="border">
    <div class="inner">
      <h2>명언</h2>
      <span>사람 이름</span>
    </div>
    <button onclick="random()">새 명언 보기</button>
    <button class="showButton">명언 리스트 보기</button>
    <dialog id="dialog">
      <b>< 현재 명언 리스트 ></b>
      <p class="list">여기 명언 리스트를 보여주세요!</p>
      <form method="dialog">
        <button class="close">OK</button>
      </form>
    </dialog>
  </div>
  <div class="add_box">
    <h3>명언 추가</h3>
    <div class="inner">
      <span>명언 : </span><input type="text" id="text_box1" /> <br />
      <span>사람 : </span><input type="text" id="text_box2" />
    </div>
    <button class="add" onclick="add()">추가하기</button>
  </div>
</div>


2) CSS 스타일링

CSS로 스타일링을 진행합니다.

  • 애플리케이션의 레이아웃과 디자인을 꾸미는 CSS입니다.

글꼴 지정

  • 사용자 지정 폰트를 사용하기 위해 @font-face로 폰트를 임포트합니다.

전체 레이아웃

  • .box 클래스를 사용해 중앙 정렬된 구조로 레이아웃을 설정하고, .inner 클래스로 명언을 표시할 영역의 스타일을 정의합니다.

버튼 및 다이얼로그 스타일

  • 버튼과 다이얼로그 스타일을 설정하여 UI가 보기 좋게 꾸며집니다.
@font-face {
  font-family: "Katuri";
  src: url("https://gcore.jsdelivr.net/gh/projectnoonnu/noonfonts_13@1.0/Katuri.woff") format("woff");
  font-weight: normal;
  font-style: normal;
}

@font-face {
  font-family: "Ownglyph_corncorn-Rg";
  src: url("https://fastly.jsdelivr.net/gh/projectnoonnu/2412-1@1.0/Ownglyph_corncorn-Rg.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
}

* {
  margin: 0;
  padding: 0;
}

.box {
  width: 800px;
  margin: 0 auto;
  text-align: center;
  margin-bottom: 50px;
}

.inner {
  background-color: rgb(255, 255, 255);
  padding: 30px;
  line-height: 30px;
  width: 600px;
  margin: 0 auto;
  border-radius: 20px;
}

h1 {
  margin: 40px 0 20px 0;
}

h2 {
  margin: 10px 0px;
  font-family: "Katuri";
  font-weight: 200;
}

span {
  font-family: "Ownglyph_corncorn-Rg";
  font-size: 18px;
}

.border {
  border: solid 2px black;
  border-radius: 10px;
  padding: 40px 20px;
  background-color: rgb(214, 245, 255);
  margin-bottom: 20px;
}

button {
  margin-top: 30px;
  width: 200px;
  height: 50px;
  border-radius: 20px;
  border: solid 1px rgb(39, 39, 39);
  font-size: 18px;
  font-family: "Ownglyph_corncorn-Rg";
  line-height: 55px;
}

button:hover {
  background-color: rgb(132, 174, 188);
  color: white;
}

dialog {
  width: 700px;
  height: 300px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 10px;
  padding: 50px 30px 0 30px;
  background-color: #fff;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  overflow: auto;
}

dialog p.list {
  font-family: "Ownglyph_corncorn-Rg";
  font-size: 16px;
  line-height: 1.6;
  color: #333;
  white-space: pre-line;
}

form {
  display: flex;
  justify-content: center;
}

button.close {
  font-family: "Ownglyph_corncorn-Rg";
  font-size: 16px;
  border: none;
  border-radius: 10px;
  margin-bottom: 30px;
  background-color: #4caf50;
  color: white;
  cursor: pointer;
}

button.close:hover {
  background-color: #45a049;
}

::backdrop {
  background-color: black;
  opacity: 0.4;
}

.add_box {
  width: 760px;
  margin: 0 auto;
  text-align: center;
  padding: 20px;
  background-color: #c5ffc7;
  border: solid 2px black;
  border-radius: 10px;
}

h3 {
  margin: 20px;
}

input {
  font-family: "Ownglyph_corncorn-Rg";
  width: 200px;
  height: 20px;
}

b {
  font-size: 20px;
  font-family: "Ownglyph_corncorn-Rg";
}

.list {
  margin-top: 10px;
  margin-bottom: 10px;
}


3) 데이터 저장하기

javascript 객체로 데이터를 저장합니다.

  • say 객체는 우리가 사용할 데이터들을 모아두는 곳입니다.
  • srting : 명언들을 저장한 배열입니다.
  • person : 명언을 말한 사람들의 이름을 저장한 배열입니다.
  • image : 각 명언에 맞는 이미지를 저장한 배열입니다.
  • default : 기본 이미지를 설정해 놓은 변수입니다.
const say = {
  saying: {
    srting: [
      "삶이 있는 한 희망은 있다",
      "후회없는 하루를 보내야 한다",
      "산다는것 그것은 치열한 전투이다",
      "언제나 현재에 집중할 수 있다면 행복할 것이다",
      "저만의 낭만과 감성을 간직하고 있는 사람이 되고 싶어요",
    ],
    person: [
      "키케로",
      "진예희",
      "로맹롤랑",
      "파울로 코엘료",
      "보이넥스트도어 성호",
    ],
    image: ["img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg"],
    default: "img.jpg",
  },
};


4) 랜덤 명언 출력 함수

랜덤 명언 출력 함수를 생성합니다.

랜덤 숫자 생성

  • Math.random( )을 사용하여 0과 1 사이의 랜덤한 숫자를 만들고, Math.floor( )로 내림을 해서 say.saying.person 배열의 길이만큼 랜덤 숫자를 생성합니다.
  • 이 숫자를 이용해 명언과 이미지를 선택합니다.

기존 이미지 삭제

  • 화면에 기존 이미지가 있으면 삭제합니다.
  • document.querySelector(".inner img")로 .inner 안에 있는 <img> 요소를 찾고, 있으면 remove( )로 제거합니다.

새 이미지 생성

  • 랜덤으로 선택된 이미지를 <img> 태그로 생성하고, 스타일을 추가한 후 명언 위에 삽입합니다.

명언과 사람 이름 출력

  • ran_saying.innerHTML에 랜덤 명언을, ran_person.innerHTML에 해당 명언을 말한 사람 이름을 넣습니다.
function random() {
  // 0부터 person 배열 길이까지의 랜덤 숫자 생성
  let ran = Math.floor(Math.random() * say.saying.person.length);

  let ran_saying = document.querySelector("h2");
  let ran_person = document.querySelector("span");

  // 기존에 있던 이미지가 있다면 삭제
  let existingImg = document.querySelector(".inner img");
  if (existingImg) {
    existingImg.remove();
  }

  // 새로운 이미지를 생성
  let img = document.createElement("img");
  img.src = say.saying.image[ran] || say.saying.default; // 랜덤 이미지 선택
  img.style = "width: 300px; height: 250px; padding: 20px; margin-bottom: 20px;";

  // 이미지를 명언 위에 추가
  let innerDiv = document.querySelector(".inner");
  innerDiv.insertBefore(img, ran_saying); // 명언 앞에 이미지 삽입

  // 명언과 사람 이름 업데이트
  ran_saying.innerHTML = say.saying.srting[ran]; // 랜덤 명언
  ran_person.innerHTML = say.saying.person[ran]; // 랜덤 사람 이름
}


5) 명언 리스트 보기

명언의 리스트를 볼 수 있도록 해줍니다.(다이얼로그 사용)

infor_list( ) 함수

  • 이 함수는 현재 저장된 모든 명언을 하나의 문자열로 합쳐서 반환합니다.
  • for 문을 이용하여 say.saying.srting과 say.saying.person 배열의 값을 하나씩 이어 붙입니다.

명언 리스트 보기 버튼

  • showButton.addEventListener는 "명언 리스트 보기" 버튼을 클릭했을 때 발생할 이벤트입니다.
  • 버튼 클릭 시 dialog에 명언 리스트를 보여주고 다이얼로그 창을 열어줍니다.

닫기 버튼

  • closeButton.addEventListener는 다이얼로그 창 안에 있는 "OK" 버튼을 클릭했을 때, 다이얼로그 창을 닫는 역할을 합니다.
const dialog = document.querySelector("dialog");
const showButton = document.querySelector(".showButton");
const closeButton = document.querySelector(".close");

// 명언 리스트를 텍스트로 반환하는 함수
function infor_list() {
  let infor = "";
  for (let i = 0; i < say.saying.person.length; i++) {
    infor += `${say.saying.srting[i]} - ${say.saying.person[i]}\n`;
  }
  return infor;
}

// 명언 리스트 보기 버튼 클릭 시 다이얼로그 표시
showButton.addEventListener("click", () => {
  dialog.querySelector("p").innerText = infor_list(); // 명언 리스트 업데이트
  dialog.showModal(); // 다이얼로그 창 열기
});

// 다이얼로그 창 닫기 버튼 클릭 시 닫기
closeButton.addEventListener("click", () => {
  dialog.close(); // 다이얼로그 창 닫기
});


6) 명언 추가

명언을 추가할 수 있는 기능을 만듭니다.

명언과 사람 이름 입력 받기

  • 사용자가 입력한 명언과 사람 이름을 각각 text_box1, text_box2에서 가져옵니다.

명언과 사람 이름 추가

  • 만약 명언과 사람 이름 모두 입력되었으면, say.saying.srting 배열과 say.saying.person 배열에 새로운 명언과 사람 이름을 push( ) 메서드를 사용하여 추가합니다.

입력창 비우기

  • 명언과 사람 이름을 추가한 후, 입력창을 비워줍니다.
  • add_string.value = ""와 add_person.value = ""로 각각의 입력 필드를 초기화합니다.
function add() {
  let add_string = document.getElementById("text_box1");
  let add_person = document.getElementById("text_box2");

  // 명언과 사람 이름이 모두 입력되었을 경우
  if (add_string.value && add_person.value) {
    say.saying.srting.push(add_string.value); // 명언 추가
    say.saying.person.push(add_person.value); // 사람 이름 추가
  } else {
    alert("다시 입력하세요!!"); // 명언 또는 사람 이름이 비었을 경우 알림
  }

  // 입력창 비우기
  add_string.value = "";
  add_person.value = "";
}


7) 전체 흐름 요약

랜덤 명언 보기

  • 사용자가 "새 명언 보기" 버튼을 클릭하면 random( ) 함수가 실행되어 무작위로 명언을 보여줍니다.

명언 리스트 보기

  • "명언 리스트 보기" 버튼을 클릭하면 모든 명언을 다이얼로그 창에 표시하고, 그 목록을 보여줍니다.

명언 추가

  • 사용자가 명언과 사람 이름을 입력한 후 "추가하기" 버튼을 클릭하면 새로운 명언이 목록에 추가됩니다.


💌 결과 보기

  • 전체 코드는 너무 길어서 생략하였습니다.
  • 명언들의 사진은 햄스터 / 청설모 / 다람쥐 사진으로 들어가있습니다.
  • 추가되는 명언들의 사진은 디폴트 값으로 고양이 사진을 넣어주었습니다.




23일차 후기

  • 처음 실습 문제를 받았을 때는 막막했는데, 하다보니 괜찮았습니다.
  • 명언 추가 부분을 만들 때 .value 값을 가져와서 변수에 담은 후 그걸 초기화 시켰는데 왜 Input에 입력한게 안사라지냐고 교수님께 바보 같은 질문을 했습니다..
  • .value을 변수에 담고 초기화하면.. 그 변수만 비워지는거니까 당연히 input 박스 안에 작성한 text는 안사라지는데.. 난 바보야~ ( °ᗝ° ).ᐟ.ᐟ
  • 그래도 CSS도 나름 꾸며주고 글꼴도 귀여운 폰트로 바꿔주었습니다.
  • 1월 초반에 비해 이해도가 좋아진 것 같아 기분이 좋습니다. ଘ(∩^o^)⊃━☆゜
profile
૮꒰ ྀི〃´꒳`〃꒱ა

0개의 댓글