사이트명 : 미미즈
작업 기간 : 23.03.06 ~ 23.03.09 (4일 소요)
라이브러리 : swiper, json
유형 : Mobile 적응형, 클론코딩
특징 : 탭 메뉴, swiper슬라이드와 json데이터 통신을 접목시킨 페이지
.header.hide { transform: translate(-50%, -100%); }
.fixed-menu.hide { transform: translate(-50%, 100%); }
/* sideBtn */
.group-sideBtn {
position: fixed;
z-index: 10;
bottom: 100px;
left: 50%;
/* bottom 에만 모션이 들어가게 */
transition: bottom .3s;
margin-left: 430px;
}
.group-sideBtn.down { bottom: 10px; }
.group-sideBtn.up { bottom: 100px; }
.group-sideBtn.hide { visibility: hidden; }
/* Sub page - detail */
.sc-detail .subMenu-area.fixed {
position: fixed; z-index: 30;
top: 0; left: 50%;
transform: translateX(-50%);
max-width: 1025px; }
.sc-detail .group-tit.detail-tit.hide { top: -50px; }
.sc-detail .group-tit.detail-tit.hide02 { top: -100px; }
$(function(){
// header gnb
lastScroll = 0;
$(window).scroll(function(){
curr = $(window).scrollTop();
if(curr > lastScroll){
$('.header, .fixed-menu, .group-tit, .group-tit.goods, .goods .group-sub-menu').addClass('hide');
$('.group-sideBtn').addClass('down');
}else {
$('.header, .fixed-menu, .group-tit, .group-tit.goods, .goods .group-sub-menu').removeClass('hide');
$('.group-sideBtn').removeClass('down');
}
// subMenu
if(curr > 700 ){
$('.sc-detail .subMenu-area').addClass('fixed');
$('.sc-detail .group-tit.detail-tit').addClass('hide02');
}else {
$('.sc-detail .subMenu-area').removeClass('fixed');
$('.sc-detail .group-tit.detail-tit').removeClass('hide02');
}
if (curr == 0){
$('.group-sideBtn').addClass('hide');
}else {
$('.group-sideBtn').removeClass('hide');
}
lastScroll = curr
})
$(window).trigger('scroll');
- if 조건문 활용 :
if(curr > lastScroll){
스크롤 내릴 때
}else {}
스크롤 올릴 때if(curr > 700 ){
스크롤 올렸을 때 Subpage title 사라지게 하기if (curr == 0){
스크롤이 제일 위쪽에 있을 때 sideBtn 사라지게 하기- 첫 로드 후 스크롤 이벤트 바로 실행
$(window).trigger('scroll');
처음부터 sideBtn이 인식을 해야하기 때문에 scroll 강제 실행해주기 위해trigger
태그 사용- Sub page의 Title부분에도 이와 같은 모션을 주었습니다.
📋 Review 영역 : 매번 새로운 json 데이터를 만드는 것이 아니라 하나의 reviewData.json 파일을 활용하였습니다. 필요한 부분만 추출해 각 영역의 fetch문에 재사용하여 파일과 코드를 좀 더 간결하게 작성하였습니다.
{
"items":[
{
"snippets":{
"thumbnails":{
"url":"./assets/images/main/review01.jpeg"
},
"review":4,
"title":"첫 굿즈 구매입니다💜",
"desc":"아쉽게도 알바를 다녀와서 직접 언박싱은 못했지만 집에 와보니 의자에 멋사쿠션이?? 보자마자 너무 행복했습니당 ㅜㅜ! 화이트색상에 멋사님 영상에서처럼 떡처럼 늘어나서 귀엽고 포근해요💜 폰케이스는 A랑 단독으로 C를 구매했는데 정말 후회중이에요.. 왜 B, D는 안..",
"bookmark":81,
"product":{
"thumbnails":"https://memez861.cdn-nhncommerce.com/data/goods/22/10/40/3388/3388_main_056.jpg",
"title":"멋사 북극곰 풀세트 (얼굴쿠션 + 젤리 폰케이스)",
"price":{
"sale":"42,300",
"origin":"47,000",
"per":"10"
}
}
}
},
{
"snippets":{
"thumbnails":{
"url":"./assets/images/main/review01.jpeg"
},
"review":4,
"title":"22첫 굿즈 구매입니다💜",
"desc":"아쉽게도 알바를 다녀와서 직접 언박싱은 못했지만 집에 와보니 의자에 멋사쿠션이?? 보자마자 너무 행복했습니당 ㅜㅜ! 화이트색상에 멋사님 영상에서처럼 떡처럼 늘어나서 귀엽고 포근해요💜 폰케이스는 A랑 단독으로 C를 구매했는데 정말 후회중이에요.. 왜 B, D는 안..",
"bookmark":81,
"product":{
"thumbnails":"https://memez861.cdn-nhncommerce.com/data/goods/22/10/40/3388/3388_main_056.jpg",
"title":"멋사 북극곰 풀세트 (얼굴쿠션 + 젤리 폰케이스)",
"price":{
"sale":"42,300",
"origin":"47,000",
"per":"10"
}
}
}
}
]
}
fetch('./assets/data/reviewData.json')
.then((response) => response.json())
.then((json) => {
data = json.items;
let html = '';
data.forEach(element => {
html+=`<div class="swiper-slide">
<a href="">
<img src="${element.snippets.thumbnails.url}" alt="">
</a>
<div class="group-txt">
<div class="review-area">
<div class="star-wrap">
<span class="star">
<span class="star-on" style="width:${element.snippets.thumbnails.review/5*100}%">
<span class="blind">별 다섯개 중 다섯개</span>
</span>
</span>
</div>
<p>${element.snippets.title}</p>
<a href="">${element.snippets.desc}
</a>
</div>
<div class="goods-area">
<div class="info-area">
<a href="" class="img-box">
<img src="${element.snippets.product.thumbnails}" alt="${element}">
</a>
<a href="" class="info-box">
<p>${element.snippets.product.title}</p>
<div class="price">
<strong class="per">${element.snippets.product.per}</strong>
<em class="sale">${element.snippets.product.sale}</em>
<span class="origin">${element.snippets.product.origin}</span>
</div>
</a>
</div>
<div class="wish-box">
<span class="blind">찜하기</span>
<button type="button" class="btn-wish"></button>
<span class="wish-caunt">${element.snippets.bookmark}</span>
</div>
</div>
</div>`
});
$('#reviewList').html(html);
})
fetch("./assets/data/prdData.json")
불러올 json 데이터 파일.then((response) => response.json())
읽어온 데이터를 json으로 변환data = json.items;
json에 있는 items만 받아오기data.forEach(element => {})
배열의 개수만큼 반복문을 돌리기 위해 사용${element.name}
형식으로 경로를 작성하여 각 부분에 필요한 데이터를 불러오기<span class="star-on" style="width:${element.snippets.thumbnails.review/5*100}%">
백분율 계산하여 만족도 시각효과 주기
📋 현 사이트에서는 리스트의 갯수가 적어 keyframe animaiton 으로 슬라이드 효과를 주었지만, 추후에 공지사항 리스트들의 갯수가 늘어나게 된다면 유지보수에 적합하지 않다고 생각하여 Swiper 라이브러리를 활용한 슬라이드로 재구성하였습니다.
<section class="sc-notice">
<h2 class="blind">공지사항</h2>
<div class="group-notice">
<h3 class="tit">notice</h3>
<div class="swiper noticeSwiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<a href="">[MEMEZ] 설 연휴 배송 안내</a>
</div>
<div class="swiper-slide">
<a href="">[MEMEZ] <하하하 - 냥테미즘 행운카드 세트> 불량 제품 '보상' 신청 안내</a>
</div>
<div class="swiper-slide">
<a href="">[MEMEZ] 라디유 '디유는 못말려' 인형 배송 박스 파손...</a>
</div>
</div>
</div>
</div>
</section>
// footer - noticeSwiper
var swiper = new Swiper(".noticeSwiper", {
direction: "vertical",
pagination: {
el: ".swiper-pagination",
clickable: true,
},
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
direction: getDirection(),
on: {
resize: function () {
swiper.changeDirection(getDirection());
},
},
});
function getDirection() {
var windowWidth = window.innerWidth;
var direction = window.innerWidth <= 760 ? 'vertical' : 'horizontal';
return direction;
}
- vertical 플러그인 ,Autoplay 플러그인 등을 활용하여 슬라이드 구성
var direction = window.innerWidth <= 760 ? 'vertical' : 'horizontal';
window 의 창이 760보다 같거나 작다면 vertical slide, 그렇지 않다면 horizontal slide로 조건문 생성
//btn-wish
$('.btn-wish').click(function(e){
e.preventDefault();
alert('로그인하셔야 본 서비스를 이용하실 수 있습니다');
window.open("./html/login.html", "_self");
return false;
});
- 단순히 팝업창만 보이게 하는게 아니라 페이지 내에서 링크이동을 할 수 있도록
window.open("./html/login.html", "_self");
코드 입력
window.open 기존창 참고 사이트
// top button $('.group-sideBtn .btn-top').click(function(){ window.scrollTo({top:0,behavior:"smooth"}) })
behavior:"smooth"
화면이 부드럽게 위로 올라가게 함
<div class="group-search">
<form action="" method="get" id="searchForm">
<fieldset>
<legend class="blind">검색</legend>
<div class="wrap">
<input type="text" class="input-text" placeholder="침착맨의 침착 장패드">
<button type="submit" class="btn-submit">
<span class="blind">검색</span>
</button>
</div>
</fieldset>
</form>
<button class="btn-close">닫기</button>
</div>
$('#searchForm').submit(function(){
keyword = $(this).find('.input-text');
if (!keyword.val()) {
alert('검색어를 입력하세요');
keyword.focus();
return false;
}
})
- 검색창이기 때문에
form
태그를 이용해서 html 을 구성Form
태그의 onsubmit을 사용하지 않고 jquery$('#theForm').submit(function(event){})
을 이용this
: 내가 선택한 #searchFormif (!keyword.val()) {
키워드 없이 검색창을 누를 경우 alert 창이 뜨게 하기 위해서 if 구문 활용return false;
더이상 실행되지 않게 스크립트 끝내주기