TIL-25 인스타그램 메인 페이지 review

PRB·2021년 8월 13일
0

Project

목록 보기
2/13
post-thumbnail
post-custom-banner

1. 메인 페이지 HTML

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Westagram</title>
    <link rel=stylesheet href="style/main.css">
    <link rel=stylesheet href="style/common.css">
    <link href="https://fonts.googleapis.com/css2?family=Lobster&display=swap" rel="stylesheet">
    <script src="https://kit.fontawesome.com/e2f453cbbf.js"></script>
</head>
<body>
    <div class="nav">
        <div class="nav_logo"">
            <a href="main.html"><i class="fab fa-instagram"></i>
            <span class="nav_logo_name">Westagram</span></a>
        </div>
        <div class="nav_search">
            <input placeholder="검색">
            <div class="search_plus">
                <div class="search_plus_nav">
                    <div>최근 검색 항목</div>
                    <div>모두 지우기</div>
                </div>
                <div class="search_plus_article">
                    <div class="search_plus_profile">
                        <div class="search_plus_photo">
                            <img alt="wecoder_photo" src="/img/wecode.jpeg">
                        </div>
                        <div class="search_plus_info">
                            <div class="search_plus_id">wecode_bootcamp</div>
                            <div class="search_plus_name">WeCode | 위코드</div>
                        </div>
                    </div>
                </div>
            </div>
            <i class="fas fa-search" id="search_icon"></i>
        </div>
        <div class="nav_icons">
            <img alt="explore" class="nav_icon" src="img/explore.png">
            <img alt="my_profile" class="nav_icon" src="img/profile.png" id="my_profile">
            <div class="my_profile_plus">
                <li><div><i class="far fa-user-circle"></i></div><div>프로필</div></li>
                <li><div><i class="far fa-bookmark"></i></div><div>저장됨</div></li>
                <li><div><i class="fas fa-cog"></i></div><div>설정</div></li>
                <li><div><i class="fas fa-exchange-alt"></i></div><div>계정 전환</div></li>
                <li class="my_profile_logout">로그아웃</li>
            </div>
            <img alt="news" class="nav_icon" src="img/heart.png">
        </div>
    </div>
    <main>
        <div class="feeds">
            <div class="article">
                <div class="profile_box">
                    <div class="profile">
                        <div>
                            <img alt="my_profile" class="user_photo" src="img/wecode.jpeg">
                        </div>
                        <div class="username">
                            <strong>code_bootcamp</strong>
                        </div>
                    </div>
                    <div>
                        <i class="fas fa-ellipsis-h"></i></div> 
                    </div>
                <div class="feed">
                    <img alt="feed_photo" class="feed_photo" src="img/main.jpeg">
                </div>
                <div class="feed_bottom">
                    <div class="feed_icons">
                        <div>
                        <i class="far fa-heart" id="love"></i>
                        <i class="far fa-comment"></i>
                        <i class="far fa-paper-plane"></i>
                        </div>
                        <div id="bookmark"><i class="far fa-bookmark"></i></div>
                    </div>
                    <div class="feed_likes">
                        <strong>CSS</strong>님 외 3명이좋아합니다
                    </div>
                    <div class="feed_text">
                        <strong>wecode_bootcamp</strong> 안녕하세요<br>
                    </div>
                    <div class="comment_box">
                        <div class="comment">
                            <div><b>html</b> 멋져요🛶</div><div><i class="fas fa-times"></i><i class="far fa-heart"></i></div>
                        </div>
                        <div class="comment">
                            <div><b>java</b> 이뻐요🚀</div><div><i class="fas fa-times"></i><i class="far fa-heart"></i></div>
                        </div>
                    </div>
                    <div class="feed_time">
                        12분전
                    </div>
                </div>
                <div class="comment_input_box">
                    <input class="comment_input" type="text" placeholder="댓글 달기...">
                    <span class="comment_enter">게시</span>
                </div>
            </div>
        </div>
        <aside>
            <div class="main_right">
                <div class="my_profile">
                    <div class="my_photo">
                        <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                    </div>
                    <div class="my_info">
                        <div class="my_id">wecode_bootcamp</div>
                        <div class="my_name">WeCode | 위코드</div>
                    </div>
                </div>
                <div class="story">
                    <div class="story_nav">
                        <div>스토리</div>
                        <div>모두보기</div>
                    </div>
                    <div class="story_peeds">
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">JAVA</div>
                                <div class="feed_time">1분 전</div>
                            </div>
                        </div>
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">HTML</div>
                                <div class="feed_time">48분 전</div>
                            </div>
                        </div>
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">react</div>
                                <div class="feed_time">21분 전</div>
                            </div>
                        </div>
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">code</div>
                                <div class="feed_time">42분 전</div>
                            </div>
                        </div>
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">dsfnl2</div>
                                <div class="feed_time">24분 전</div>
                            </div>
                        </div>
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">fds2</div>
                                <div class="feed_time">16분 전</div>
                            </div>
                        </div>
                        <div class="story_peed">
                            <div class="story_photo">
                                <img alt="wecoder_photo" class="user_photo" src="img/wecode.jpeg">
                            </div>
                            <div class="stoty_info">
                                <div class="username">wecoder</div>
                                <div class="feed_time">10분 전</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="recommend">
                    <div class="story_nav">
                        <div>회원님을 위한 추천</div>
                        <div>모두보기</div>
                    </div>
                    <div class="recommend_peeds">
                        <div class="recommend_peed">
                            <div class="recommend_photo">
                                <img alt="wecoder_photo"src="img/wecode.jpeg" class="user_photo">
                            </div>
                            <div class="recommend_info">
                                <div>
                                    <div class="username">have</div>
                                    <div class="feed_time">8명이 팔로우</div>
                                </div>
                                <div class="follow">팔로우</div>
                            </div>
                        </div>  
                        <div class="recommend_peed">
                            <div class="recommend_photo">
                                <img alt="wecoder_photo"src="img/wecode.jpeg" class="user_photo">
                            </div>
                            <div class="recommend_info">
                                <div>
                                    <div class="username">have</div>
                                    <div class="feed_time">7명이 팔로우</div>
                                </div>
                                <div class="follow">팔로우</div>
                            </div>
                        </div> 
                        <div class="recommend_peed">
                            <div class="recommend_photo">
                                <img alt="wecoder_photo"src="img/wecode.jpeg" class="user_photo">
                            </div>
                            <div class="recommend_info">
                                <div>
                                    <div class="username">have</div>
                                    <div class="feed_time">6명이 팔로우</div>
                                </div>
                                <div class="follow">팔로우</div>
                            </div>
                        </div> 
                        <div class="recommend_peed">
                            <div class="recommend_photo">
                                <img alt="wecoder_photo"src="img/wecode.jpeg" class="user_photo">
                            </div>
                            <div class="recommend_info">
                                <div>
                                    <div class="username">have</div>
                                    <div class="feed_time">2명이 팔로우</div>
                                </div>
                            </div>
                            <div class="follow">팔로우</div>
                        </div>
                    </div>
                </div>
                <footer>
                    instagram 정보 · 지원 · 홍보 센터 · API · 채용정보 · 개인정보처리방침 · 약관 · 다렉터리 · 프로필 · 해시태그 · 언어
                    <br>© 2021 INSTAGRAM FROM FACEBOOK
                </footer>
            </div>
        </aside>
    </main>
    <script src='js/main.js'></script>
