Westagram - 2. main page html/css/Js

🌈 Instagram clone코딩을 해보았다.

🌀 main page
📌 main페이지 댓글을 입력할 경우에 댓글창에 댓글이 입력되게 구현
내가 구현해본 main page 👇

✏️ main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=3.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>westagram</title>
    
    <!-- 외부 스타일시트 연결 -->
    <link rel="icon" type="image/png" href="imgs/favicon.png" />
    <link rel="stylesheet" href="common.css">
    <link rel="stylesheet" href="style.css">
    <style type="text/css"></style>
    
    <!-- 외부 스크립트 연결 -->
    <script src="index.js" defer></script>
    
    <!-- 폰트어썸 -->
    <script src="https://kit.fontawesome.com/684e97b7f2.js" crossorigin="anonymous"></script>

</head>

<!-- body start -->
<body>
    <main>
        <!-- 헤더 -->
        <header>
            <nav>
            <!-- 로고 -->
            <div class="logo">
                <div onClick="location.href='#'">
                    <a><i class="fab fa-instagram"></i></a>
                </div>
                <div class="wefont">
                <h3 class="we"><a>WESTAGRAM</a></h3> 
                </div>
            </div>
            <!-- 검색 -->
            <div class="searchbar">
                <input type="text" placeholder="검색">
            </div>
            <!-- 아이콘들 -->
            <div class="nav">
                <div class="navo" onClick="location.href='#'"></div>
                <div class="navt" onClick="location.href='#'"></div>
                <div class="navh" oncCick="location.href='#'"></div>  
            </div>
            </nav>
        </header>

        <!-- 인스타그램 피드 & 스토리  -->
        <article>
            <!-- 인스타그램 피드 -->
            <section class="peedleft">
                <!-- peedleft의 헤더부분 -->
                <div class="top">
                    <div class="toplogo">
                        <div class="topimg">
                            <a><img src="https://i.ibb.co/CQGw903/Kakao-Talk-Image-2021-10-14-18-01-43.jpg" alt=""></a>
                        </div>
                        <h4 class="memberid"><a>Cello_daily.0</a></h4>
                    </div>
                    <a><i class="fas fa-ellipsis-h"></i></a>

                </div>
                <!-- 피드이미지 -->
                <div class="peedimg"></div>
                <!-- 이미지 아래 부분 -->
                <div class="peedundericons">
                    <div class="underleft">
                        <a><i class="fas fa-heart"></i></a>
                        <a><i class="far fa-comment"></i></a>
                        <a><i class="fas fa-external-link-alt"></i></a>
                    </div>
                    <div class="underight">
                        <a><i class="far fa-bookmark"></i></a>
                    </div>
                </div>
                <!-- 피드 아이곤 아래 좋아합니다 부분 -->
                <div class="peedunderlikes">
                    <div class="likesleft">
                        <a><img src="https://i.ibb.co/CQGw903/Kakao-Talk-Image-2021-10-14-18-01-43.jpg" alt=""></a>
                        <p><a href="#">cookies</a>님 외<a href="#"> 10명이</a> &nbsp;좋아합니다</p>
                    </div>
                </div>
                <!-- 피드 아래 텍스트 부분 -->
                <div class="peedtext">
                    <p class="canon"><a href="#">canon_mj</a> 위워크에서 진행한 베이킹 클래스...<a> 더 보기</a></p>
                    <div class="id2flexbox">
                        <p class="id2"><a href="#">neceosecius</a> 거봐 좋았잖아~~~ 🌝 🌝</p>
                        <a><i class="far fa-heart"></i></a>
                    </div>
                    <span class="minit">
                        <p><a href="#">42분 전</a></p>
                    </span>
                    <ul id="commentLists">
                        <li></li>
                    </ul>
                </div>
                <!-- 피드아래 댓글 다는 부분 + 자바스크립트 코드 연동해야하는 부분 -->
                <div class="comment">
                    <input id="name" clss="names" type="text" placeholder="댓글 달기...">
                    <button class="upload" id="submit">게시</button>
                </0>
                </div>

            </section>

        <!-- 인스타그램 오른쪽 스토리부분 -->
        <!-- 사이드 오른쪽 부분 -->
        <section class="side-right">
            <div class="side-container"  onclick="location.href='#'">
                <div>
                </div>
                <div>
                    <div>
                    <p>wecode_bootcamp<br>
                    <p>WeCode<span>위코드</span></p>
                </div>
                </div>
            </div>

            <div class="side-story">
                <div class="side-navigation">
                    <p>스토리</p>
                    <div onclick="location.href='#'" class="see-all">
                        모두 보기
                    </div>
                </div>

                <div class="story" onclick="location.href='#'">
                    <div class="story-img-one"></div>
                    <div class="story-text">
                        <p class="bold">god_jaewon</p>
                        <p class="color">2시간 전</p>
                    </div>
                </div>
                <div class="story" onclick="location.href='#'">
                    <div class="story-img-two"></div>
                    <div class="story-text">
                        <p class="bold">soyoon</p>
                        <p class="color">33분 전</p>

                    </div>
                </div>

                <div class="story" onclick="location.href='#'">
                    <div class="story-img-three"></div>
                    <div class="story-text">
                        <p class="bold">ujinSin</p>
                        <p class="color">10시간 전</p>
                    </div>
                </div>

                <div class="story" onclick="location.href='#'">
                    <div class="story-img-four"></div>
                    <div class="story-text">
                        <p class="bold">selina</p>
                        <p class="color">20분 전</p>
                    </div>
                </div>
            </div>
            <!-- 추천 시작 -->
            <div class="side-pick">
                <div class="side-navigation">
                    <p>회원님을 위한 추천</p>
                    <div onclick="location.href='#'" class="see-all">
                        모두 보기
                    </div>
                </div>

                <div class="side-wrap">
                    <div class="sidewraps">
                        <div class="side-img side-wrap-img1"></div>
                        <div cass="side-childs">
                            <p class="name">ockNim</p>
                            <p class="info">hoo님 외 7명이 팔...</p>
                        </div>
                    </div>

                    <button>팔로우</button>
                </div>

                <div class="side-wrap">
                    <div class="sidewraps">
                        <div class="side-img side-wrap-img2"></div>
                        <div cass="side-childs">
                            <p class="name">dragonYong</p>
                            <p class="info">god_jaewon님 외...</p>
                        </div>
                    </div>

                    <button>팔로우</button>
                </div>

                <div class="side-wrap">
                    <div class="sidewraps">
                        <div class="side-img side-wrap-img3"></div>
                        <div cass="side-childs">
                            <p class="name">yeju</p>
                            <p class="info">Hwayeon 외 4명이...</p>
                        </div>
                    </div>

                    <button>팔로우</button>
                </div>
            </div>

            <div class="footer-wrapper">
                <p>Instagram 정보 · 지원 · 홍보센터 · API · <br>채용정보
                개인정보처리방침 · 약관 ·<br> 디렉터리 · 프로필 · 해시태그 · 언어</p>
                <p>ⓒ 2019 INSTAGRAM</p>
            </div>
        </section>


        </article>

    </main>
    <script src="index.js" defer></script>
