다노샵 클론코딩

오혜림·2022년 8월 4일
0
post-thumbnail

DANOSHOP Clone coding

1. 체크포인트

1. 자바스크립트 & 비동기처리

1-1) 자바스크립트 클릭 이벤트
1-2) json 활용 비동기통신

2. 쇼핑몰 레이아웃 & 공통 scss

2-1) 쇼핑몰 리스트 html 마크업
2-2) sticky nav(header) css
2-3) fixed top btn
2-4) css gradient
2-5) 공통 scss 정리
2-6) 추후 미디어쿼리 적용

1-1) 자바스크립트 클릭 이벤트


0. 각 클래스 요소 변수 처리
1. btn-search 클릭 시 .search-wrap display:block;
2. btn-close 클릭 시 .search-wrap display:none;

j-query

 $('.search-btn').click(function(){
  $('.search-wrap').css('display','block');
});
$('.btn-close').click(function(){
    $('.search-wrap').css('display','none');
});

java-script

const btnSearach = document.querySelector('.btn-search');
const searchWrap = document.querySelector('.search-wrap');
const btnClose = document.querySelector('.btn-close');

btnSearch.addEventListener('click',()=>{
	searchWrap.style.display = 'block';
});
btnClose.addEventListener('click',()=>{
	searchWrap.style.display = 'none';
});

*()=>{} == function(){}

1-2) json 활용 비동기통신

비동기처리 기본원리

  • json 파일 데이터
{
    "member":[
        {
            "이름":"유미",
            "나이":"18"
        },
        {
            "이름":"수미",
            "나이":"28"
        },
        {
            "이름":"혜미",
            "나이":"38"
        }
    ]
}
  • java script
fetch("./sample.json") // json파일 불러오기
.then((response) => response.json())
.then((json) => {
 const member = json.member // json데이터에 member 접근
 let html = ''; // 변수가 반복해서 계속들어갈꺼라 한번 생성
    member.forEach(el => { // 개수만큼 반복해야함
        isAdult = el.나이 < 20 ? '미성년자' : '성인' 
        // 조건문을 통한 정보 분류. json데이터의 나이에 접근하여 나이의 값이 20미만이면 '미성년자', 아니면 '성인'
        html+=`<li>이름:${el.이름}<br>성인:${isAdult}</li>`
        // 빈 칸 생성한 변수에 들어갈 html 코드입력
    });
const list1 = document.querySelector('.list');// .list 선택 변수 정의
list1.innerHTML = html; // .list에 html 삽입

결과

나는 데이터 비동기처리를 메인 슬라이드 배너와 첫번째 리스트 레이아웃에 적용해보았다.

결과

하지만 여기서 한가지 문제점이 발생하게 되는데... swiper slide loop가 안먹는다!

해결법 -> swiper code를 fetch문 맨 마지막에 넣어서 비동기 -> 스와이퍼 순서로 코딩하면 loop 문제 해결!!!

fetch("./asset/data/mainslide.json")
  .then((response) => response.json())
  .then((json) => {

    const mainSlide = json.mainSlide;

    let html = '';
    mainSlide.forEach(el => {
      html += `<div class="swiper-slide">
                    <a href="${el.url}">
                        <img src="${el.imgSrc}" alt="${el.alt}">
                    </a>
                </div>`
    });

    const slideList = document.querySelector('.sc-visual .swiper-wrapper');
    slideList.innerHTML = html;

    // 3. sc-visual swiper slide
    const slide1 = new Swiper(".slide1 .swiper", {
      loop: true,
      autoplay: {
        delay: 2000,
        disableOnInteraction: false,
      },
      pagination: {
        el: ".pagination",
        clickable: true,
      },
      navigation: {
        nextEl: ".next",
        prevEl: ".prev",
      },
    });

  });

2-1) 쇼핑몰 리스트 html 마크업


살짝 아쉬운.. 실수한 마크업
1. li > a로 이미지와 정보를 전부 감싼 것
2. 장바구니 추가 버튼을 span태그로 구현한 것
3. 리스트에서 중요한 내용(강조할 내용)을 강조하지 못한 마크업
4. 굳이 h2를 blind처리한 것
5. 광범위한 클래스명

=> 전체적으로 과한 마크업과 정작 중요한 정보는 강조가 안되어 있음

<section class="sc-type2">
 <h2 class="blind">샐러드</h2>
  <div class="text-box">
   <strong class="title">
   쓴맛 없고 싱싱한 샐러드
   <i class="ic-title greenlove"></i>
   </strong>
   <p class="desc">건강하고 가볍게 식단 챙겨요</p>
  </div>
  <div class="group-flex5">
   <ul class="product-list">
    <li class="product-item">
     <a href="#">
       <div class="thumb-box">
        <img src="./asset/images/salad-thumb1.png" alt="다노 그린믹스샐러드 / 파프리카믹스샐러드">
       <div class="badge-box">
         <span class="sale">sale</span>
       </div>
       <span class="cart"><span class="blind">장바구니 추가</span></span>
       <div class="info-box">
         <em class="free-delivery">무료배송</em>
         <span class="product-name">다노 그린믹스샐러드 / 파프리카믹스샐러드</span>
         <em class="current-sale">
           11%<del>18,900</del>
         </em>
         <span class="price">
          <span>16,900</span></span>
       </div>
      </a>
    </li>
   </ul>
 </section>
                       

개선 마크업
1. a는 .thumb-box img, .info-box에 각각 감싸서 코딩
2. 장바구니 추가버튼 button으로 변경
3. h2 blind없애고 해당 제목 영역으로 수정
4. 가격,세일은 강조되는 태그 요소로 구성
6. 애매한 클래스명은 의미가 분명하게 수정 (.text-box -> .title-box)

<section class="sc-type2">
 <div class="title-box">
  <h2 class="title">쓴맛 없고 싱싱한 샐러드<img src="./asset/images/greenlove.png" alt="초록하트아이폰이모지"></i></h2>
  <p class="desc">건강하고 가볍게 식단 챙겨요</p>
 </div>
 <div class="group-flex3">
  <ul class="product-list">
   <li class="product-item">
    <div class="thumb-box">
     <a href="#"><img src="./asset/images/salad-thumb1.png" alt="다노 그린믹스샐러드 / 파프리카믹스샐러드"></a>
     <div class="badge-box">
      <span class="sale">sale</span>
     </div>
     <button class="cart"><span class="blind">장바구니 추가</span><svg></svg>
     </button>
    </div>
      <a href="#" class="info-box">
       <em class="free-delivery"><svg></svg>무료배송</em>
       <p class="product-name">다노 그린믹스샐러드 / 파프리카믹스샐러드</p>
      <em class="current-sale">11%<del>18,900</del></em>
      <span class="price">
       <em>16,900</em></span>
      </a>
    </li>
</section>

2-2) sticky nav(header) css