</body>
</html>

1. 네이밍의 중요성

아직도 이름에 마음이 들진 않지만 전에는 더 심각했다.
처음에 빠르게 완성만 시키자는 생각으로 이름, 태그들을 너무 대충 지었는데
리팩토링할 때 시간이 몇 시간 걸렸다.. (처음부터 잘하자 !)
완성될 때쯤 코드가 너무 지저분하고 레이아웃도 너무 이상했다.
이래서 html, css가 중요하다는 걸 다시 한번 깨달았다.
이름도 의미가 너무 없어 다시 짓고 필요 없는 코드도 정리했다.

2. 메인 페이지 CSS

i:hover {
    cursor: pointer;
}

li {
    list-style: none;
}

.nav {
    width: 100%;
    height: 50px;
    padding: 0 125px;
    border-bottom: rgb(219, 219, 219) 1px solid;
    background-color: white;
    font-size: 35px;
    display: flex;
    justify-content: space-around;
    text-align: center;
    position: fixed;
    top: 0;
    z-index: 1;
}

.nav_logo {
    margin: auto 0;
}

.nav_logo i {
    margin-right: 20px;
    color: black;
}

.nav_logo_name {
    font-family: 'Lobster', cursive;
    color: black;
}

.nav_search {
    width: 200px;
}

