Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 자바스크립트 async await
- 자바스크립트 상속
- 자바스크립트 클로저
- 자바스크립트
- 자바스크립트 반복문
- 오블완
- javascript
- css display
- 자바스크립트 프로미스
- 자바스크립트 클래스
- html 코드
- javascript opreators
- front-end
- 자바스크립트 scope
- 자바스크립트 연산자
- 티스토리챌린지
- 프론트엔드
- 웹 개발 트렌드
- CSS
- 자바스크립트 스코프
- 자바스크립트 생성자 함수
- css position
- javascript closure
- 자바스크립트 promise
- HTML
- css 포지션
- 자바스크립트 실행 컨텍스트
- javascript opreator
- css3
- html 주석
Archives
- Today
- Total
Multi Developer SuHo
[자바스크립트 실습] DOM을 사용하여 댓글 구현 본문
SMALL
안녕하세요!! 이번에는 자바스크립트 DOM을 사용한 댓글을 구현하였습니다. 코드의 내용은 주석으로 설명하였습니다.
HTML 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<ul class="comment">
<li class="comment-form">
<form action="" id="comment-frm"> <!-- form 태그 : submit 이벤트를 가지고 있는 태그,
action : 요청의 내용 -->
<h4>댓글 쓰기<span>0</span></h4>
<span class="ps-box">
<input type="text" placeholder="댓글을 입력하세요" class="int" name="content">
</span>
<input type="submit" class="btn" value="등록">
</form>
<!--
form 이라는 특별한 기능을 가지고 있는 태그중 하나,
요청을 보낼 수 있는 기능을 가지고 있다. submit 이벤트가 발생하면서 일어난다.
form 태그 안에서 중요한 역할을 하는 요소는 subimt 버튼
input의 name이라는 키가 서버에 우리가 데이터를 보낼때
데이터를 보내는 형태가 json "{content : 내 입력값}"
-->
</li>
<li id="comment-list">
</li>
</ul>
</body>
<script src="./index.js"></script>
</html>
JS 코드
// 댓글의 형태가 객체
// 생성자 함수
//
/* {
uid: "",
content : "",
date : ""
}
*/
// 유저의 정보를 담는 객체
const user = {
uid : "soon",
};
const commentList = document.querySelector('#comment-list');
const commentFrm = document.querySelector('#comment-frm');
class Comment { // 객체를 생성하기 위한 Comment 클래스
constructor(content) {
this.uid = user.uid
this.content = content; // 내용이 달라질 부분
this.date = new Date(); // 글을 작성한 현재시간
}
// 값을 조회하는 메서드
getToday(text) {
// 2025 01 21 : 날짜 사이사이 들어갈 문자열을 text 매개변수로 받는다.
// 날짜의 문자열 형태를 커스텀 하는 내용이 자주 사용되니 메서드로 만들어준다.
const date = this.date; // date 객체를 가져옴
let m = date.getMonth() + 1;
let d = date.getDate();
// 배열 메서드 join
[date.getFullYear(), (m > 9 ? "": "0") + m, (d > 9 ? "" : "0")+ d].join(text) // 달이 9보다 크면 빈 문자열, 0보다 작으면 0을 붙인다.
// join() 키값은 반환값이 string 문자열로 형변환
// , 요소의 구분 부분의 텍스트를 넣어준다.
// [1,2,3].join("") === '123'
// [1,2,3].join("*") === '1*'2*3'
// (text === "-") === 2025-01-21
return [date.getFullYear(), (m > 9 ? "": "0") + m, (d > 9 ? "" : "0")+ d].join(text);
}
}
// 글을 작성했을 때 객체가 생성
// 생성자 함수가 호출된다.
// 전체 글을 담을 배열
const state = [
];
// 총 글의 갯수를 담을 객체
const setTotalRecord = () => {
const span = document.querySelector('h4>span'); // HTML 에서 h4 태그 안에 있는 span 태그를 가져와서 span 변수에 저장
span.innerHTML = state.length; // span 태그 안의 내영을 state의 배열의 길이만큼 설정
}
// 배열에 글 추가
// addstate 라는 함수에 value라는 매개변수를 받는다.
// comment 생성자 함수를 사용해서 새로운 객체를 만들고
const addstate = (value) => {
const instance = new Comment(value);
state.push(instance);
setTotalRecord();
}
// 게시글 하나 생성하는 함수
// 글 번호는 index
// index 매개변수가 필요한 이유는 배열안에서 하나씩 가져올려고
const createRow = (index) => {
// 배열에 추가된 글의 인덱스 번호를 사용하기 위해
const item = state[index]; // item : 글 하나를 담을 변수
const commentRow = document.createElement("ul");
const commentId = document.createElement("li");
const commentContent = document.createElement("li");
const comeentDate = document.createElement("li");
commentRow.classList.add("comment-row");
// data-index="0"
commentRow.dataset.index = index; // 수정이나 삭제 부분 사용할 때 index를 요소에 기록
// index라는 이름을 dataset 속성으로 만들고 내가 필요한 값을 저장, 요소에 속성값으로 저장,
// 민감한 정보는 담으면 안된다
// 스타일 작성하는 것 -> class
// 개발자가 요소에 속성의 값이 필요할 때
commentId.classList.add("comment-id");
commentId.innerHTML = item.uid;
commentContent.innerHTML = item.content;
comeentDate.classList.add("comment-date");
comeentDate.innerHTML = item.getToday('-');
commentRow.append(commentId, commentContent, comeentDate); // 자식으로 추가
return commentRow;
}
const drawing = () => {
commentList.innerHTML = ""; // 글자가 있을 수도 있으니 빈문자열로 초기화
for(let i = 0; i< state.length; i++) {
const row = createRow(i);
commentList.append(row);
}
}
// Create
const submitHandler = (e) => {
e.preventDefault(); // 요청을 막는다 -> 새로고침이 일어나지 않는다.
// 기본적인 form의 submit 요청기능을 제거
console.log("안녕")
const {content} = e.target; // input 요소의 name을 content로 작성했기 때문에 값을 가져올 수 있다.
// content : content라는 이름의 속성을 가지고 있는 input 요소 자체
const {value} = content; // 입력값
console.log(value);
addstate(value) // 배열에 객체 데이터 추가 글의 정보를 추가
drawing(); // 화면에 그리는 작업
content.value = ""
}
commentFrm.onsubmit = submitHandler; // 함수의 값을 전달
CSS 코드
CSS 코드에서는 인러랙션 효과를 주기 위해 keyframe과 애니메이션 효과를 부여했습니다.
@font-face {
font-family: 'PartialSansKR-Regular';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2307-1@1.1/PartialSansKR-Regular.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul, li {
list-style: none;
}
body {
background-color: #f4f4f4;
font-family: 'PartialSansKR-Regular';
}
.comment {
display: flex;
flex-direction: column;
padding: 30px;
width: 600px;
margin: 40px auto;
background: #fff;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
animation: fadeIn 0.8s ease-in-out;
}
.comment-form > form {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.ps-box {
display: flex;
align-items: center;
width: 78%;
height: 50px;
border: 1px solid #ccc;
padding: 10px 14px;
background-color: #fff;
border-radius: 25px;
transition: all 0.3s ease-in-out;
}
.ps-box:hover {
border-color: #007bff;
box-shadow: 0 0 8px rgba(0, 123, 255, 0.3);
}
.ps-box > input {
width: 100%;
height: 100%;
border: none;
outline: none;
font-size: 16px;
padding: 0 10px;
background: transparent;
}
.btn {
width: 20%;
height: 50px;
background-color: #007bff;
color: #fff;
font-size: 16px;
font-weight: bold;
border: none;
border-radius: 25px;
cursor: pointer;
}
.btn:active {
transform: scale(0.95);
}
.btn:hover {
background-color: #0056b3;
}
.comment-row {
width: 100%;
display: flex;
align-items: center;
padding: 8px;
border-bottom: 1px solid #ddd;
opacity: 0;
transform: translateY(10px);
animation: fadeSlideIn 0.5s ease-in-out forwards;
}
.comment-row:last-child {
border-bottom: none;
}
.comment-row li {
padding: 12px;
font-size: 14px;
color: #555;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.comment-row li:nth-child(1) {
width: 20%;
text-align: center;
font-weight: bold;
}
.comment-row li:nth-child(2) {
width: 50%;
padding: 12px;
background: #f9f9f9;
border-radius: 5px;
}
.comment-row li:nth-child(3) {
width: 30%;
text-align: center;
color: #888;
font-size: 12px;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeSlideIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
실행결과 화면
LIST
'자바스크립트 기록' 카테고리의 다른 글
[자바스크립트 비동기 문법] Promise(프로미스)란? (0) | 2025.02.04 |
---|---|
[자바스크립트 문법] 동기(Synchronous) 비동기(Asynchronous) 프로그래밍 (4) | 2025.02.03 |
[자바스크립트 문법] DOM의 사용목적과 DOM의 문법 (1) | 2025.01.21 |
[자바스크립트 정보] DOM(Document Object Model)과 DOM의 구조 🌳 (0) | 2025.01.18 |
자바스크립트 class, 메서드 축약형, ES6 화살표 함수, this bind 🔎 (0) | 2025.01.15 |