지그재그 클론코딩(5)(코드만)
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" />
<title>Document</title>
<link rel="stylesheet" href="newp.css" />
</head>
<body>
<nav class="navbar">
<img src="img/logo_zigzag.png" alt="logo" class="logo" />
<input
type="text"
class="search"
placeholder=" 검색어를 입력하세요"
/>
<img src="img/cart_zigzag.png" alt="cart" class="cart" />
</nav>
<nav class="homebar">
<button class="home1">홈</button>
<button class="home2">Brand</button>
<button class="home3">베스트</button>
<button class="home4">혜택</button>
<button class="home5">신상</button>
</nav>
<div class="section">
<input type="radio" class="slide" id="slide01" checked />
<input type="radio" class="slide" id="slide02" />
<input type="radio" class="slide" id="slide03" />
<div class="slidewrap">
<ul class="slidelist">
<li>
<a>
<label for="slide03" class="left"></label>
<!-- label을 slide03으로 설정했기 때문에,
이 left버튼을 누르면 같은 slide03을 id로 갖는 radio버튼이 눌린다. -->
<img src="./img/banner1.png" />
<label for="slide02" class="right"></label>
<!-- label을 slide02로 설정했기 때문에,
이 right버튼을 누르면 radio버튼의 slide02를 id로 가지는 버튼이 눌린다. -->
</a>
</li>
<li>
<a>
<label for="slide01" class="left"></label>
<img src="./img/banner2.png" />
<label for="slide03" class="right"></label>
<!-- 2번 이미지가 노출되었을 때는,
왼쪽 버튼은 slide01, 오른쪽 버튼은 slide03의 라벨이 적용되어
동일한 id값을 갖는 radio버튼이 눌리고, 해당 이미지로 이동한다. -->
<!-- 배너 이미지 출처:https://www.pinterest.co.kr/pin/3377768461355481/ -->
</a>
</li>
<li>
<a>
<label for="slide02" class="left"></label>
<!-- label을 slide03으로 설정했기 때문에,
이 left버튼을 누르면 같은 slide03을 id로 갖는 radio버튼이 눌린다. -->
<img src="./img/banner3.png" />
<label for="slide01" class="right"></label>
<!-- label을 slide02로 설정했기 때문에,
이 right버튼을 누르면 radio버튼의 slide02를 id로 가지는 버튼이 눌린다. -->
</a>
</li>
</ul>
</div>
</div>
<!-- 기존 -->
<!-- <article class="banner">
<div class="banner_slide">
<img
src="img/banner3_zigzag.png"
id="lastbanner"
alt="banner_img1"
class="banner_img"
/>
<div class="dots">
<button class="dot1"></button>
<button class="dot2" onclick="dot2click()"></button>
<!-- <button class="dot3"></button> -->
<!-- </div>
</div>
</article> -->
<box class="title">당신을 위한 추천 아이템</box>
<box class="filters">
<img src="img/filter_icon.png" alt="filter_icon" class="filter_icon" />
<!-- <p class="filter">filter</p> -->
<nav class="navbar2">
<button class="menu1" data-key="type" data-value="shirt">셔츠</button>
<button class="menu2" data-key="type" data-value="chardigan">
가디건
</button>
<button class="menu3" data-key="type" data-value="knit">니트</button>
<button class="menu4" data-key="type" data-value="pants">바지</button>
<button class="menu5" data-key="type" data-value="skirt">치마</button>
</nav>
</box>
<!-- title시멘틱 태그는 텍스트가 보이지 않는다. 왜일까? -->
<section class="items"></section>
<!-- <box class="title2">지그재그 베스트 100</box> -->
<!-- title시멘틱 태그는 텍스트가 보이지 않는다. 왜일까? -->
<section class="otheritems">
<div class="item2">
<img src="img/item2_img2.png" alt="${item.type}" class="item_img2" />
<box class="item_description">
<div class="item_mall">무아무아</div>
<div class="item_title">5color 무아 시그니처 와펜 후드 집업</div>
<box class="price">
<div class="item_discount">56%</div>
<div class="item_price">18,900</div>
</box>
</box>
</div>
<div class="item2">
<img src="img/item2_img3.png" alt="${item.type}" class="item_img2" />
<box class="item_description">
<div class="item_mall">무아무아</div>
<div class="item_title">5color 무아 시그니처 와펜 후드 집업</div>
<box class="price">
<div class="item_discount">56%</div>
<div class="item_price">18,900</div>
</box>
</box>
</div>
<div class="item2">
<img src="img/item2_img3.png" alt="${item.type}" class="item_img2" />
<box class="item_description">
<div class="item_mall">무아무아</div>
<div class="item_title">5color 무아 시그니처 와펜 후드 집업</div>
<box class="price">
<div class="item_discount">56%</div>
<div class="item_price">18,900</div>
</box>
</box>
</div>
<div class="item2">
<img src="img/item2_img3.png" alt="${item.type}" class="item_img2" />
<box class="item_description">
<div class="item_mall">무아무아</div>
<div class="item_title">5color 무아 시그니처 와펜 후드 집업</div>
<box class="price">
<div class="item_discount">56%</div>
<div class="item_price">18,900</div>
</box>
</box>
</div>
</section>
<div class="popup">
<box class="popup_box">
<img src="img/icon_popup.png" alt="popup_icon" class="popup_icon" />
<div class="popup_text">지금 보는 상품 10만원 할인받기 ></div>
<button class="popup_close">X</button>
</box>
</div>
<footer class="footer">
<box class="footerbox">
<button class="btn_footer">
<img src="img/icon1_footer.png" alt="icon1" class="imt_footer" />
<div class="text_footer">홈</div>
</button>
<button class="btn_footer">
<img src="img/icon2_footer.png" alt="" class="imt_footer" />
<div class="text_footer">쇼핑몰</div>
</button>
<button class="btn_footer">
<img src="img/icon3_footer.png" alt="" class="imt_footer" />
<div class="text_footer">모아보기</div>
</button>
<button class="btn_footer">
<img src="img/icon4_footer.png" alt="" class="imt_footer" />
<div class="text_footer">찜</div>
</button>
<button class="btn_footer">
<img src="img/icon5_footer.png" alt="" class="imt_footer" />
<div class="text_footer">마이페이지</div>
</button>
</box>
</footer>
<script defer src="src/main.js"></script>
</body>
</html>
css
::-webkit-scrollbar {
width: 3px;
height: 3 px;
}
::-webkit-scrollbar-thumb {
background-color: transparent;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
:root {
--height-navbar: 40px;
--font-size-item: 10px;
--font-color: rgb(65, 65, 65);
/* --width-item: 10px; */
/* 아이템 */
--item-padding: 2px;
--item-height: 200px;
--item-width: 170px;
--item-border-radius: 5px;
}
body {
padding: 20px;
font-family: "paybook_font";
}
.navbar {
background-color: transparent;
display: flex;
justify-content: center;
justify-content: space-between;
align-items: center;
height: var(--height-navbar);
/* padding: 10px; */
}
.logo {
height: var(--height-navbar);
}
.cart {
height: var(--height-navbar);
}
.search {
border: none;
border-radius: 50px;
background-color: rgb(245, 245, 245);
height: 33px;
width: 250px;
}
.homebar {
display: flex;
justify-content: center;
justify-content: space-around;
height: 50px;
}
.navbar2 {
display: flex;
justify-content: flex-end;
/* justify-content: space-around; */
padding-top: 5px;
height: 30px;
}
.home1,
.home2,
.home3,
.home4,
.home5,
.menu1,
.menu2,
.menu3,
.menu4,
.menu5 {
font-weight: bold;
border: none;
background-color: transparent;
font-size: 15px;
color: gray;
cursor: pointer;
}
/* 배너 */
/* input radio 버튼 가리기 */
.section input[id*="slide"] {
display: none;
}
/* 슬라이드 영역 크기 조절 */
.section {
display: flex;
justify-content: center;
}
.section .slidewrap {
max-width: 100vw;
margin-bottom: 20px;
margin-top: 13px;
overflow: hidden;
/* 영역보다 큰 부분은 자르기 */
}
.section .slidelist {
white-space: nowrap;
font-size: 0;
}
.section .slidelist > li {
display: inline-block;
/* 여기가 중요!!list태그로 만든 각 슬라이드 이미지들이 한 줄로 가로 정렬되도록 만든다.
*/
vertical-align: middle;
/* 각 이미지들의 높이가 다를 경우,가운데를 기준으로 정렬해 준다 */
width: 100%;
/* 슬라이드 영역(이미지가 노출되는 곳)에 딱맞도록 너비를 설정해준다. */
/* 여기까지 하면, 노출 영역에 딱 맞도록 첫번째 이미지만 보이게 되고, 오른쪽으로 가로로 한 줄정렬되어 있는 다른 이미지는 보이지 않게 된다. */
transition: all 0.5s;
/* 0.5초간 서서히 움직인다. */
}
.section .slidelist > li > a {
display: block;
position: relative;
/* 이건 왜지? */
}
.section .slidelist > li > a img {
width: 100%;
}
/* 좌우로 넘기는 label버튼 스타일 지정 */
.section .slidelist label {
position: absolute;
z-index: 1;
top: 50%;
transform: translateY(-50%);
padding: 50px;
cursor: pointer;
}
/* 이것도 다시 살펴보자. */
.section .slidelist .left {
left: 0px;
background: url("./img/left.png") center center / 50% no-repeat;
}
.section .slidelist .right {
right: 0px;
background: url("./img/right.png") center center/50% no-repeat;
}
/* input 체크될 경우 변화값이 li까지 전달될 수 있도록 하는 아주 중요한 부분!!!!!! */
.section input[id="slide01"]:checked ~ .slidewrap .slidelist > li {
transform: translateX(0%);
}
.section input[id="slide02"]:checked ~ .slidewrap .slidelist > li {
transform: translateX(-105%);
}
.section input[id="slide03"]:checked ~ .slidewrap .slidelist > li {
transform: translateX(-209%);
}
/* 기존 */
/*
.banner {
display: flex;
background-color: rgb(247, 62, 163);
height: 200px;
margin-bottom: 50px;
overflow: hidden;
}
.banner_img {
object-fit: cover;
}
.dots {
position: absolute;
top: 290px;
left: 220px;
}
.dot1,
.dot2,
.dot3 {
border-radius: 100px;
width: 100px;
height: 100px;
border-color: transparent;
background-color: rgb(179, 40, 121);
cursor: pointer;
} */
.title,
.title2 {
background-color: transparent;
font-weight: bold;
color: var(--font-color);
height: 150px;
margin-top: 10px;
margin-left: 10px;
}
.filters {
display: flex;
align-items: center;
justify-content: flex-end;
}
.filter_icon {
height: 15px;
}
.items {
background-color: transparent;
height: 300px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 10px;
/* flex-wrap: wrap; */
overflow-x: scroll;
}
.item {
width: var(--item-width);
height: var(--item-height);
padding: var(--item-padding);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
justify-content: space-between;
}
.item_mall {
font-size: var(--font-size-item);
padding: 1px;
font-weight: bold;
}
.item_title {
font-size: var(--font-size-item);
padding: 1px;
}
.item_price {
font-size: 15px;
font-weight: 900;
padding: 1px;
color: black;
}
.item_img {
height: var(--item-height);
width: var(--item-width);
border-radius: var(--item-border-radius);
margin-bottom: 7px;
}
.item_description {
color: var(--font-color);
width: var(--item-width);
height: 30%;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-start;
padding-bottom: 10px;
}
/* 2열 아이템 목록*/
.otheritems {
display: flex;
flex-direction: row;
padding: 10px;
flex-wrap: wrap;
/* justify-content: space-between; */
}
.item2 {
width: 47%;
padding: 5px;
}
.item_img2 {
height: 70%;
width: 100%;
padding: var(--item-padding);
}
.price {
display: flex;
align-items: center;
}
.item_discount {
font-size: 20px;
color: rgb(255, 51, 129);
font-weight: bold;
}
/* 팝업 */
.popup {
position: fixed;
bottom: 80px;
left: 70px;
display: flex;
justify-content: center;
}
.popup_box {
height: 40px;
width: 400px;
border-radius: 7px;
/* margin: 20px; */
background-color: rgb(44, 44, 44);
display: flex;
align-items: center;
}
.popup_icon {
height: 15px;
border-radius: 100px;
margin-left: 13px;
}
.popup_text {
margin-left: 15px;
color: rgba(228, 228, 228, 0.801);
font-size: 1px;
font-weight: 700;
}
.popup_close {
background-color: transparent;
border: none;
color: rgba(255, 255, 255, 0.404);
font-size: 5px;
margin-left: 170px;
cursor: pointer;
}
/* footer */
.footerbox {
position: fixed;
background-color: white;
left: 40px;
bottom: 0px;
width: 470px;
height: 70px;
display: flex;
justify-content: space-between;
}
.footer {
/* background-color: white; */
position: fixed;
bottom: 0px;
background-color: transparent;
margin-top: 20px;
border: 10px;
height: 100px;
display: flex;
justify-content: space-around;
}
.btn_footer {
font-size: 10px;
background-color: transparent;
border: none;
margin-top: 1px;
}
.text_footer {
color: gray;
margin-top: 4px;
}
.popup_icon.active {
visibility: hidden;
}
.popup_text.active {
color: transparent;
}
.popup_close.active {
color: transparent;
}
.popup_box.active {
background-color: transparent;
}
.home1:hover,
.home2:hover,
.home3:hover,
.home4:hover,
.home5:hover {
color: black;
border-bottom: 3px solid black;
}
js
function loaditems() {
return fetch("data/data.json")
.then((response) => response.json())
.then((json) => json.items);
// .catch(console.log("error"));
}
function displayitems(items) {
const container = document.querySelector(".items");
// const html = items.map((item) => createHTMLString(item)).join("");
// console.log(html);
container.innerHTML = items.map((item) => createHTMLString(item)).join("");
}
function createHTMLString(item) {
return `
<div class="item">
<img src="${item.image}" alt="${item.type}" class="item_img" />
<box class="item_description">
<div class="item_mall">${item.mall}</div>
<div class="item_title">${item.title}</div>
<div class="item_price">"${item.price}"</div>
</box>
</div>`;
}
/*아이템 이미지 출처
청순 브라운 니트 :라이키365 https://m.likey365.com/product/detail.html?product_no=33907
아이보리 골지니트:무신사 로에일 https://www.google.com/url?sa=i&url=https%3A%2F%2Fstore.musinsa.com%2Fapp%2Fgoods%2F1720790&psig=AOvVaw2mmAJIIfO4lZarfUADqId8&ust=1623554481392000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCMCc1JySkfECFQAAAAAdAAAAABAL
밴딩 부츠컷 바지: 올리비아 하슬러 https://www.google.com/url?sa=i&url=http%3A%2F%2Fprod.danawa.com%2Finfo%2F%3Fpcode%3D12454157&psig=AOvVaw1YSvFJuOermAmCQcQMaZtC&ust=1623554671922000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCLjf686SkfECFQAAAAAdAAAAABAG
*/
// 버튼 클릭 시 아이템 필터링 하기
function onButtonClick(event, items) {
const dataset = event.target.dataset;
const key = dataset.key;
const value = dataset.value;
// console.log("ss");
console.log(event.target.dataset.key);
console.log(event.target.dataset.value);
if (key == null || value == null) {
return;
}
const filtered = items.filter((item) => item[key] === value);
console.log(filtered);
displayitems(filtered);
// displayitems(items.filter((item) => item[key] === value));
}
function setEventListeners(items) {
const logo = document.querySelector(".logo");
const menu = document.querySelector(".navbar2");
//이 때,html에서는 각 버튼의 클래스는 따로 지정해준 뒤, 이 버튼들을 묶은 상위 클래스에 클릭 이벤트를 적용한다.
// querySelector 와 getElementbyId는 뭐가 다를까?
// logo.addEventListener("click", () => displayitems(items));
menu.addEventListener("click", (event) => onButtonClick(event, items));
// console.log("event");
}
loaditems()
.then((items) => {
displayitems(items);
setEventListeners(items);
})
.catch(console.log);
// 팝업 창 클릭해 닫기
const popup_close = document.querySelector(".popup_close");
const popup_box = document.querySelector(".popup_box");
const popup_icon = document.querySelector(".popup_icon");
const popup_text = document.querySelector(".popup_text");
// 팝업 창 닫기 버튼을 누르면 이벤트 발생
popup_close.addEventListener("click", () => {
popup_box.classList.toggle("active");
console.log("delete box");
popup_icon.classList.toggle("active");
console.log("delete icon");
popup_text.classList.toggle("active");
console.log("delete text");
popup_close.classList.toggle("active");
console.log("delete close icon");
console.log("창닫기 클릭");
// popup_close의 classList중 active 클래스를 토글링
// =마우스 클릭시 클래스가 액티브가 있다면 빼주고,없다면 액티브 추가
});
// 배너 이미지 변경
// 원래 내가 작성했던 코드
function dot2click() {
const banner_img = document.querySelector("banner_img");
const dot1 = document.querySelector("dot1");
const dot2 = document.querySelector("dot2");
// banner_img.setAttribute("src", "img/banner3_zigzag.png");
document
.getElementById("banner_img")
.setAttribute("src", "img/banner3_zigzag.png");
}
//element.setAttribute('attribute_name','attribute_value');
// 출처: https://kkamikoon.tistory.com/139 [컴퓨터를 다루다]
// const imgs = ["img/image1.jpg", "img/image2.jpg", "img/image3.jpg"];
// let index = 0;
// document.getElementById("roadtrip").addEventListener(
// "click",
// clickimg // If you'll do this, remove the onclick attribute from the img tag
// );
// function clickimg(e) {
// e.target.src = imgs[index]; // Change the src of the clicked image
// index = ++index % imgs.length; // Increase index, shows the first image when the length of the array is reached
// }
// const dot3 = document.querySelector("dot3");
// window.onload = function () {
// function banner_change(banner_img) {
// dot2.addEventListener("click", () => dotclick());
// console.log("click");
// banner_img.src = "img/banner2_zigzag.png";
// console.log("pressed dot 2");
// banner_img.innerHTML = "img/banner2_zigzag.png";
// console.log("pressed dot 2");
// // // EventListener, setAttribute, querySelector, getElementbyClass에 대해 한번 정리해야겠다.
// }
// banner_change();
// window.onload = function () {
// dot2.addEventListener("click", () => {
// console.log("click");
// // banner_img.src = "img/banner2_zigzag.png";
// console.log("pressed dot 2");
// // banner_img.innerHTML = "img/banner2_zigzag.png";
// console.log("pressed dot 2");
// });
// };
// // EventListener, setAttribute, querySelector, getElementbyClass에 대해 한번 정리해야겠다.
// };
// banner_change();
// 강의
// const bannerslide = document.querySelector("banner_slide");
// const banner_img = document.querySelectorAll("banner_img");
// // queryselectorall을 썼다! 배너 이미지를 클래스로 가진 것들이 여러개이기 때문
// // buttons
// const dot1 = document.querySelector("dot1");
// const dot2 = document.querySelector("dot2");
// // counter
// let counter = 1;
// const size = banner_img[0].clientwidth;
// ?????
// bannerslide.getElementsByClassName.transform =
// "translateX(" + -size * counter + "px";
// button listeners
// window.onload = function () {
// dot2.addEventListener("click", () => {
// bannerslide.style.transition = "transform 0.4 ease-in-out";
// counter++;
// console.log(counter);
// });
// };
// [에러]main.js:118 Uncaught TypeError: Cannot read property 'addEventListener' of null
// at main.js:118 이게 대체 뭘까?)
Author And Source
이 문제에 관하여(지그재그 클론코딩(5)(코드만)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@gygy/지그재그-코드만저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)