.nav_search input {
    height: 25px;
    width: 100%;
    background-color: #FAFAFA;
    border: rgb(219, 219, 219) 1px solid;
    border-radius: 3px;
    text-indent: 95px;
}

#search_icon {
    font-size: 12px;
    color: #A4A7AA;
    position: relative;
    bottom: 43px;
    right: 13px;
}

.search_plus {
    width: 375px;
    height: 360px;
    font-size: 25px;
    position: relative;
    background-color: white;
    display: none;
    overflow: scroll;
    flex-direction: column;
    border : gray 1px solid;
    border-radius: 10px;
    padding: 15px;
    float:right;
}

.search_plus::-webkit-scrollbar {
    display: none;
}

.search_plus_nav {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
    font-size: 15px;
}

.search_plus_article {
    display: flex;
    flex-direction: column;
}

.search_plus_profile {
    display: flex;
}

.search_plus_profile img {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    margin-right: 20px;
}
.search_plus_info {
    font-size: 13px;
}

.nav_icon {
    width: 30px;
    height: 30px;
    margin: 10px;
}

.my_profile_plus{
    flex-direction: column;
    z-index: 1;
    background-color: white;
    border: black 1px solid;
    font-size: 18px;
    border-radius: 8px;
    position: fixed;
    display: none;
    left: 1000px;
}

.my_profile_plus li{
    display: flex;
    padding: 10px;
    width: 230px;
}

.my_profile_plus li:hover{
    background-color: gray;
    cursor: pointer;
    border-radius: 4px;
}

.my_profile_plus i{
    margin-right: 20px;
    width: 33px;
}

.my_profile_logout{
    border-top: 1px gray solid;
    width: 33px;
}

.nav_icons img:hover{
    cursor: pointer;
}

main { 
    background-color:#FAFAFA;
    padding: 100px 223px;
    display: flex;
}

.feeds {
    height: 100%;
    width: 615px;
    border: 1px rgb(219, 219, 219) solid;
    border-radius: 3px;
    margin-right: 40px;
}

.article {
    width: 100%;
    height: 1100px;
    border-radius: 3px;
    background-color: white;
    display: flex;
    flex-direction: column;
}

.profile_box {
    width: 100%;
    height: 60px;
    display: flex;
    justify-content: space-between;
}

.profile_box i {
    margin: 20px;
    font-size: 20px;
}

.profile .user_photo {
    width: 35px;
    height: 35px;
    border-radius: 50%;
    margin: 13px;
}

.profile {
    display: flex;
    text-align: center;
}

.profile .username {
    font-size: 15px;
    margin: auto 0;
}

.feed {
    width: 100%;
    height: 100%;
}

.feed_photo {
    width: 100%;
    height: 100%;
}

.feed_bottom {
    height: 250px;
    padding: 15px;
    font-size: 15px;
    border-bottom: 1px rgb(219, 219, 219) solid;
    display: flex;
    flex-direction: column;
    justify-content: space-around;

}

