728x90
[JS] westagram - 댓글 게시 기능 구현
메인 페이지 내에서 피드에 댓글을 다는 기능을 구현하였다.
쉽게 말해서 해당 댓글 게시 기능은 사용자가 입력한 input값을 담은 요소가 새로 생성되는 것이다.
Check List ✅
- 사용자가 원하는 내용의 댓글을 입력할 수 있도록 input 요소가 있어야 한다. => input ❌, textarea ⭕️
input으로 구성하려던 도중 인스타그램의 경우 textarea로 구성되어 있었다. 생각해보니 사용자가 정말 긴 내용을 코멘트로 달 수도 있었다. 실제로 인스타그램에서는 많은 양의 내용을 담은 코멘트를 다는 사용자도 있으니 필요한 부분이었다. - 사용자가 댓글을 입력을 할 때에만 게시 버튼이 활성화 되어야 한다.
keyup 이벤트를 줘서 사용자가 입력하면 게시 버튼을 바로 활성화 시켜준다. - 사용자가 게시 버튼을 누르면 댓글이 바로 생성되어야 한다.
- 사용자가 게시 버튼을 누르지 않고 Enter 키를 누를 수도 있으므로 해당 이벤트도 함께 포함시킨다.
구현한 모습 🎁
작성한 코드 ⚙️
HTML
<body>
<div id="container">
<header class="main_header">
<div class="header_content">
<h1 id="logo">westagram</h1>
<section class="search_wrap">
<i class="fas fa-search fa-xs"></i>
<input type="text" placeholder="검색">
</section>
<nav>
<div class="nav_content">
<ul>
<li>
<a href="#"><i class="fas fa-home fa-lg"></i></a>
</li>
<li>
<a href="#"><i class="far fa-paper-plane fa-lg"></i></a>
</li>
<li>
<a href="#"><i class="far fa-plus-square fa-lg"></i></a>
</li>
<li>
<a href="#"><i class="far fa-compass fa-lg"></i></a>
</li>
<li>
<a href="#"><i class="far fa-heart fa-lg"></i></a>
</li>
<li class="header_my_profile">
<a href="#"><img
src="https://images.unsplash.com/photo-1617198420518-e2b79c2cdbb2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1064&q=80"
alt="my profile img"></a>
</li>
</ul>
</div>
</nav>
</div>
</header>
<main>
<div class="main_wrap">
<section class="feed_wrap">
<div class="users_story">
<div class="users_story_content">
<div>
<div class="arrows">
<i class="fas fa-chevron-left"></i>
<i class="fas fa-chevron-right"></i>
</div>
<ul class="story">
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>kangheewon</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>kangminhee</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt=""></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
<li>
<div><img class="circle_profile_img" src="" alt="story_user_profile_img"></div>
<em>dlwlrma_</em>
</li>
</ul>
</div>
</div>
</div>
<section class="users_feed_list">
<article class="user_feed">
<header>
<section class="user_profile">
<div><img src="https://images.unsplash.com/photo-1617198420518-e2b79c2cdbb2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1064&q=80"
alt="user profile img"></div>
<em>kangheewon</em>
</section>
<i class="feed_handler fas fa-ellipsis-h fa-1x"></i>
</header>
<ul class="feed_imgs">
<li><img src="https://images.unsplash.com/photo-1633113212875-8ecf30ad2e81?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80" alt="feed_img1"></li>
</ul>
<ul class="feed_img_dots">
<li></li>
<li class="active_feed_dots"></li>
</ul>
<section class="feed_reaction">
<span><i class="far fa-heart fa-2x"></i></span>
<span><i class="far fa-comment fa-2x"></i></span>
<span><i class="far fa-paper-plane fa-2x"></i></span>
<span><i class="far fa-bookmark fa-2x"></i></span>
</section>
<a href="#" class="like_people">좋아요 <em>12,020개</em></a>
<section class="feed_desc_wrap">
<div class="user_desc">
<em>kangheewon</em>
<span>hello world 🌏</span>
</div>
<a href="#" class="more_comment">댓글 <b>120개</b> 모두 보기</a>
<ul class="comment_list">
<li>
<div class="user_desc">
<em>dlwlrmaa</em>
<span>우와 멋지다!!</span>
</div>
<button><i class="far fa-heart fa-xs"></i></button>
</li>
<li>
<div class="user_desc">
<em>taeyeon_ss_</em>
<span>✨</span>
</div>
<button><i class="far fa-heart fa-xs"></i></button>
</li>
</ul>
<time class="before_post">1일 전</time>
</section>
<section class="post_comment_wrap">
<button class="emoji"><i class="far fa-smile fa-2x"></i></button>
<input id="post_comment_input" type="text" placeholder="댓글 달기..." />
<button class="post_comment_btn">게시</button>
</section>
</article>
</section>
</section>
<aside class="recommend_aside">
<div id="my_profile">
<div class="profile_img">
<img src="https://images.unsplash.com/photo-1617198420518-e2b79c2cdbb2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1064&q=80"
alt="user profile img">
</div>
<div class="my_info">
<em>kangheewon</em>
<span class="my_desc">후론트라라라 👩🏻💻</span>
</div>
<button class="my_transform">전환</button>
</div>
<section class="recommend_me">
<div class="title">
<h4>회원님을 위한 추천</h4>
<button>모두 보기</button>
</div>
<ul class="users_list">
<li>
<div class="recommend_user_img">
<img class="circle_profile_img" src="" alt="recommend_user_profile_img">
</div>
<div class="recommend_user_title">
<em>allabout_jungmin</em>
<span class="recommand_desc">회원님을 위한 추천</span>
</div>
<button>팔로우</button>
</li>
<li>
<div class="recommend_user_img">
<img class="circle_profile_img" src="" alt="recommend_user_profile_img">
</div>
<div class="recommend_user_title">
<em>memo04.50</em>
<span class="recommand_desc">dlwlrma님 외 1명이 팔로우합니다</span>
</div>
<button>팔로우</button>
</li>
<li>
<div class="recommend_user_img">
<img class="circle_profile_img" src="" alt="recommend_user_profile_img">
</div>
<div class="recommend_user_title">
<em>meaning_0</em>
<span class="recommand_desc">adulkid님 외 1명이 팔로우합니다</span>
</div>
<button>팔로우</button>
</li>
<li>
<div class="recommend_user_img">
<img class="circle_profile_img" src="" alt="recommend_user_profile_img">
</div>
<div class="recommend_user_title">
<em>iilihelloili</em>
<span class="recommand_desc">WEstagram 신규 가입</span>
</div>
<button>팔로우</button>
</li>
</ul>
</section>
<footer>
<div class="footer_link_list">
<a href="#">소개</a>
<a href="#">도움말</a>
<a href="#">홍보 센터</a>
<a href="#">API</a>
<a href="#">채용 정보</a>
<a href="#">개인정보처리방침</a>
<a href="#">약관</a>
<a href="#">위치</a>
<a href="#">인기 계정</a>
<a href="#">해시태그</a>
<a href="#">언어</a>
</div>
<address>© 2021 INSTAGRAM FROM META</address>
</footer>
</aside>
</div>
</main>
</div>
<script src="./js/main.js"></script>
</body>
JS
'use strict';
const postCommentInFeed = () => {
const commentInput = document.getElementById('post_comment_input');
const commentPostBtn = document.getElementsByClassName('post_comment_btn')[0];
// 댓글 입력시 요소 생성
const addNewComment = () => {
const newCommentLocation = document.getElementsByClassName('comment_list')[0];
const newComment = document.createElement('li');
newComment.innerHTML = `
<div class="user_desc">
<em>iAmUser</em>
<span>${commentInput.value}</span>
</div>
<button><i class="far fa-heart fa-xs"></i></button>
`;
newCommentLocation.appendChild(newComment);
commentInput.value = '';
}
// 사용자 입력 들어올 시, 게시 버튼 활성화
commentInput.addEventListener('keyup', () => {
commentInput.value ? commentPostBtn.style.opacity = '1' : commentPostBtn.style.opacity = '.3';
if (window.event.keyCode === 13 && commentInput.value) {
addNewComment();
}
});
// 댓글 게시
commentPostBtn.addEventListener('click', () => {
if (commentInput.value) {
addNewComment();
} else {
alert('댓글이 입력되지 않았습니다 😳');
}
})
}
postCommentInFeed();
Process 🤖
댓글 게시
- 댓글 입력 시에 해당 input의 value를 담은 새로운 요소가 댓글 리스트 가장 맨 밑에 추가되어야 하므로 addNewComment라는 함수를 만들어 내용을 추가한다.
새로운 댓글(li)이 ul 부모 안에 가장 맨 밑에 새롭게 추가되어야 하므로 부모 ul 태그를 DOM으로 접근하여 변수에 담아주고 li 태그를 createElement 메소드로 만든다. - 안에 해당 요소가 많으므로 innerHTML로 댓글을 구성하는데 필요한 요소들을 모두 불러온다.
그 중 유저의 아이디는 우선 임의로 설정해두고, 유저가 input에 입력한 값을 불러와서 보여주기 위해 ${commentInput.value}로 보여줄 수 있도록 한다. - 필요한 모든 요소를 담은 li태그를 ul 부모 안에 붙여준다.
그러면 해당 함수는 이제 어떤 이벤트로 인해 동작하게 되면 ul 부모 안에 사용자가 input에 입력한 값을 담은 댓글 요소(li)가 가장 맨 밑에 생성되게 되는 것이다. - 그러면 이제 댓글이 생성되는 과정이 끝난거다. 사용자가 원하는 댓글이 모두 생성되었다면 입력한 input의 값은 사라져야 하므로 commentInput.value = ''로 빈 값을 만들어준다.
- keyup 이벤트가 실행되면 댓글을 게시할 준비가 되었다는 뜻이다. 이 때 사용자의 댓글 값이 존재하고 그런 상태에서 Enter키를 누르면 addNewComment 함수가 실행되도록 한다.
- 댓글이 생성된다.
게시 버튼 활성화
- 게시 버튼을 누르면 이벤트가 실행된다.
- 만약 input에 사용자가 입력한 값이 존재하는 상태에서 게시 버튼을 클릭 하였다면 addNewComment 함수가 실행된다.
- 댓글이 생성된다.
해결하고 싶다... 구현하고 싶다... 🤔
textarea를 적용시키고 자동으로 height가 resizing 되는거까진 해봤는데 이상하게 바로 댓글을 입력하고 빠르게 엔터를 치면 빈 문자열의 댓글이 쌍으로 생성된다. 흐아 ^^... 리액트 들어가서 한번 더 해봐야겠는데 오기가 생긴다.. 일단 아직 이 부분은 막혀있다.
728x90
'WEB > JAVASCRIPT' 카테고리의 다른 글
JS Clipboard API 클립보드 복사 (+ exeCommand) (0) | 2022.09.15 |
---|---|
[JS] 객체안에 객체에서 원하는 값만 가져오기 (feat. entries, filter) (0) | 2022.01.16 |
[JS] westagram login page (feat. 로그인 버튼 활성화&비활성화) (0) | 2021.12.07 |
[JS] ES6 (ECMA Script 2015) - arrow function (0) | 2021.12.05 |
[JS] 매개 변수(parameter)와 인자(argument) (0) | 2021.12.01 |