Westagram(1) Login 페이지

💁 Instagram 클론페이지, 이름하야 Westagram!

✔️ 완성본

✔️ 구현기능

  • 로그인 아이디, 비밀번호 input에 값 입력시 로그인 버튼의 색상 변경
  • 정규식을 활용한 아이디, 비밀번호 validation

✔️ 코드

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Lobster&family=Noto+Sans+KR:wght@100;400&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style/common.css">
    <link rel="stylesheet" href="style/login.css">
    <title>Document</title>
</head>
<body>
    <main>
        <div class="phoneImg">
            <div class="imgBox">
                <img class="phoneImgs visible" src="img/imgbox1.jpeg" alt="">
                <img class="phoneImgs" src="img/imgbox2.jpeg" alt="">
                <img class="phoneImgs" src="img/imgbox3.jpeg" alt="">
                <img class="phoneImgs" src="img/imgbox4.jpeg" alt="">
                <img class="phoneImgs" src="img/imgbox5.jpeg" alt="">
            </div>
        </div>
        <article class="rightBox">
            <div class="container">
                <div class="logo">
                    <h1 class="title" style="font-family: 'Lobster', cursive;">Westagram</h1>
                </div>
                <form class="loginContainer">
                    <input class="idInput input" type="text" placeholder="전화번호, 사용자 이름 또는 이메일">
                    <input class="passInput input" type="password" placeholder="비밀번호">
                    <button class="button">log in</button>
                </form>
                <div class="lineBox">
                    <div class="line"></div>
                    <div class="or">OR</div>
                    <div class="line"></div>
                </div>
                <button class="fb">
                    <i class="fab fa-facebook-square"></i>
                    <a href="#"><span>Log in with Facebook</span></a>
                </button>
                <div class="findPassword">
                    <a href="#">비밀번호를 잊으셨나요?</a>
                </div>
            </div>
            <div class="signUp">
                <p>Don't have an account? </p>
                <a href="#">Sign up</a>
            </div>
            <div class="app">
                <p>Get the app.</p>
            </div>
            <div class="appLink">
                <a href="#">
                    <img class="appLinkBtn" src="img/app1.png" alt="애플스토어">
                </a>
                <a href="#">
                    <img class="appLinkBtn" src="img/app2.png" alt="플레이스토어">
                </a>
            </div>
        </article>
    </main>
    <script src="js/login.js"></script>
</body>
</html>

CSS

body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: #fafafa;
  font-family: "Noto Sans KR", sans-serif;
}

main {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 아이폰 이미지 */
.phoneImg {
  height: 600px;
  width: 450px;
  background-image: url("../img/login.png3");
  background-size: cover;
}

.imgBox {
  position: relative;
}

.phoneImgs {
  display: none;
  top: 95px;
  left: 146px;
  position: absolute;
  height: 435px;
}

.visible {
  display: block;
}

/* 오른쪽 부분 */
.rightBox {
  display: flex;
  flex-direction: column;
  height: 560px;
}

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 370px;
  padding: 30px;
  background-color: white;
  border: 1px solid #ccc;
  border-radius: 3px;
}

.title {
  margin: 10px 20px 30px 20px;
  font-size: 3rem;
}

/* 로그인 박스 */
.loginContainer {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 280px;
}

.input {
  width: 100%;
  padding: 15px 10px;
  margin: 5px;
  border-radius: 5px;
  border: 1px solid #ccc;
  background-color: #fafafa;
  color: black;
}

.button {
  padding: 10px;
  margin: 10px;
  width: 100%;
  background-color: #c4e1fb;
  color: white;
  border-radius: 5px;
  cursor: pointer;
  font-size: 1.1rem;
  font-weight: bolder;
}

.activate {
  background-color: #0095f6;
}

/* or */
.lineBox {
  display: flex;
  align-items: center;
  padding: 10px;
  width: 100%;
}

.line {
  flex: 1;
  flex-grow: 1;
  height: 1px;
  background-color: #dbdbdb;
}

.or {
  padding: 10px;
  color: #8e8e8e;
  font-size: 0.8rem;
  font-weight: 800;
}

/* button fb */
.fb {
  width: 200px;
  padding: 10px;
  background-color: transparent;
  color: #385185;
  font-weight: bolder;
  font-size: 0.9rem;
}

.fb a {
  color: #385185;
}

/* 패스워드 찾기 */
.findPassword {
  padding-top: 10px;
  font-size: 0.8rem;
  text-decoration: none;
}

.findPassword a {
  color: #385185;
  font-weight: bolder;
}

/* 가입하기 */
.signUp {
  display: flex;
  justify-content: center;
  height: 100px;
  width: 370px;
  margin: 10px 0;
  padding: 10px;
  background-color: white;
  border: 1px solid #ccc;
  border-radius: 3px;
  font-size: 0.8rem;
}

.signUp p,
.signUp a {
  display: inline-block;
  padding: 5px;
  font-weight: bolder;
}

.signUp a {
  color: #0095f6;
}

/* 어플 버튼 */
.app {
  padding: 5px 10px;
  text-align: center;
}

.appLink {
  display: flex;
  align-items: center;
  justify-content: center;
}

.appLinkBtn {
  width: 130px;
  padding: 10px;
}

JS

//selectors
const passInput = document.querySelector(".passInput")
const idInput = document.querySelector(".idInput")
const loginBtn = document.querySelector(".button");


//event listeners
const init=()=>{
passInput.addEventListener('keyup', loginBtnActivate);
idInput.addEventListener('keyup', loginBtnActivate);
loginBtn.addEventListener('click', validate);
loginBtn.addEventListener('click', success)
}

init();

//functions
//login button activate
function loginBtnActivate () {
    const idInputValue = idInput.value;
    const pwInputValue = passInput.value;

    if(idInputValue && pwInputValue){
        loginBtn.classList.add("activate")
    }else {
        loginBtn.classList.remove("activate")
    }
}

//id, password validate
function validate(e) {
    e.preventDefault();

    const idInputValue = idInput.value;
    const pwInputValue = passInput.value;

    const idValidator = /@./ //아이디에 @과 '.'이 포함되어 있는지 검사할 정규식

    if(!idValidator.test(idInputValue) || pwInputValue.length < 5){
        alert("적합하지 않은 이메일 또는 비밀번호 형식입니다.");
    }
}

//로그인 기능
function success (){
  location.replace("http://127.0.0.1:5500/students/22th/somihwang/main.html");
}

🙈 느낀 점

  • 처음에는 링크 처럼 간단히 만들었다가 현재 인스타그램과 똑같이 클론하는 몇 동기들을 보고 자극받아서 레이아웃을 수정해야했다. 수정작업이 처음부터 만드는 것 보다 더 오래 걸려서 역시 기획단계가 가장 중요하다는 걸 새삼 깨달았다.
  • 로그인페이지 레이아웃은 간단했는데 JS부분에서 시간이 조금 걸렸다. 코딩을 하다보면 항상 느끼는게, 간단한걸 어렵게 생각하는 경향이 있는 거 같다;;
  • 처음에 loginBtnActivate함수를 email인풋과 password 인풋에 따로 따로 함수를 만들었는데, 동기인 지수님의 조언으로 하나로 합칠 수 있었다. 기능이 같거나 중복되는 라인이 있으면 합치는게 훨씬 가독성도 좋고 효율적이라는 점을 잊지말자!
  • function success 부분은 wrap up시간에 멘토님이 힌트를 주신 것을 반영했다. 페이지를 옮기는 부분을 JS로 이렇게 할 수 있다는 걸 처음 알아서 기록해두었다.

좋은 웹페이지 즐겨찾기