.feed_icons {
    display: flex;
    justify-content: space-between;
    font-size: 25px;
    margin-bottom: 5px;
}

.feed_icons i {
    padding-right: 10px;
}

#bookmark i {
    padding: 0;
}

.feed_likes {
    margin-bottom: 10px;
}

.feed_time{
    color: gray;
    font-size: 12px;
}
.comment_box {
    width: 100%;
    height: 50px;
    overflow: scroll;
    margin-bottom: 5px;
}

.comment {
    display: flex;
    justify-content: space-between;
    height: 25px;
}

.comment i {
    margin: 5px 0;
}

.comment .fa-times {
    margin-right: 5px;
}
.comment_box::-webkit-scrollbar {
    display: none;
}

.comment_input_box {
    width: 615px;
    height: 65px;
    padding: 0 25px;
    display: flex;
    justify-content: space-between;
}

.comment_enter {
    color: #C1E0FD;
    margin: auto 0;
}

.comment_enter:hover {
    cursor: pointer
}

.comment_input {
    width: 520px;
    background-color: white;
    margin: auto 0;
    color: gray ;
    border: white;
    height: 20px;
    border-radius: 3px;
}

.main_right {
    display: flex;
    flex-direction: column;
    width: 325px;
    position: fixed;
    top: 100px;
}

.my_profile {
    display: flex;
    flex-direction: row;
    margin-bottom: 20px;
    width: 325px;
    margin-left: 20px;
}

.my_photo img {
    width: 55px;
    height: 55px;
    border-radius: 50%;
}

.my_info {
    padding: 10px;
}

.my_name {
    color: #8E8E8E;
}

.story {
    width: 100%;
    height: 250px;
    padding: 20px;
    border: rgb(219, 219, 219) 1px solid;
    border-radius: 3px;
    margin-bottom: 20px;
    display: flex;
    flex-direction: column;
    background-color: white;
    overflow: scroll;
}

.story::-webkit-scrollbar {
    display: none;
}

.story_nav {
    color: gray;
    margin-bottom: 5px;
    display: flex;
    justify-content: space-between;
}

.story_peeds {
    display: flex;
    flex-direction: column;
}

.user_photo {
    width: 35px;
    height: 35px;
    border-radius: 50%;    
    margin-right: 10px;
}

.story_peed {
    margin-bottom: 5px;
    display: flex;
    flex-direction:row;
}

.recommend {
    height: 150px;
    padding: 20px;
    border: 1px rgb(219, 219, 219) solid;
    background-color: white;
    border-radius: 3px;
    display: flex;
    flex-direction: column;
    overflow: scroll;
}

.recommend::-webkit-scrollbar {
    display: none;
}

.recommend_peeds {
    display: flex;
    flex-direction: column;
    }

.recommend_peed {
    margin-bottom: 5px;
    display: flex;
    flex-direction:row;
    }

.recommend_info {
    display: flex;
    justify-content: space-between;
    }

.follow {
    margin-left: 134px;
    color: #0095F6;
}

.follow:hover {
    cursor: pointer;
}

footer {
    color: rgb(219, 219, 219);
    font-size: 12px;    
    margin-top: 15px;
}

@media screen and (max-width: 1000px) {
.main_right {
    display: none;
}
}

클론 코딩은 처음이여서 그런지 CSS를 하면서 모르는부분을 많이 배웠다.

1. z-index

z-index 개념은 알고있었는데 z-index가 적용이 안될때가 있다는건 처음알았다.

2. text-indent

처음에 text-indent을 몰라서 input태그 안에 padding을 줘서 조절했는데 그렇게 하다가 보니까 계속 망가졌는데 text-indent을 알게되서 잘 조절하였다.
값이 양수이면 들여쓰기, 값이 음수이면 내어쓰기가 된다!

3. overflow: scroll