sticky란? 스크롤하지 않을 때는 static position처럼 동작하다가 스크롤할 때는 fixed position과 유사하게 동작한다.

Sticky 속성은 Sticky 포지션을 사용할 요소에 Position:sticky; 로 포지션을 지정 후 top:0; 와 같이 고정될 영역만 입력해주면 된다.

-Sticky가 동작 하지 않을 때 확인 사항
1.Sticky 속성을 갖는 요소는 자신의 부모 요소안에서만 적용
2.부모요소중에 overflow:auto, overflow:hidden, overflow:scroll속성이 적용되어 있는 경우 사용 불가
3.IE(Internet Explorer) 사용 불가

sticky를 적용하기 위해서는 left,right,bottom,right의 위치값이 필수이며, height값이 존재해야한다.

2-3) fixed top btn


다노샵은 모바일 first 웹사이트이기 때문에, .wrapper에 max-width가 존재한다. 그러나 fixed가 되어야하는 top버튼의 기준점은 뷰포트가 되기 때문에, 시안과 동일하게 해당 640px안에 fixed 시키는 것이 어려웠었다.

max-width안에 fixed 처리하는 방법 2가지
1. .btn-top에 부모요소와 조부모요소(?)를 감싸서 조부모 요소에는 position:absolute; 부모요소에 position:fixed;를 주고 .btn-top에는 버튼 스타일을 지정해준다.

.fixed-area{
    position: absolute;
    bottom: 0;
    right: 90px;
}
.fixed-box{
    position: fixed;
    bottom: 54px;
    z-index: 100;
}
.btn-top{
    display: flex;
    justify-content: center;
    align-items: center;
    width: 48px;
    height: 48px;
    margin: 20px 21px;
    opacity: 0.9;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.9);
    color: $colors-gray9;
    box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1);
}
  1. 조부모,부모요소 필요없이, 뷰포트 기준으로 fixed 설정하기
    -> 대신 이 방법은 미디어쿼리로 640px 이하 디바이스 사이즈에서 위치 수정 필요
