Webucks 만들기 - js
스타벅스를 복제해봅시다 ~ 🧑💻
[Mission 1] 로그인 페이지 레이아웃 구현 #1
과제의 사진을 보고 똑같이 구현하라.
<body>
<section class="container">
<div class="login-logo">
<img src="./images/logo.png" alt="로고이미지" />
</div>
<form class="login-form">
<input
id="id"
placeholder="전화번호, 사용자 이름 또는 이메일"
autocomplete="off"
/>
<input type="password" id="pw" placeholder="비밀번호" />
<button class="showHide" type="button">
show
</button>
<button id="toList" type="button">
로그인
</button>
</form>
<div class="login-forget">
<a href="#">비밀번호를 잊으셨나요?</a>
</div>
</section>
<script src="./js/login.js"></script>
</body>
크게 <section> 안에 2개의 <div>와 1개의 <form>으로 만들었다.
form안에는 로그인,패스워드의 input태그와 1개의 버튼으로 이루어져있다.
form에 flex를 주어 세로정렬시키고 margin을 통해 약간씩 띄어주었다.
[Mission 2] 로그인 페이지 기능 구현 #2
1 - 아이디값으로 @가 들어오면 input창이 초록색으로
2 - 비밀번호값으로 대문자,소문자,숫자,특수기호가 포함되고 길이가 8자이상이면 input창 초록색으로
3 - 이 두개의 조건을 모두 갖추면 버튼이 활성화되게 하라.
4 - 또한 show,hide버튼을 만들어 비밀번호의 값이 보이게,안보이게 구현하라.
id.addEventListener("input", (e) => {
const num = pw.value.search(/[0-9]/g);
const eng = pw.value.search(/[a-z]/gi);
const spe = pw.value.search(/[`~!@@#$%^&*|₩₩₩'₩";:₩/?]/gi);
if (
id.value.includes("@") &&
pw.value.length > 7 &&
num > -1 &&
eng > -1 &&
spe > -1
) {
button.style.backgroundColor = "#79BAF2";
} else {
button.style.backgroundColor = "#b4d2e8";
id.style.borderColor = "#dddddd";
}
if (id.value.includes("@")) {
id.style.borderColor = "#659c31";
} else {
id.style.borderColor = "#dddddd";
}
});
코드가 길어지니 아이디의 이벤트만 보도록한다.
정규식을 통해 비밀번호의 값을 확인하였고 if문으로 구현하였다.
serch는 원하는 값이 있으면 해당값의 인덱스를 없으면 -1을 반환하기에 위와같이 작성하였다.
[Mission 3] 커피 리스트 페이지 레이아웃 구현 #3
과제의 사진을 보고 똑같이 구현하세요.
// 콜드브루 아이템들
const 에스프레소 = [
{ name: "아이스 토피 넛 라떼" },
{ name: "토피 넛 라떼" },
{ name: "에스프레소 콘 파나" },
{ name: "에스프레소 마키아또" },
{ name: "아이스 카페 아메리카노" },
{ name: "카페 아메리카노" },
{ name: "아이스 카라멜 마키아또" },
{ name: "카라멜 마키아또" },
{ name: "아이스 카푸치노" },
{ name: "카푸치노" },
{ name: "라벤더 카페 브레베" },
{ name: "럼 샷 코르타도" },
{ name: "바닐라 빈 라떼" },
{ name: "블론드 에스프레소 라떼" },
{ name: "사케라또 비안코 오버 아이스" },
];
//페이지 렌더링되면 보여줌
window.addEventListener("load", () => {
showItems(콜드브루, 0, "coffee");
});
//페이지 렌더링되면 보여줌
window.addEventListener("load", () => {
showItems(에스프레소, 1, "coffeeshot");
});
//나열함수
function showItems(item, num, what) {
for (let i = 1; i < item.length; i++) {
const add = document.createElement("div");
const img = document.createElement("img");
const h4 = document.createElement("h4");
const like = document.createElement("span");
const name = document.createElement("div");
like.setAttribute("class", "like");
add.setAttribute("class", "add");
img.setAttribute("src", `./images/${what}${i}.png`);
img.setAttribute("alt", `${item[i].name}`);
name.setAttribute("class", "name");
h4.innerHTML = item[i].name;
like.innerHTML = ` 🤍`;
like.addEventListener("click", () => {
if (like.innerHTML === ` 🤍`) {
like.innerHTML = ` ❤️`;
} else like.innerHTML = ` 🤍`;
});
add.appendChild(img);
add.appendChild(name);
name.appendChild(h4);
name.appendChild(like);
document.getElementsByClassName("상품들")[num].appendChild(add);
}
}
이부분은 고민을 조금하였다.
html에 전부 써주자니 html이 너무 더러워보였다.
그래서 내가 보여줘야할 item들을 배열에 저장시키고
window의 load이벤트를 통해 페이지가 렌더링되면~
동적으로 요소들을 생성하여 그값들을 flex, space-between을 통해 나열하였다.
[Mission 4] 커피 상세 페이지 레이아웃 구현 #4
과제의 사진과 같이 만들어라.
<div class="container">
<h2>콜드 브루</h2>
<div class="detail-img">
<img src="./images/coffee11.png" alt="화이트 초콜릿 모카" />
</div>
<div class="detail-info">
<h3 class="title">화이트 초콜릿 모카</h3>
<span class="like">♡</span>
<p class="smallP">White chocolate Mocha</p>
<p class="info">
달콤하고 부드러운 화이트 초콜릿 시럽과 에스프레소를 스팀 밀크와 섞어
휘핑크림으로 마무리한 음료로 달콤함과 강렬한 에스프레소가 부드럽게
어우러진 커피
</p>
<div class="item">
<p class="item-info">제품 영양 정보</p>
<span class="item-span">Tall(톨) / 355ml (12 fl oz)</span>
</div>
<div class="detail-kcal">
<div class="division">
<div class="kcal">
<p>1회 제공량 (kcal)</p>
<p>345</p>
</div>
<div class="kcal">
<p>1회 제공량 (kcal)</p>
<p>345</p>
</div>
<div class="kcal">
<p>1회 제공량 (kcal)</p>
<p>345</p>
</div>
</div>
<div class="division">
<div class="kcal2">
<p>1회 제공량 (kcal)</p>
<p>345</p>
</div>
<div class="kcal2">
<p>1회 제공량 (kcal)</p>
<p>345</p>
</div>
<div class="kcal2">
<p>1회 제공량 (kcal)</p>
<p>345</p>
</div>
</div>
</div>
<div class="알러지">알레르기 유발 요인 : 우유</div>
<div class="review">
<h2>리뷰</h2>
<div class="comment"></div>
<input
placeholder="리뷰를 입력해주세요."
id="commentInput"
type="text"
/>
</div>
큰 틀로보면 <div>안에 <h2>1개와 <div>2개로 이루어져 있다.
flex를 써도 되지만 float도 써보고 싶어 옆의 <div>는 float:right를 통해 이미지와 나란히 배치시켰다.
그 밑으로는 모두 flex를 사용하여 구현하였다
[Mission 5] 커피 상세 페이지 기능 구현 #5
좋아요 버튼 구현과 댓글 추가기능 구현하라.
const likeSpan = document.getElementsByClassName("like")[0];
// 하트
likeSpan.addEventListener("click", () => {
if (likeBool === false) {
likeSpan.innerHTML = "❤️";
likeBool = true;
} else {
likeSpan.innerHTML = "♡";
likeBool = false;
}
});
const comment = document.querySelector(".comment");
const input = document.getElementById("commentInput");
//엔터치면 댓글
input.addEventListener("keydown", (e) => {
if (e.keyCode === 13) {
//감싸는 박스 div
const commentBox = document.createElement("div");
commentBox.setAttribute("class", "commentBox");
//텍스트 추가 span
const commentText = document.createElement("span");
commentText.setAttribute("class", "commentText");
commentText.innerHTML =
"<b>" + sessionStorage.getItem("id") + "</b>" + " : " + e.target.value;
//좋아요 span
const likeBtn = document.createElement("span");
let likeNum = 0;
likeBtn.setAttribute("class", "likeBtn");
likeBtn.innerHTML = ` ❤️ ${likeNum}명`;
likeBtn.addEventListener("click", () => {
likeNum++;
console.log(likeNum);
likeBtn.innerHTML = ` ➡️ ❤️ ${likeNum}명`;
});
//삭제 button
const deleteBtn = document.createElement("button");
deleteBtn.setAttribute("class", "deleteBtn");
deleteBtn.innerHTML = "삭제";
deleteBtn.addEventListener("click", () => {
comment.removeChild(commentBox);
});
//실제로 달기
commentText.appendChild(likeBtn);
commentBox.appendChild(commentText);
commentBox.appendChild(deleteBtn);
comment.appendChild(commentBox);
input.value = "";
}
});
리뷰 역시 동적으로 요소들을 생성하여 구현하였고
로그인할때의 아이디값을 어떻게 받아올지 구상하다가 Session storage를 통해서
값을 옮기면 되겠다고 생각하여 구글링을 통해 완성하였다.
[Mission 6] 도전 과제 #6
리뷰별로 좋아요버튼과 삭제버튼을 만들어주세요. 커피 이름 옆 좋아요 버튼(하트)를 눌렀을 때 붉은색 하트로 변하게 구현해주세요
위와 같은 코드를 통해 해결하였고 구현한 것을 사진으로 대체하겠다.