스토리를 구현하다가 알게된 기능이다.
넘어간 컨텐츠는 잘리고, 스크롤바가 생겨서 스크롤해서 볼 수 있는 기능인데 가로&세로 스크롤바가 생겨서 보기가 안좋아서 이걸 어떻게 지울까 구글링하다 방법을 찾았다. 4번이 그 내용이다.

4.::-webkit-scrollbar

스크롤에 대한 스타일을 변경해줄수있는 기능이다.
스크롤 보기싫어서 display: none 을 줬다.

3. 메인 페이지 JS

"use strict";
const $navSearch = document.querySelector('.nav_search input')
const $searchPlus = document.querySelector('.search_plus')
const $searchIcon = document.querySelector('#search_icon')
const $myProfile = document.querySelector('#my_profile')
const $myProfilePlus = document.querySelector('.my_profile_plus')
const $myProfilePlusList = document.querySelector('.my_profile_plus li')
const $love = document.querySelector('#love')
const $feedLikes = document.querySelector('.feed_likes')
const $commentBox = document.querySelector('.comment_box')
const $commentInput = document.querySelector('.comment_input')
const $comment = document.querySelector('.comment')
const $commentEnter = document.querySelector('.comment_enter')
const $keywords = ['wecode_bootcamp']
let keyword = ""
// 메뉴바 검색기능
function keywordSplit(){
    for(let i = 0; $keywords.length > i; i++ ){
        keyword += $keywords[i]
    }
    return keyword.split('')
}
const smallKeyword = keywordSplit()
$navSearch.addEventListener( 'keyup', () => {
    for(let i = 0; $navSearch.value.length > i; i++){
        if ($navSearch.value[i] === smallKeyword[i]){
            $searchPlus.style.display = 'flex'
            i= i+1
            return;
        }
        else {
            $searchPlus.style.display = 'none'
        }
    }
        if(!$navSearch.value){
            $searchPlus.style.display = 'none'
            return;
        }
})
// 메뉴바 검색창 
$navSearch.addEventListener('focus', (event) => {
    event.target.style.textIndent= '20px'
    $searchIcon.style.display = 'none'
    $navSearch.value=''
})
$navSearch.addEventListener('blur', (event) => {
    event.target.style.textIndent = '95px'
    $searchIcon.style.display = 'inline-block'
    $navSearch.value = '검색'
    $searchPlus.style.display = 'none'
})
//내 프로필
$myProfile.addEventListener('click',() => {
    if ($myProfilePlus.style.display === 'none'){
        $myProfilePlus.style.display = 'block'
        if($myProfilePlus.style.display === 'block'){
        document.querySelector('body').addEventListener('click',(event)=>{
                if(event.target == $myProfilePlusList){
                    $myProfilePlus.style.display = 'none'
                    console.log(1)
                }
        })
    }    
    }
    else {
        $myProfilePlus.style.display = 'none'
    }
}) 

//댓글 입력창 (키보드입력)
$commentInput.addEventListener('keyup', (event) => {
    if (event.key === 'Enter' && $commentInput.value) {
        $commentBox.innerHTML += '<div class = "comment">'+'<div>' + '<b>wecode_bootcamp </b>'+ $commentInput.value + '</div>' + '<div><i class="fas fa-times"></i><i class="far fa-heart"></i></div>' + '</div>';
        $commentInput.value = ''
        return;
    }
    if ($commentInput.value) {
        $commentEnter.style.color = '#0095F6'
        return;
    }
    if (!$commentInput.value){
        $commentEnter.style.color = '#C1E0FD'
        return;
    }
})

