-
[Assignment] 위스타그램 코딩 Chapter 2. main pageDevelope/Assignment 2020. 5. 2. 15:32
1. 시작
◎ 위스타그램 login page를 마무리하고 main page 작업을 시작하였다.
repl.it 에 있는 위스타그램 메인 페이지를 구현을 하였다.
2. 가이드
◎ html, css
-
header는 scroll 되어도 최상단에 fiexd 되어야 한다.
-
hedaer와 main은 화면의 중앙에 위치하여야 한다.
-
main을 두 개로 나누어 좌측에는 피드, 우측에는 스토리 및 팔로우 추천이 있다.
-
우측 정보들은 scroll 되어도 fiexd 되어야 한다.
-
피드는 하나만 만들어도 된다.
◎ javascript
-
댓글 input 창에 엔터 치거나 "게시"를 누르면 댓글이 추가되어야 한다.
-
createElement로 요소를 생성해서, input에 입력한 값이 추가되어야 한다.
3. 레이아웃
◎ 위스타그램 메인 페이지는 레이아웃 구현이 오래 걸렸다.(생각보다 신경 써야 할게 많았다..)
repl.it에 있는 main page 디자인을 보았다.
hedaer와 main 이 정확히 중앙에 위치하여야 하며, main안에 좌측 , 우측을 정확히 나눠야 하기 때문이다.
아이콘도 영역의 중앙에 배치하여야 하며, 프로필 이미지와 아이디 부분도 영역의 중앙에 배치해야 한다.
main page는 전체적으로 중앙에 배치하여야 하기 때문에 신경 쓸 부분이 많았다.
로그인 페이지를 구현할 때와 같이 html로 레이아웃을 먼저 구성하고 css를 작업하기 시작했다.
레이아웃만 구성한 화면이다. 이제 css를 입혀보자.
4. 코드
◎ html code
※ 내용이 많아서 전체적인 코드는 깃에서 확인할 수 있다.
<div class="wrap"> <!-- header --> <header class="header"> </header> <!-- //header --> <!-- main --> <div class="main"> <div class="container"> <!--left --> <div class="contents_left"> </div> <!--//left --> <!-- rigth --> <div class="contents_right"> <!-- aside --> <aside class="aside"> </aside> <!-- //aside --> <!-- footer --> <footer class="footer"> </footer> <!-- //footer --> </div> <!-- //rigth --> </div> </div> <!-- //main --> </div>
-
레이아웃은 크게 header, main, left, rigth로 나누었다.
-
header tag 안에는 Img 태그를 사용하여 logo를 나타내었다.
-
form태그 안에는 comment의 input, button으로 나누었다.
◎ css code
※ 내용이 많아서 전체적인 코드는 깃에서 확인할 수 있다.
/* main.css */ /* header */ .header { position: fixed; top: 0; left: 0; right: 0; z-index: 100; height: 55px; background: #fff; box-sizing: border-box; border-bottom: 1px solid #dbdbdb; } .header .header_wrap { height: 100%; max-width: 1066px; margin: 0 auto; } .header .inner { display: flex; justify-content: space-between; align-items: center; height: 100%; } /* //header */ /* main */ .main { position: relative; top: 55px; background: #f8f9fa; } .main .container { display: flex; max-width: 1066px; margin: 0 auto; padding: 30px 0; } /* 왼쪽 영역 */ .contents_left { width: 650px; box-sizing: border-box; margin-right: 40px; } /* 왼쪽 영역 */ /* 오른쪽 영역 */ .main .container .contents_right { position: fixed; left: calc(100% - 712px); width: 383px; box-sizing: border-box; } /* // 오른쪽 영역 */ /* // 메인 영역 */
-
header에 position: fiexd로 설정하여 스크롤해도 고정되게 구현하였고, z-index 속성을 주어서 메인 페이지보다 위에 나타내게 하였다.
-
.header_wrap를 가진 div에 max-width값을 주고 marign: 0 autu; 로 설정하여 영역을 중앙으로 배치하였다.
-
hedaer안에 있는 자식들이 영역 안의 중앙으로 오고 그 영역에 맞게 적절한 수평 위치를 배치하여야 하기 때문에 display: flex; justify-content: space-between; align-items: center; 로 설정하였다.
-
.main class를 가진 div에 position: relative; top: 55px; 로 설정하여 header의 높이만큼 떨어진 곳에 배치하였다.
-
.container class를 가진 div에 .header_wrap class와 같이 중앙으로 배치하여야 하기 때문에 max-width, margin을 사용하였고 좌측 영역과 오른쪽 영역을 수평으로 배치하여야 하기 때문에 display:flex를 주었다.
-
왼쪽영역 .contents_left class를 가진 div에 width값을 주어 영역을 잡아주었다.
-
오른쪽 영역 .contents_right class를 가진 div에 position: fixed;를 주고 left 값만큼 떨어진 곳에 배치하였다.
/* main.css media query */ @media only screen and (max-width: 1150px) { .contents_left { margin-left: 40px; } } @media only screen and (max-width: 800px) { .contents_right { display: none; } }
-
반응형을 조금 적용해 보고 싶어서 간단하게 작성해 보았다.
-
화면을 줄였을 때 .content_left class를 가진 div가 왼쪽으로 붙은 현상을 발견하여 max-width: 1150px로 설정하여 marin-left: 40px; 만큼 띄어주었다.
-
화면을 줄였을 때, .content_rigth class를 가진 div를 display: none;으로 설정하여 안 보이게 설정하였다.
/* common.css */ .wrap { height: 100%; } .scroll { overflow: auto; } .link_list { display: flex; align-items: center; } .link_list li { margin-left: 20px; } .link_list li:first-child { margin: 0; } .state_btn { border: none; padding: 0; width: 25px; } .state_btn img { width: 100%; } .feed_profile { display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; } .profile { display: flex; align-items: center; } .profile .profile_img { width: 40px; margin-right: 10px; border-radius: 50%; } .follow_info { margin-bottom: 10px; padding: 10px 13px; border: 1px solid #dee2e6; border-radius: 5px; background: #fff; } .follow_title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; } .follow_title span { font-size: 13px; line-height: 1.4; } .follow_title .text_tit { font-size: 15px; color: #828282; } .follow_title .sub_tit { font-weight: bold; } .follow_title a { display: block; } .follow_title a .profile_intro { font-size: 14px; } .feed_profile.follow_list_wrap { padding: 0; } .follow_list { display: block; width: 100%; max-height: 175px; } .follow_list li { display: flex; align-items: center; padding: 5px 0; }
-
공통적으로 사용하는 css는 common.css 파일을 만들고 코딩하였다.
-
특히 우측 스토리와 팔로우 영역은 공통적으로 사용하는 css가 많아 클래스를 동일하게 주고 재사용하였다.
◎ Javascript code
const commentForm = document.querySelector('.comments_form'); const comments = document.querySelector("#comment_input"); const submitButton = document.querySelector(".btn span"); function commentUpdate() { const ulbox = document.querySelector(".comments_info.comment_list_ul") const liBox = document.createElement("li"); const pBox = document.createElement("div"); const userBox = document.createElement("span"); const commentCtnBox = document.createElement("span"); let user ="test"; userBox.setAttribute("class", "user_id"); commentCtnBox.setAttribute("class", "comment_contents"); pBox.setAttribute("class", "comments_tit"); userBox.innerHTML = user; commentCtnBox.innerHTML = comments.value; pBox.appendChild(userBox); pBox.appendChild(commentCtnBox); liBox.appendChild(pBox); ulbox.appendChild(liBox); comments.value = ""; }; // keydown시 page stop commentForm.addEventListener("submit", function(e) { e.preventDefault(); }); // 게시버튼 클릭 시 발생하는 함수 submitButton.addEventListener("click",commentUpdate); // 댓글 작성 후 엔터를 쳤을 때 발생하는 함수 comments.addEventListener("keydown", function(e) { if(e.keyCode === 13) { const ulbox = document.querySelector(".comments_info.comment_list_ul") const liBox = document.createElement("li"); const pBox = document.createElement("div"); const userBox = document.createElement("span"); const commentCtnBox = document.createElement("span"); let user ="test"; userBox.setAttribute("class", "user_id"); commentCtnBox.setAttribute("class", "comment_contents"); pBox.setAttribute("class", "comments_tit"); userBox.innerHTML = user; commentCtnBox.innerHTML = comments.value; pBox.appendChild(userBox); pBox.appendChild(commentCtnBox); liBox.appendChild(pBox); ulbox.appendChild(liBox); comments.value = ""; } });
-
DOM에 접근하여 해당 요소들을 전역 변수로 선언하였다.
-
댓글 작성 후 submitButton을 클릭했을 때 commentUpdate 함수를 호출하게 구현하였다.
-
댓글 작성 후 엔터를 눌렀을 때 게시글이 작성되야 하므로 'keydown' 이벤트를 연결하고 함수를 내부에 작성하였다.
-
댓글 작성 후 작성한 댓글이 보이도록 createElement(), settAttribute(), innetHTML(), appendChild() 등의 DOM 함수를 사용하였다.
-
keydown 시 page reload 현상을 막기 위해 e.preventDefault(); 를 설정하였다.
5. 문제점
◎ 오른쪽 영역 position: fiexd를 설정하였을 때, 화면을 줄이면 계속 띄어지면서 따라오는 현상을 발견하였다.
left값에 문제가 있는 거 같으며, 검색을 해보고 해결되지 않아서 멘토님한테 질문을 드렸는데, 반응형 웹을 배울 때 이 문제를 다룬다고 하셨다. 아직 해결방안은 잘 모르겠다..ㅜㅜ
◎ 댓글을 작성했을 때 엔터를 치면 댓글이 추가 안되고 페이지가 새로고침 되는 현상이 나타났다.
검색해본 결과 e.preventDefault(); 를 사용하여 해결하였다.
6. 최종 결과
◎ 디자인에 맞게 구현하였고, 댓글 기능을 구현하였다.
◎ 추가로 레이아웃만! 반응형을 조금 적용해보았다.
7. 느낀 점
-
fiex를 헤더 말고 옆에 주었을 때, 화면을 줄였을 때 띄워지는 현상을 좀 더 알아봐야겠다.
-
click, keydown 이벤트를 발생할 때 실행되는 로직은 똑같아서 리펙토링을 해봤는데 실패했다. 리펙토링 정말 어렵다.
-
공통적으로 사용하는 css는 common.css 파일을 만들어 재사용하는 방법은 좋은 거 같다.
-
반응형에 대해서 좀 더 알아보고 싶어 졌다.
-
appendChild() 사용이 미숙하여 요소를 붙이는데 오래 걸렸다.. 많이 실습하여 익숙해지도록 하자.
※ 참조
https://www.w3schools.com/jsref/event_onkeydown.asp
https://developer.mozilla.org/ko/docs/Web/API/Event/preventDefault
https://developer.mozilla.org/ko/docs/Web/API/Node/appendChild
- Git
https://github.com/JinDevT/fast-html-css/tree/master/westrgram
'Develope > Assignment' 카테고리의 다른 글
[TIL] 자기소개 페이지 Chapter 3. 모달창 만들기 (0) 2020.05.07 [Assignment] 위스타그램 코딩 Chapter 1. login page (0) 2020.05.01 [TIL] javasciprt 만 나이 계산하기 (0) 2020.04.23 [Study] 인스타그램 클론코딩 Chapter 1. (0) 2020.03.31 [Study] 자기소개 페이지 Chapter 2. (0) 2020.03.27 -