API
Fetch
javascript
portfolio
#AMOREMALL
#모바일 적응형
#데이터비동기처리
#fetch()
#json
#swiper
📌 PROJECT KEY POINTS
fetch()
함수로 데이터 호출 (feat.JSON)swiper
사용한 슬라이드
1. fetch() 함수로 데이터 호출 (feat.JSON)
👉🏻 아모레몰의 상품 영역은 거의 비슷한 레이아웃을 가지고 있어 매번 새로운 json 데이터를 만드는 것이 아니라 하나의 prdData.json 파일을 활용. 필요한 부분만 추출해 각 영역의 fetch문에 재사용하여 파일과 코드를 좀 더 간결하게 작성.
- json
{
"items":[
{
"id":0,
"thumb": "./assets/img/recom01.png",
"saleThumb":"./assets/img/sale_first_01.png",
"brand":"아이오페",
"name":"슈퍼바이탈 기초 2종 세트 (150ml+150ml)",
"price":{
"ori":125000,
"curr":95000
},
"rate": "4.8",
"review":"(6)",
"hashtag": "#유수분 밸런스",
"benefit":[
"사은품"
],
"cate1":0,
"cate2":2,
"cate3":2,
"sale1":0
},
....
]
}
- js
fetch("./assets/data/prdData.json")
.then((response) => response.json())
.then((json) => {
data = json.items;
let html = '';
data.forEach(element => {
benefitHtml = '';
element.benefit.forEach(benefitEl => {
benefitHtml += `<span>${benefitEl}</span>`;
});
const saleEl = (element.price.ori === element.price.curr) ? 'hide' : '';
html += `
<div class="swiper-slide">
<div class="product-inner">
<a href="">
<div class="pro-thumb-area">
<img src="${element.thumb}" alt="${element.name}" />
</div>
<div class="pro-text-area">
<div class="pro-title">
<strong class="brand">${element.brand}</strong>
<span class="name">${element.name}</span>
</div>
<div class="pro-price">
<span class="del-price ${saleEl}">${price(element.price.ori)}</span>
<em class="discount-rate ${saleEl}">${salepercent(element.price.ori, element.price.curr)}%</em>
<span class="price"><strong class="size_16">${price(element.price.curr)}</strong>원</span>
</div>
<div class="pro-rate">
<span class="icon-star">
<span>${element.rate}</span>
<span>${element.review}</span>
</span>
</div>
<div class="pro-gift">${benefitHtml}</div>
</div>
</a>
<button class="pro-like"><span class="blind">좋아요</span></button>
</div>
</div>`;
});
$('#adviceData').html(html);
🖋 code review
fetch("./assets/data/prdData.json")
불러올 json 데이터 파일then((response) => response.json())
읽어온 데이터를 json으로 변환data = json.items;
json에 있는 items만 받아오기data.forEach(element => {})
배열의 개수만큼 반복문을 돌리기 위해 사용${element.name}
형식으로 경로를 작성하여 각 부분에 필요한 데이터를 불러옵니다.saleEl = (element.price.ori === element.price.curr) ? 'hide':'';
할인가가 없어서 판매가만 존재하는 경우를 위한 조건문 -> 'ori'금액과 'curr'의 금액이 같을때'hide'클래스를 추가해 할인가와 할인율을 display:none 시켜주었습니다.
// 천단위 콤마(정규식)
function price(p) {
return p.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
//할인율 함수
function salepercent(ori, curr) {
return (ori - curr) / ori * 100;
}
- 할인율 영역은 데이터 파일에 담겨진 'ori', 'curr'의 값을 이용하여 return 값을 받도록 하였습니다.
- 배열의 요소를 나타내는 문자열을 반환하는 toLocaleString() 메서드를 사용해 가격의 천단위 콤마 정규식 패턴을 사용하였다.
- js
//첫 페이지에 보여줄 데이터
sortFirst(0, 2);
function sortFirst(a, b) {
sortData(a, b);
popSkinItems[a].classList.add('active');
const skinSiblings = Array.from(popSkinItems[a].parentNode.children).filter(el => el !== popSkinItems[a]);
skinSiblings.forEach(sibling => sibling.classList.remove('active'));
popTroubleItems[b].classList.add('active');
const troubleSiblings = Array.from(popTroubleItems[b].parentNode.children).filter(el => el !== popTroubleItems[b]);
troubleSiblings.forEach(sibling => sibling.classList.remove('active'));
}
// 데이터 필터링 해줄 함수
function sortData(cate1, cate2) {
fetch("./assets/data/prdData.json")
.then((response) => response.json())
.then((json) => {
const data = json.items;
const result = data.filter((parm) => parm.cate1 == cate1 || parm.cate2 == cate2);
let html = '';
result.forEach(element => {
const saleEl = (element.price.ori === element.price.curr) ? 'hide' : '';
html += `
... `;//중복으로 생략
});
sortDataContainer.innerHTML = html;
});
}
- 버튼 클릭시 각 타입에 맞는 상품을 보여주기 위해 fetch문을 함수에 넣어주고 filter() 메서드로 데이터 필터링을 하였습니다.
filter 란❔
자바스크립트에서 filter 는 배열에 사용하며, 주어진 함수를 만족하는 모든 요소를 모아 새 배열로 반환합니다.
- const result = data.filter(function (parm) {return parm.cate1 == cate1 || parm.cate2 == cate2});
: cate1, cate2와 맞는 데이터만 나오도록 세팅(두가지 타입 모두 충족하게 하고 싶다면 '&&'사용
💡 ||(or연산자), &&(and연산자)
▪️ json 데이터의 활용
'메인 배너 영역'과 '이벤트 전체보기 팝업 영역'의 데이터가 같아 새로운 파일을 만들지 않고 하나의 JSON 데이터 파일을 활용하여 구현하였습니다.
2. swiper 사용한 슬라이더
- 페이지 내 대부분에 슬라이더를 사용
-html
<section class="sc-mainbanner swiper" id="banner_swiper">
<h2 class="blind">메인 배너 영역</h2>
<div class="swiper-wrapper" id="bannerData1"></div>
<div class="swiper-page">
<div class="page-area">
</div>
<button class="btn-area" id="allBanner"><span class="blind">전체보기</span></button>
</div>
</section>
-js
const swiper2 = new Swiper("#banner_swiper", {
slidesPerView: 'auto',
spaceBetween: 5,
loop: true,
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
centeredSlides: true,
// pagination
pagination: {
el: ".page-area",
type: "custom",
renderCustom: function (swiper, current, total) {
currentNum = (current < 10) ? '0' + current : current;
totalNum = (total < 10) ? '0' + total : total;
return `<span class="page-current">${currentNum}</span>
<span class="page-total">${totalNum}</span>`;
}
},
});
🖋 code review
* swiper 사용시 아래 구조와 같은 클래스 명을 지정해줘야 합니다.swiper > swiper-wrapper > swiper-slide
* spaceBetween: 5, css에서 마진값을 주지 않고 swiper의 속성인 spaceBetween은 사용하여 슬라이드의 여백을 설정하였습니다.
* disableOnInteraction: false 마우스 클릭시 슬라이드 멈춤 제어(true: 일시정지, false: 재생)
* pagination을 커스텀하기 위해 type: "custom"으로 바꾸어 주고 renderCustom 속성을 이용해 현재 페이지/전체 페이지수를 표현하였습니다.
* return 값으로 미리 마크업 했던 코드를 사용해 커스텀 하였는데 이때 10 미만의 수에는 앞에 '0'이 붙는 조건문을 사용하여 01/09 형식의 pagination을 구현하였습니다.
💡 Swiper 사용시 주의할 점
- swiper-wrapper, swiper-slide 클래스 이름 제대로 들어갔는지 확인하기
- 슬라이더를 여러 개 만들 때 각각의 변수명과 클래스 이름을 다 구분지어주기
'portfolio' 카테고리의 다른 글
SEOUL CITY HALL (0) | 2023.07.07 |
---|---|
NAVER (0) | 2023.07.07 |
FLO (0) | 2023.07.07 |