//댓글 입력창 (마우스클릭)
$commentEnter.addEventListener('click', () => {
    if ($commentInput.value) {
        $comment.innerHTML += '<div class = "comment">'+'<div>' + '<b>wecode_bootcamp </b>'+ $commentInput.value + '</div>' + '<div><i class="fas fa-times"></i><i class="far fa-heart"></i></div>' + '</div>';
        $love.setAttribute('class', 'far fa-heart');
        $commentInput.value = ''
    }
})
//댓글 좋아요 구현
$commentBox.addEventListener('click',(event) => {
    if(event.target.className === "far fa-heart" || 
        event.target.className === "fas fa-heart"){
        if(event.target.style.color === 'rgb(237, 73, 86)'){
            event.target.style.color = 'black'
            event.target.setAttribute('class', 'far fa-heart');
        }
        else{
            event.target.style.color = 'rgb(237, 73, 86)'
            event.target.setAttribute('class', 'fas fa-heart');
            
        }
    }
})
// 댓글 삭제 기능
$commentBox.addEventListener('click',(event) => {
        if(event.target.className === "fas fa-times"){
            event.target.parentNode.parentNode.remove();
        }
})
// 피드 좋아요 구현
$love.addEventListener('click', () => {
    if($love.style.color === 'rgb(237, 73, 86)'){
        $love.style.color = 'black'
        $love.setAttribute('class', 'far fa-heart');
        $feedLikes.innerHTML = '<b>CSS</b>님 외 3명이 좋아합니다'
    }
    else{
        $love.style.color = 'rgb(237, 73, 86)'
        $love.setAttribute('class', 'fas fa-heart');
        $feedLikes.innerHTML = '<b>wecode_bootcamp</b>님 외 4명이 좋아합니다'
        
    }
})

1. use strict

strict 모드로 설정하는하는 건데 제일 상단에 "use strict"를 추가해주면 된다.
strict 모드에서 허용되지 않은 문법

  1. 정의되지 않은 변수의 사용
  2. 변수나 객체의 삭제
  3. 함수 파라미터에 중복된 이름
  4. 8진수
  5. 이스케이프 문자
  6. 읽기전용 프로퍼티에 값 설정
  7. 조회 전용 프로퍼티에 값 설정
  8. eval, arguments 문자열에 대한 변수로의 사용
  9. with 사용
  10. eval() 에 정의된 변수 사용

2. addEventListener blur

엘리먼트가 focus를 잃었을 때 발생되는 이벤트인데
같은 용도로 사용되는 이벤트로 focusout가 있다.
둘의 차이점은 버블링의 차이인데
focusout는 버블링이 일어나고, blur는 버블링이 일어나지 않는다.
버블링에 관한 영상을 본 적 있는데 다시 한번 봐야 할 거 같다.

4. 미해결

우측 상단에 사용자 메뉴가 있다.
저걸 누르면 실제 인스타그램 처럼 정보가 나오는데 다른곳을 클릭하면 없어지지않는다.

$myProfile.addEventListener('click',() => {
    if ($myProfilePlus.style.display === 'none'){
        $myProfilePlus.style.display = 'block'
        if($myProfilePlus.style.display === 'block'){
        document.querySelector('body').addEventListener('click',(event)=>{
                if(event.target == $myProfilePlusList){
                    $myProfilePlus.style.display = 'none'
                }
        })
    }    
    }
    else {
        $myProfilePlus.style.display = 'none'
    }
}) 

이 부분인데 이미지에 focus 이벤트를 줄 수 없다고 한다.
부여하고 싶다면 img 태그에 tabindex 속성을 주면 된다고 하는데 안된다. 어떤 분은 buttom 태그를 감싸면 된다고 하는데 안된다.
굳이 이 방법 말고도 더욱 효율성 좋은 방법들이 많겠지만 이게 왜 안되는지 알고 싶다 😩
console.log(1)을 해봤는데 누르면 누를수록 1이 많이 찍힌다.(이게 버블링인가?)

참고사이트
https://uwostudy.tistory.com/55
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=anonymousx&logNo=10183869727
https://mygumi.tistory.com/321

profile
사용자 입장에서 사용자가 원하는 것을 개발하는 프론트엔드 개발자입니다.
post-custom-banner

0개의 댓글