.btn-top{
	position: fixed;
    bottom: 54px;
    left: 50%;
    transform:translateX(200px);
    display: flex;
    justify-content: center;
    align-items: center;
    width: 48px;
    height: 48px;
    margin: 20px 21px;
    opacity: 0.9;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.9);
    color: $colors-gray9;
    box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1);
} 입력하세요

2-4) css gradient

https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Images/Using_CSS_gradients
css 그라디언트 속성 정의
https://cssgradient.io/
css 그라디언트 제작 사이트

2-5) 공통 scss 정리

쇼핑몰 리스트 레이아웃을 효율적으로 디자인하기 위해 리스트 공통 디자인 요소를 scss를 활용하여 정리했다.

폰트컬러 변수 할당

$font-kr1:'Noto Sans KR', sans-serif;

$colors-coral10: #FFF5F0;
$colors-coral20: #F9CEC2;
$colors-coral40: #FEB49B;
$colors-coral60: #FE8F71;
$colors-coral80: #FE7B66;
$colors-coral100: #FF6F61;
$colors-coral100_disabled: #FFB7B0;
$colors-coral150: #FF473D;
$colors-green80: #008282;
$colors-green100: #0B666A;
$colors-dark1: #000000;
$colors-gray9: #222222;
$colors-gray8: #3B3B3B;
$colors-gray7: #696969;
$colors-gray6: #A1A1A1;
$colors-gray5: #C4C4C4;
$colors-gray4: #DADADA;
$colors-gray3: #ECECEC;
$colors-gray2: #F3F3F3;
$colors-gray1: #F8F8F8;
$colors-white: #FFFFFF;

_title.scss 리스트 레이아웃의 제목 섹션 공통 디자인

.title-box{
    position: relative;
    padding: 16px 20px;
    .title{
        display: flex;
        align-items: center;
        font-size: 22px;
        line-height: 150%;
        font-weight: 700;
        color: $colors-gray9;
        word-break: keep-all;
        @include ellip(150%, 2);
        margin-bottom: 4px;
        img{
            display: inline-block;
            width: 24px;
            height: 24px;
            margin-left: 1px;
            vertical-align: -4px;
            object-fit: contain;
        }
    }
    .desc{
        display: flex;
        align-items: center;
        font-size: 16px;
        line-height: 150%;
        font-weight: 500;
        color: $colors-gray6;
        img{
            display: inline-block;
            width: 16px;
            height: 16px;
            vertical-align: -4px;
        }
    }
    .link-more{
        position: absolute;
        right: 16px;
        top: 20px;
    }
}

_product.scss 쇼핑몰 리스트 레이아웃 공통 디자인 영역

.product-main,
.product-item{
    .thumb-box{
        position: relative;
        img{
            border-radius: 12px;
        }
    }
    .badge-box{
        position: absolute;
        top: 10px;
        left: 10px;
    }
    .sale{
        display: inline-flex;
        align-items: center;
        justify-content: center;
        height: 18px;
        padding: 4px;
        margin-right: 4px;
        line-height: 11px;
        font-size: 11px;
        font-weight: 700;
        border-radius: 4px;
        text-transform: uppercase;
        color: $colors-white;
        background-color: $colors-coral150;
    }
    .new{
        display: inline-flex;
        align-items: center;
        justify-content: center;
        height: 18px;
        padding: 4px;
        line-height: 11px;
        font-size: 11px;
        font-weight: 700;
        border-radius: 4px;
        text-transform: uppercase;
        color: $colors-coral100;
        background-color: $colors-coral10;
    }
    .cart{
        position: absolute;
        bottom: 10px;
        right: 10px;
        width: 40px;
        height: 40px;
        padding: 8px;
        border-radius: 50%;
        color: $colors-white;
        box-shadow:  0px 0px 2px rgba(0, 0, 0, 0.1);
        background-color: rgba($color: #000000, $alpha: 0.6);
    }
    .info-box{
        padding: 10px 0;
        display: flex;
        flex-direction: column;
    }
    .free-delivery{
        display: flex;
        font-size: 13px;
        line-height: 160%;
        color: $colors-gray6;
    }
    .current-sale{
        color: $colors-coral100;
        font-weight: 700;
        del{
            color: $colors-gray6;
            font-weight: 400;
        }
    }
    .product-name{
        color: $colors-gray8;
        font-weight: 500;
    }
    .price{
        em{
            font-weight: 700;
            margin-right: 2px;
            color: $colors-gray8;
            .sc-type4 &{
                color: $colors-coral100;
            }
        }
    }
}
profile
퍼블리싱 코딩기록

0개의 댓글