1) 코드 실습
1-1) 숫자 증감기
1-2) 댓글(Create / Read)
1) 코드 실습
1-1) 숫자 증감기
코드 설계
/*
Counter 예제
처음에는 "0"으로 값이 설정(초기화)되어 있어야 함
"+" 버튼을 생성해야 함
"-" 버튼을 생성해야 함
"+" 버튼을 누르면 1씩 증가하도록 이벤트를 걸어줘야 함
"-" 버튼을 누르면 1씩 감소하도록 이벤트를 걸어줘야 함
1. 화면 그리기(html 구성 작업)
2. 어떻게 구성할지 고민
3. 입력값이 무엇인지 살펴볼 계획
*/
// 첫번째 형태
const display = document.querySelector("#counter");
const incrementBtn = document.querySelector("#increment");
const decrementBtn = document.querySelector("#decrement");
let num = 0;
display.innerHTML = num;
incrementBtn.addEventListener("click", function () {
display.innerHTML = ++num;
});
decrementBtn.addEventListener("click", function () {
display.innerHTML = --num;
});
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" />
<title>Document</title>
</head>
<body>
<h1>
Value :
<span id="counter"></span>
</h1>
<button id="increment">+</button>
<button id="decrement">-</button>
<script type="text/javascript">
const display = document.querySelector("#counter");
const incrementBtn = document.querySelector("#increment");
const decrementBtn = document.querySelector("#decrement");
let num = 0;
display.innerHTML = num;
function handler(e) {
// e.target: e.target은 Element이기에 데이터 타입은 객체이다!!
if (e.target.id === "increment") {
++num;
} else {
--num;
}
display.innerHTML = num;
}
// 바로 위의 if 조건문을 삼항연산자로 변형한 코드(출력결과는 동일함!!)
// display.innerHTML = e.target.id === 'increment' ? ++num : --num;
incrementBtn.addEventListener("click", handler);
decrementBtn.addEventListener("click", handler);
</script>
</body>
</html>
+) index2.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>
</head>
<body>
<ul>
<li id="menu1">메뉴1</li>
<li id="menu2">메뉴2</li>
<li id="menu3">메뉴3</li>
<li id="menu4">메뉴4</li>
<li id="menu5">메뉴5</li>
</ul>
<script type="text/javascript">
const ulElement = document.querySelector("ul");
function handler(e) {
console.log(e.target);
}
ulElement.addEventListener("click", handler);
</script>
</body>
</html>
1-2) 댓글(Create / Read)
※ 댓글 구현 목적 - "CRUD"를 연습하기 위함!!
1. 댓글을 입력할 수 있다. (Create)
- 댓글 입력 폼에 내용을 입력한 뒤 'submit' 버튼을 누르면 리스트에 추가되도록 함
- 만일 입력 폼이 비어있는 상태에서 'submit' 버튼을 누르면 경고 팝업을 띄움(alert or modal)
- 댓글이 성공적으로 처리되면 입력 폼을 'reset'함
2. 댓글을 리스트로 볼 수 있다. (Read)
- 댓글 내용은 '아이디', '댓글내용', '날짜'로 표현함
- 댓글 리스트는 최신순으로 나타냄(가장 최근의 댓글이 맨 상단으로 올라오도록 한다는 의미)
- 댓글 총 갯수를 나타냄
- 댓글 삭제를 위한 삭제 버튼을 생성함
3. 댓글을 수정할 수 있다. (Update)
- 댓글 리스트에서 내용을 '클릭'하면 input box로 변경됨
- input value 값의 경우, '클릭한 내용'을 유지함(내용 수정 시 기존의 내용을 일단 띄워주고 거기서 수정을 하도록 한다는 의미)
- input 내용의 경우, 'enter'를 누르면 수정사항을 저장함
4. 댓글을 삭제할 수 있다. (Delete)
- 해당 리스트의 삭제 버튼을 '클릭'하면 안내창을 띄우도록 함
- 안내창에서 확인 버튼을 누르면 삭제를 진행함
- 안내창에서 취소 버튼을 누르면 아무런 수정을 하지 않음
설명
기본적으로 CRUD는 작업 진행 시 'C(Create)'를 가장 먼저 작업함!
Create 작업 시 Read와 연관성이 높음!
데이터를 어떻게 저장하는지까지가 Create의 범위이다!!
즉, 리스트에 어떻게 뿌려질지 생각하면서 변수를 어떻게 넣을지 고려하는 것이 Create의 범위이다!!
Create 설명
Object, Array >> 변수 하나에 데이터를 여러 개 담을 수 있음!!
객체와 배열을 같이 사용해야 하는 상황(배열 안에 복수 개의 객체를 담은 형태)이다! >> 'Object[]'
리스트를 표현할 때는 배열이 좋고,
하나의 댓글에 내용을 표현할 시에는 객체가 좋음!
따라서 데이터 타입이 'Object[]'가 될 것 같음!!
const list = [
{
userid : 'web7722',
comment : '내용을 입력할 공간',
date : '2022-11-15'
},
{
userid : 'web7722',
comment : '내용을 입력할 공간',
date : '2022-11-15'
},
{
userid : 'web7722',
comment : '내용을 입력할 공간',
date : '2022-11-15'
},
]
// 문제
// 학생을 객체로 표현하시오.
// 문제
// 학생 리스트를 만드시오.
const students = [];
const person = {
name : '황상범',
age : 27,
}
const person2 = {
name : '장준영',
age : 28,
}
students.push(person);
students.push(person2);
생성자 함수
function Person(name, age) {
// this = {}
this.name = name
this.age = age
// return this
}
const person1 = new Person('황상범', 27);
const person2 = new Person('장준영', 28);
students.push(person1, person2);
Class
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
const person1 = new Person('황상범', 27);
const person2 = new Person('장준영', 28);
students.push(person1, person2);
Read 설명
어떤 데이터를 보여줄 것인지
const list = [
{userid: 'web7722', content: '안녕하세요1', date: '2022-11-15'},
{userid: 'web7722', content: '안녕하세요2', date: '2022-11-15'},
{userid: 'web7722', content: '안녕하세요3', date: '2022-11-15'}
]
어떤 형태로 표현할 것인지
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요1</li>
<li class="comment-date">2022-11-15</li>
</ul>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요2</li>
<li class="comment-date">2022-11-15</li>
</ul>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요3</li>
<li class="comment-date">2022-11-15</li>
</ul>
그리고 난 뒤 Javascript를 통해서
<ul>
<li></li>
<li></li>
<li></li>
</ul>
아래와 같이 만들 수 있는가
const ul = document.createElement('ul');
const li1 = document.createElement('li');
const li2 = document.createElement('li');
const li3 = document.createElement('li');
ul.append(li1);
ul.append(li2);
ul.append(li3);
ul.setAttribute('class', 'comment-row');
li1.setAttribute('class', 'comment-id');
li2.setAttribute('class', 'comment-content');
li3.setAttribute('class', 'comment-date');
const obj1 = {};
const obj2 = {};
const obj3 = {};
obj2.name = 'sangbeom';
console.log(obj1.name); // undefined
<ul>
<li></li>
<li></li>
<li></li>
</ul>
comment.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>
<link rel="stylesheet" href="./public/css/comment.css" />
</head>
<body>
<div>
<ul class="comment">
<li class="comment-form">
<form id="commentFrm">
<h4>
댓글쓰기
<span></span>
</h4>
<span class="ps_box">
<input
type="text"
placeholder="댓글 내용을 입력해주세요."
class="int"
name="content"
/>
</span>
<input type="submit" class="btn" value="등록" />
</form>
</li>
<li id="comment-list">
<!-- const list = [ {userid: 'web7722', content: '안녕하세요1', date:
'2022-11-15'}, {userid: 'web7722', content: '안녕하세요2', date:
'2022-11-15'}, {userid: 'web7722', content: '안녕하세요3', date:
'2022-11-15'} ]
createElement >>
-->
<!-- <ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요1</li>
<li class="comment-date">2022-11-15</li>
</ul>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요2</li>
<li class="comment-date">2022-11-15</li>
</ul>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요3</li>
<li class="comment-date">2022-11-15</li>
</ul> -->
</li>
</ul>
</div>
<script src="./public/js/comment.js" type="text/javascript"></script>
</body>
</html>
comment.css
* {
margin: 0;
padding: 0;
}
ul,
li {
list-style: none;
}
.comment {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
padding: 30px;
width: 600px;
margin: 0 auto;
}
.comment > li {
margin-top: 20px;
}
.comment > li:nth-child(1) {
margin: 0px;
}
.comment-row {
display: flex;
justify-content: space-between;
flex-direction: row;
}
.comment-row {
margin-top: 20px;
width: 100%;
}
.comment-row > li:nth-child(2) {
flex-shrink: 0;
flex-grow: 1;
padding-left: 25px;
z-index: 1;
width: 100%;
}
.comment-row > li:nth-child(2) {
width: 85px;
}
.comment-form > form {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.comment-form > form > h4 {
width: 100%;
margin: 14px 0 14px 0;
}
.comment-content {
word-break: break-all;
padding-right: 25px;
}
.ps_box {
display: block;
position: relative;
width: 80%;
height: 51px;
border: solid 1px #dadada;
padding: 10px 14px 10px 14px;
background: #fff;
box-sizing: border-box;
}
.ps_box > input {
outline: none;
}
.int {
display: block;
position: relative;
width: 100%;
height: 29px;
padding-right: 25px;
line-height: 29px;
border: none;
background: #fff;
font-size: 15px;
box-sizing: border-box;
z-index: 10;
}
.btn {
width: 18%;
padding: 18px 0 16px;
text-align: center;
box-sizing: border-box;
text-decoration: none;
border: none;
background: #333;
color: #fff;
font-size: 14px;
}
.comment-delete-btn {
display: inline-block;
margin-left: 7px;
cursor: pointer;
}
.comment-update-input {
border: none;
border-bottom: 1px solid #333;
font-size: 16px;
color: #666;
outline: none;
}
comment.js
// input value console 찍기
// Read
const form = document.querySelector("#commentFrm");
const total = document.querySelector("h4 > span");
const commentList = document.querySelector("#comment-list");
const list = [];
function Comment(content) {
this.userid = "web7722";
this.content = content;
this.date = "2022-11-15";
}
function totalRecord() {
total.innerHTML = `(${list.length})`; // 템플릿 리터럴
// total.innerHTML = "(" + list.length + ")"; // 바로 위의 코드를 "+" 연산자를 써서 문자열을 더해준 방식(실행 결과는 동일함!!)
}
function createRow(userid, content, date) {
const ul = document.createElement("ul");
const li1 = document.createElement("li");
const li2 = document.createElement("li");
const li3 = document.createElement("li");
ul.append(li1);
ul.append(li2);
ul.append(li3);
ul.setAttribute("class", "comment-row");
li1.setAttribute("class", "comment-id");
li2.setAttribute("class", "comment-content");
li3.setAttribute("class", "comment-date");
li1.innerHTML = userid;
li2.innerHTML = content;
li3.innerHTML = date;
return ul;
}
// 해당 drawing 함수 코드는 비효율적임 >> 그렇기에 react를 배우는 것임!!
function drawing() {
commentList.innerHTML = "";
// for 문을 반대로 돌림으로써 원래 의도한대로 댓글이 가장 최신 것이 맨 상단에 올라오도록 처리함
// 만일 아래 코드와 달리 for 문을 정방향으로 돌리게 된다면 최신 댓글이 맨 아래에 쌓이게 되는 구조가 형성됨
for (let i = list.length - 1; i >= 0; i--) {
// console.log(list[i].userid, list[i].content, list[i].date); // Object
const row = createRow(list[i].userid, list[i].content, list[i].date);
commentList.append(row);
}
}
function submitHandler(e) {
// 여기서 "submit" 버튼의 경우, 누를 시 url 주소가 바뀌며 웹 페이지 render가 다시 진행되기에 화면이 바뀌는, 즉 다시 웹 페이지가 load되기에 해당 함수가 동작하지 않는 것처럼 보임!!
// 따라서 자바스크립트를 통해 해당 submit 기능, 즉 form element의 기능을 막아야 하므로 "e.preventDefault();"를 사용함!!
e.preventDefault();
// 여기사 e.target은 form element를 의미함!!
const input = e.target.content;
// console.log(e.target); // Object(form Element가 들어감!!)
// console.log(e.target.content) // Object(input Element가 들어감!!)
if (input.value === "") {
alert("내용을 넣고 등록해주시기 바랍니다!");
return;
}
// console.log(input.value); // console.log(e.target.content.value);
const instance = new Comment(input.value);
list.push(instance);
totalRecord();
// const ulElement = createRow(input.value);
// commentList.append(ulElement);
drawing();
e.target.reset();
}
form.addEventListener("submit", submitHandler);
'DOM' 카테고리의 다른 글
DOM 기초(9) - 댓글 구현 기능 보강(CRUD), 게시판 기초 (0) | 2022.11.17 |
---|---|
DOM 기초(8) - 댓글 구현(CRUD) (0) | 2022.11.16 |
DOM 기초(6) - 메뉴 / 서브메뉴, 이미지 슬라이드, 로또 (0) | 2022.11.14 |
DOM 기초(5) - 이미지 슬라이드, preview / next 버튼 구현 (0) | 2022.11.11 |
DOM 기초(4) - setTimeout, setInterval, single thread, event loop (0) | 2022.11.10 |