</body>
</html>

✏️ main.css

/* header start */
header {
    width: 100%;
    height: 90px;
    background-color: rgb(255, 255, 255);
    border-bottom: 1px solid rgb(235, 233, 233);
    position: fixed;
    background-color: white;
    z-index: 999;
    top: 0;
    left: 0;
}
nav {
    width: 1200px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    padding-top: 20px;
}
/* header logo */
.logo {
    width: 300px;
    display: flex;
    padding-top: 5px;
}
.logo .fa-instagram {
    font-size: 2rem;
    color: black;
    padding-right: 1.1rem;
    border-right: 2px solid black;
}
.logo .wefont {
    padding-left: 1rem;
    padding-top: 0.3rem;
}
.we {
    font-family: 'Lobster', cursive;
    color: black;
    font-size: 1.6rem;
}
/* 헤더 검색바 */
.searchbar {
    width: 250px;
    /* position: relative; */
}
.searchbar input {
    width: 100%;
    padding: 0.5rem 2rem;
    margin-top: 6px;
    background-color: rgba(238, 235, 235, 0.288);
    border: 1px solid rgba(218, 217, 217, 0.767);
}
.searchbar input::placeholder{
    font-size: 1rem;
    color: silver;
    text-align: center;
    background: url(https://cdn2.iconfinder.com/data/icons/ios-7-icons/50/search-512.png) no-repeat 35% center/20px 20px;
    filter: invert(0.5);
}
input:focus {
    outline: 1px solid rgb(179, 179, 179);
}
/* 헤더 우측 아이콘들  */
.nav {
    width: 135px;
    height: 45px;
    display: flex;
    justify-content: space-between;
    position: relative;
}
.nav div {
    display: block;
    width: 33px;
    /* height: 35px; */
}
.navo{
    background: url(https://s3.ap-northeast-2.amazonaws.com/cdn.wecode.co.kr/bearu/explore.png) no-repeat;
    background-size: 100%;
    background-position: center;
}
.navt {
    background: url(https://s3.ap-northeast-2.amazonaws.com/cdn.wecode.co.kr/bearu/heart.png) no-repeat;
    background-size: 100%;
    background-position: center;
}
.navh {
    background: url(https://s3.ap-northeast-2.amazonaws.com/cdn.wecode.co.kr/bearu/profile.png) no-repeat;
    background-size: 100%;
    background-position: center;
}
.navt::after {
    content: "";
    display: block;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background-color: red;
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
}
/* 피드 부분 */
article {
    width: 1200px;
    height: 100%;
    margin: 5rem auto;
    display: flex;
    justify-content: space-between;
}

.peedleft{
    width: 66%;
    border: 1px solid #e6e6e6;
    margin-top: 80px;
}

.topimg img{
    width: 40px;
    height: 40px;
    border-radius: 50%;
}

.top {
    display: flex;
    justify-content: space-between;
    padding: 10px 20px;
}

.toplogo {
    display: flex;
    
}

.memberid a {
    margin-top: 15px;
    margin-left: 15px;
    color: black;
    display: block;
}

.fa-ellipsis-h {
    color: black;
    font-size: 1rem;
    margin-top: 15px;
}

.peedimg {
    width: 100%;
    height: 750px;
    background: url(https://i.ibb.co/Np3sttL/10209-D38-C65-C-4-CEC-B871-43459-D788-A06.jpg) no-repeat;
    background-size: cover;
    background-position: 100%;
}

/* 피드 아이콘들 */
.peedundericons {
    display: flex;
    padding: 10px 0px;
}

.underleft {
    width: 96%;
    display: flex;
    padding-left: 3px;
}

.underleft a {
    display: block;
    font-size: 1.5rem;
    margin-left: 13px;
    color: rgb(145, 145, 145);
}

.underight a {
    display: block;
    font-size: 1.2rem ;
    color: srgb(145, 145, 145);
}

.fa-heart {
    color: red;
}

.fa-comment {
    transform: rotateY(180deg);
}

.fa-bookmark {
    font-size: 1.4rem;
}

/* 좋아요부분 */
.likesleft {
    display: flex;
    padding: 0 15px;
    margin-bottom: 0.5rem;
}

.likesleft img {
    width: 25px;
    height: 25px;
    border-radius: 50%;
}

.likesleft p {
    padding-top: 5px;
    margin-left: 8px;
    font-weight: normal;
}

.likesleft p a {
    color: black;
    font-weight: 800;
}

/* 댓글 달린 부분 */
.peedtext {
    padding-left: 17px;
    border-bottom: 1px solid #e6e6e6;
    padding-bottom: 10px;
}

.canon {
    margin-bottom: 3px;
}

.id2flexbox {
    margin-top: 5px;
    margin-bottom: 5px;
    display: flex;
}

.id2flexbox p {
    width: 96%;
}

.id2flexbox>:nth-child(2) i{
    color: silver;
}

.minit a{
    color: rgb(153, 153, 153);
    font-weight: normal;
}
/* form  댓글 다는 부분*/
.comment {
    width: 100%;;
    position: relative;
}

.comment input {
    width: 90%;
    border: none;
    padding:20px 0;
    padding-left: 15px;
}

.comment input:focus {
    outline: none;
}

.upload {
    padding: 15px 15px;
    border: none;
    font-size: 0.8rem;
    position: absolute;
    color: rgba(113, 147, 238, 0.747);
    background-color: none;
    right: 0px;
    top: 6px;
}

.upload:hover {
    background: none;;
    color: rgba(113, 147, 238, 0.747);
}

#commentLists {
    margin-top: 0.6rem;
    margin-bottom: 0.7rem;
}

#commentLists li {
    width: 100%;
    margin-bottom: 0.3rem;
    position: relative;
    color: black;
}

.delete {
    cursor: pointer;
    position: absolute;
    right: 19px;;
}

.name {
    padding-right: 0.6rem;
    color: black;
    font-weight: bold;
}

/* 피드 오른쪽 스토리 */
.side-right {
    width: 368px;
    margin-top: 5.3rem;
}

.side-container {
    margin-bottom: 1rem;
    display: flex;
    cursor: pointer;
}

.side-container > :first-child {
    width: 60px;
    height: 60px;
    margin-right: 1rem;
    border-radius: 100%;
    background: url(https://pbs.twimg.com/profile_images/1109389733912666112/XX55fTPf.jpg)
no-repeat;
    background-size: cover;
    background-position: center;
}

.side-container > :last-child {
    position: relative;
}

.side-container > :last-child div {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

.side-container > :last-child div > :first-child {
    margin-bottom: 0.3rem;
    font-weight: bold;
}

.side-container > :last-child div > :last-child {
    color: #bababa;
}

.side-container > :last-child div > :last-child span:before {
    content: "┃";
}

.side-story {
    padding: 1rem;
    margin-bottom: 1rem;
    background: #fff;
    border: 1px solid #e6e6e6;
    border-radius: 5px;
    height: 258px;
    overflow-y: hidden;
}

.side-navigation {
    margin-bottom: 1rem;
    display: flex;
    justify-content: space-between;
}

.side-navigation p {
    color: #bababa;
}

.see-all {
    color: rgb(73, 73, 73);
    font-weight: 760;
}

.story {
    display: flex;
}

.story > :first-child {
    width: 50px;
    height: 50px;
    margin-right: 1rem;
    border: 2px solid #e56c9f;
    border-radius: 100%;
}

.side-story > :nth-child(2),
.side-story > :nth-child(3),
.side-story > :nth-child(4) {
    margin-bottom: 0.8rem;
}

.story-text {
    margin-top: 5px;
}

.story-img-one {
    background: url(https://images.unsplash.com/photo-1519764622345-23439dd774f7?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8Ym95c3xlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60)
no-repeat;
    background-size: cover;
    background-position: top;
}

.story-img-two {
    background: url(https://media.istockphoto.com/photos/teen-girl-after-her-vaccination-picture-id1311564458?b=1&k=20&m=1311564458&s=170667a&w=0&h=fK1QViaweFI1OlHtQ6G3S4VrrrMK2lMDrZK-d6yTGms=)
no-repeat;
    background-size: cover;
    background-position: center;
}

.story-img-three{
    background: url(https://images.unsplash.com/photo-1554230505-919a13968970?ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8Z2lybHN8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60)
no-repeat;
    background-size: cover;
    background-position: center;
}

.story-img-four{
    background: url(https://images.unsplash.com/photo-1524601500432-1e1a4c71d692?ixid=MnwxMjA3fDB8MHxzZWFyY2h8OXx8Z2lybHN8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60)
no-repeat;
    background-size: cover;
    background-position: center;
}

.bold {
    margin-bottom: 0.3rem;
    font-weight: bold;
}

.color {
    color: #bababa;
}

/*추천 시작*/
.side-pick {
    padding: 1rem;
    margin-bottom: 1rem;
    background: #fff;
    border: 1px solid #e6e6e6;
    border-radius: 5px;
    position: relative;
}

.side-pick > :nth-child(2),
.side-pick > :nth-child(3) {
    margin-bottom: 0.3rem;
}

.side-wrap {
    display: flex;
    position: relative;
}

.sidewraps {
    display: flex;
}

.sidewraps>:last-child {
    margin-top: 1rem;
}

.side-img {
    width: 50px;
    height: 50px;
    margin-right: 1rem;
    border-radius: 100%;
    margin-top: 8px;
}

.side-wrap-img1 {
    background: url(https://images.unsplash.com/photo-1502307100811-6bdc0981a85b?ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8Ym95c3xlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60)
no-repeat;
    background-size: cover;
    background-position: center;
}

.side-wrap-img2 {
    background: url(https://images.unsplash.com/photo-1613852348851-df1739db8201?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTR8fGJveXN8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60)
no-repeat;
    background-size: cover;
    background-position: center;
}

.side-wrap-img3 {
    background: url(https://images.unsplash.com/photo-1500336624523-d727130c3328?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTB8fGdpcmxzfGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60)
no-repeat;
    background-size: cover;
    background-position: center;
}

.side-wrap > :first-child > :last-child > :first-child {
    margin-bottom: 0.3rem;
    font-weight: bold;
}

.side-wrap > :first-child > :last-child > :last-child {
    color: #bababa;
}

.side-wrap > :last-child {
    padding: 1.5rem 0 1rem 1rem;
    color: #2398ff;
    background: none;
    position: absolute;
    right: 0;
    border: none;
    font-size: 0.9rem;
    font-weight: 700;
}

.footer-wrapper p {
    color: #acacac;
    line-height: 1.5rem;
    margin-bottom: 1rem;
    font-weight: 600;
}

✅   css를 작성하면서
👉 처음 인스타그램 클론 코딩을 시작하면서 예시 이미지를 보고 그렇게 어렵지 않겠다고 생각했지만 css를 하면서 생각 했던것보다 할게 많았고 도중에 헷갈렸던 부분들이 조금 있었다. display: flex를 위해서 하나씩 div를 더 감싸주는게 맞을지, position: absolute를 사용해서 div의 갯수를 줄이는게 맞을지 고민했던 것 같다. 결과적으로 나는 이번 westagram에서는 flex를 많이 사용했다.


👉 input창 css에 조금 더 공부하고 알게되는 시간을 가져서 좋았다!. 항상 까다롭다고 생각했었지만 이번에 input에 대해서 공부하면서 생각보다 input을 적용하는데 있어서 조금더 가까워 진것 같다. input에 부모 요소를 하나 더 감싼고 거기에 width값을 준다음에 input의 width: 100%를 한다음 부모 요소에 margin: 0 auto를 하는 방향으로 위치 시켰다.

✏️ main.js

'use strict';

const commentInput = document.getElementById("name");
const submit = document.getElementById("submit");

function checkInput() {
    if(!commentInput.value.length) {
        alert("댓글을 입력하세요");
    }else{
        registerComment(commentInput.value);
    }
}
function registerComment(value){
    const commentLists = document.getElementById("commentLists");
    const newCommentList = document.createElement("li");
    const newComment = `<span class="name">jiwon</span><span>${value}</span><span class="delete">X</span>`
    
    newCommentList.innerHTML = newComment;
    deleteComment(newCommentList);
    commentLists.appendChild(newCommentList);
    commentInput.value = "";
}

function deleteComment(newCommentList) {
    const deleteBtn = newCommentList.querySelector(".delete");
    deleteBtn.addEventListener("click", () => newCommentList.remove());
}


commentInput.addEventListener('keyup', () => {
    if (window.event.code === 'Enter') {
        checkInput();
    }else {
        submit.addEventListener("click", checkInput);
    }
});

// const init = () => {
//     submit.addEventListener("click", checkInput);
// };
// init();

const inputId = document.querySelector("#name");
const button = document.querySelector('.upload');

function commentBtn() {
    let idValu = inputId.value;

    if(idValu.length > 0) {
        button.disabled = false;
        button.style.cursor = 'pointer';
        button.style.color = '#1c7ed6';
    } else {
        button.disabled = true;
        button.style.cursor = 'default';
        button.style.color = 'skyblue  ';
    }
}
inputId.addEventListener('keyup', commentBtn);

✅   js를 작성하면서
👉 댓글창 input에 댓글을 입력하고 '게시'버튼을 눌렀을 경우나 enter키를 쳤을 경우에 댓글이 생성되게 만들어야했다.
그래서 createElement로 새로운 값 li를 생성하게 하고 새로 추가한 li를 innerHTML로 추가하는 함수를 만들었다. 새로 생성된 li를 삭제 할 수도 있게 delete x라는 함수를 만들어서 x를 눌렀을 경우에 댓글이 삭제될 수 있게도 구현해보았다.


🔥 댓글 창 js는 머릿속에서 혼자 생각해내기 힘든 부분들이 있었지만 계속 공부하면서 발전시키고 있다.

좋은 웹페이지 즐겨찾기