본문 바로가기

코딩도 합니다/JS

[자바스크립트js / 프로젝트5] 이미지 스크롤 / hover 시 dom 이동 / 필터 기능 / dataset / toLowerCase() / trim()



안녕하세요.

디자인도 하고, 개발도 하는 '디발자 뚝딱'입니다.

 

이번 포스팅에서는

자바스크립트의 기능인 이미지 스크롤, hover하면 dom이동, 필터, dataset, toLowerCase를 사용하여 웹을 구현해보겠습니다.

 

먼저 완성된 화면을 먼저 봐주세요.

  • [welcome to Tooktak's 부분]
    스크롤에 따라 이미지가 보여지는 부분이 바뀐다.
  • [about Took 부분]
    이미지에 마우스 hover 시 노란 테두리 박스가 이미지에 겹쳐진다.
  • [our Store 부분]
    각 버튼을 누르면 해당 내용의 이미지만 선택되어 보여진다.

 

 

 

 

  html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <!-- bootstrap css -->
  <link rel="stylesheet" href="css/bootstrap.min.css">
  <!-- main css -->
  <link rel="stylesheet" href="css/style.css">

  <!-- font awesome -->
  <link rel="stylesheet" href="css/all.css">
  <title>Tooktak Project 5</title>
  <style>
  </style>
</head>

<body>
  <!-- header -->
  <header>
    <!-- navbar  -->
    <nav class="navbar navbar-expand-lg px-4">
      <a class="navbar-brand" href="#"><img class="logo" src="img/logo.png" alt="망치"></a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#myNav">
        <span class="toggler-icon"><i class="fas fa-bars"></i></span>
      </button>
      <div class="collapse navbar-collapse" id="myNav">
        <ul class="navbar-nav mx-auto text-capitalize">
          <li class="nav-item active">
            <a class="nav-link" href="#">home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link " href="#">about</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">store</a>
          </li>
        </ul>
      </div>
    </nav>
    <!-- end of nav -->



    <!-- banner  -->
    <div class="container-fluid">
      <div class="row max-height justify-content-center align-items-center">
        <div class="col-10 mx-auto banner text-center">
          <h1 class="text-capitalize">welcome to <strong class="banner-title ">Tooktak's</strong></h1>
          <a href="#store" class="btn banner-link text-uppercase my-2">EVENT</a>
        </div>
      </div>
    </div>
    <!--end of  banner  -->



  </header>
  <!-- header -->
  <!-- about us -->
  <section class="about py-5" id="about">
    <div class="container">

      <div class="row">
        <div class="col-10 mx-auto col-md-6 my-5">
          <h1 class="text-capitalize">about <strong class="banner-title ">Took</strong></h1>
          <p class="my-4 text-muted w-75">Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, aliquam voluptas
            beatae vitae expedita consectetur nesciunt quia deserunt asperiores facere fuga dicta fugiat corrupti et omnis
            porro at dolorum! Ad!</p>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase ">go</a>

        </div>
        <div class="col-10 mx-auto col-md-6 align-self-center my-5">
          <div class="about-img__container">
            <img src="img/about.jpg" class="img-fluid" alt="">
          </div>
        </div>
      </div>
    </div>
  </section>
  <!-- end of about us -->



  <!-- store -->
  <section id="store" class="store py-5">
    <div class="container">
      <!-- section title -->
      <div class="row">
        <div class="col-10 mx-auto col-sm-6 text-center">
          <h1 class="text-capitalize">our <strong class="banner-title ">store</strong></h1>
        </div>
      </div>
      <!-- end of section title -->



      <!--filter buttons -->
      <div class="row">
        <div class=" col-lg-8 mx-auto d-flex justify-content-around my-2 sortBtn flex-wrap">
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="all"> all</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="cakes">cakes</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="cupcakes">cupcakes</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="sweets">sweets</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="doughnuts">doughnuts</a>
        </div>
      </div>
      <!-- search box -->
      <div class="row">

        <div class="col-10 mx-auto col-md-6">
          <form>
            <div class="input-group mb-3">
              <div class="input-group-prepend ">
                <span class="input-group-text search-box" id="search-icon"><i class="fas fa-search"></i></span>
              </div>
              <input type="text" class="form-control" placeholder='item....' id="search-item">
            </div>

          </form>
        </div>
      </div>
      <!--end of filter buttons -->
      <!-- store  items-->
      <div class="row" id="store-items">
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
          <div class="card ">
            <div class="img-container">
              <img src="img/sweets-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">sweet item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cupcake-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cupcake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cake-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
          <div class="card ">
            <div class="img-container">
              <img src="img/doughnut-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">dougnut item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
          <div class="card ">
            <div class="img-container">
              <img src="img/sweets-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">sweet item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cupcake-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cupcake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cake-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
          <div class="card ">
            <div class="img-container">
              <img src="img/doughnut-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">dougnut item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
          <div class="card ">
            <div class="img-container">
              <img src="img/sweets-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">sweet item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cupcake-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cupcake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cake-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
          <div class="card ">
            <div class="img-container">
              <img src="img/doughnut-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">dougnut item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->

      </div>
  </section>
  <!--end of store items -->



  <!-- jquery -->
  <script src="js/jquery-3.3.1.min.js"></script>
  <!-- bootstrap js -->
  <script src="js/bootstrap.bundle.min.js"></script>
  <!-- script js -->
  <script src="js/app.js"></script>
</body>

</html>

 

 

 

 

 

  js

// 필터 버튼 기능
(function(){
    // const buttons = document.querySelectorAll('.btn')
    // const storeItems = document.querySelectorAll('.store-item')
    //console.log(buttons)
    // buttons.forEach(function(button){
    //     button.addEventListener('click', function(e){
    //         //prevent the default link jump to top of page
    //         e.preventDefault()
    //         //grab the filter button that was clicked
    //         const filter = e.target.dataset.filter
    //         if (filter === 'all'){
    //             //show all items
    //             storeItems.forEach(function(item){
    //                 item.style.display = 'block'
    //             })
    //         } else if (filter === 'cakes'){
    //             storeItems.forEach(function(item){
    //                 if (item.classList.contains('cakes')){
    //                     item.style.display = 'block'
    //                 } else {
    //                     item.style.display = 'none'
    //                 }
    //             })
    //         } else if (filter === 'cupcakes'){
    //             storeItems.forEach(function(item){
    //                 if (item.classList.contains('cupcakes')){
    //                     item.style.display = 'block'
    //                 } else {
    //                     item.style.display = 'none'
    //                 }
    //             })
    //         } else if (filter === 'sweets'){
    //             storeItems.forEach(function(item){
    //                 if (item.classList.contains('sweets')){
    //                     item.style.display = 'block'
    //                 } else {
    //                     item.style.display = 'none'
    //                 }
    //             })
    //         } else if (filter === 'doughnuts'){
    //             storeItems.forEach(function(item){
    //                 if (item.classList.contains('doughnuts')){
    //                     item.style.display = 'block'
    //                 } else {
    //                     item.style.display = 'none'
    //                 }
    //             })
    //         }
    //     })
    // })

    // all 버튼을 눌렀을 때 필터 해제
    const buttons = document.querySelectorAll('.btn')
    const storeItems = document.querySelectorAll('.store-item')

    buttons.forEach((button)=> {
        button.addEventListener('click', (e) => {
            e.preventDefault()
            const filter = e.target.dataset.filter
            
            storeItems.forEach((item)=> {
                if (filter === 'all'){
                    item.style.display = 'block'
                } else {
                    if (item.classList.contains(filter)){
                        item.style.display = 'block'
                    } else {
                        item.style.display = 'none'
                    }
                }
            })
        })
    })

})();

// 이미지에 필터 적용
(function(){

    const searchBox = document.querySelector('#search-item')
    const storeItems = document.querySelectorAll('.store-item')

    searchBox.addEventListener('keyup', (e) => {
    
        const searchFilter = e.target.value.toLowerCase().trim()
        // 필터에 해당하는 이미지만 표시

        storeItems.forEach((item) => {
            if (item.textContent.includes(searchFilter)){
                item.style.display = 'block'
            } else {
                item.style.display = 'none'
            }
        })
    })

})();
  • toLowerCase()
    대상 문자열을 모두 소문자로 변환합니다.
  • trim()
    대상 문자열의 앞 / 뒤 공백문자를 모두 제거하여 리턴해줍니다.
    예) [ 공백 제거 ] => [공백 제거] : 문자열 중간에 있는 공백 문자는 제거되지 않으므로 유의할 것.
  • .dataset
    HTMLElemnet.dataset 은 요소의 사용자 지정 데이터 특성(data-*)을 말한다.
  • .filter
    callbackFunction의 조건에 해당하는 모든 요소가 있는 배열을 새로 생성하는 기능.
    var newArray = arr.filter(callbackFunction(element, index, array), thisArg);

 

 

 

  css

@import url("https://fonts.googleapis.com/css?family=Kaushan+Script");

:root {
  --mainPink: #ef7998;
  --mainYellow: rgb(249, 228, 148);
  --mainWhite: #fff;
  --mainBlack: #000;
  --yellowTrans: rgba(249, 228, 148, 0.5);
  --mainGrey: rgb(238, 238, 238);
}

body {
  font-family: "Noto Sans KR";
  background: var(--mainWhite);
  color: var(--mainBlack);
}
/* nav links */
.navbar-toggler {
  outline: none !important;
}
.toggler-icon {
  font-size: 2.5rem;
  color: var(--mainPink);
}
.nav-link {
  color: var(--mainBlack);
  font-size: 1rem;
  transition: all 0.5s ease-in-out;
}
.nav-link:hover {
  color: var(--mainBlack);
}
.logo {
  width: 40px;
  height: 40px;
}
/* end of nav links */

/* banner */
/* 여기가 스크롤에 따라 이미지가 보여지는 부분 변하게 */
.max-height {
  min-height: calc(100vh - 76px);
  background: linear-gradient(var(--yellowTrans), var(--yellowTrans)),
    url("../img/headerBcg.png") center/cover fixed no-repeat;
  position: relative;
}
.banner {
  color: var(--mainWhite);
  margin-top: -4rem;
}
.banner-title {
  color: var(--mainPink);
  font-size: 4rem;
}
.banner-link {
  margin-top: ;
  font-size: 0.8rem;
  color: var(--mainBlack);
  border: 0.1rem solid var(--mainBlack);
}
.banner-link:hover {
  background: var(--mainBlack);
  color: var(--mainPink);
}
/* endo of banner */
/* cart  */
.cart {
  position: absolute;
  min-height: 10rem;
  background: var(--mainWhite);
  top: 0;
  right: 0;
  transition: all 0.3s ease-in-out;
  background: rgba(255, 255, 255, 0.5);
  width: 0;
  overflow: hidden;
}
.show-cart {
  width: 18rem;
  padding: 2rem 1.5rem;
  transform: rotateY(-360deg);
}
.cart-item {
  transition: all 2s ease-in-out;
}

/* end of cart */
/* cart item */
.cart-item-remove {
  color: var(--mainPink);
  transition: all 1s ease-in-out;
}
.cart-item-remove:hover {
  transform: scale(1.1);
  color: var(--mainBlack);
}
#cart-item-price {
  font-size: 0.8rem;
}
/* cart item */
/* cart buttons */
.btn-pink {
  color: var(--mainPink) !important;
  border-color: var(--mainPink) !important;
}
.btn-black {
  color: var(--mainBlack) !important;
  border-color: var(--mainBlack) !important;
}
.btn-black:hover {
  color: var(--mainPink) !important;
  background: var(--mainBlack) !important;
}
.btn-pink:hover {
  background: var(--mainPink) !important;
  color: var(--mainBlack) !important;
}
/* end of cart buttons */

/* about */
.about-img__container {
  position: relative;
}

/* 여기가 노란색 테두리 박스가 옮겨지는 부분 */
.about-img__container::before {
  content: "";
  position: absolute;
  top: -1.5rem;
  left: -1.7rem;
  width: 100%;
  height: 100%;
  outline: 0.5rem solid var(--mainYellow);
  z-index: -1;
  transition: all 1s ease-in-out;
}
.about-img__container:hover:before {
  top: 0;
  left: 0;
}

/*end of  about */

/* store items */
.store {
  background: var(--mainGrey);
}
.img-container {
  position: relative;
  overflow: hidden;
  cursor: pointer;
}
.store-img {
  transition: all 1s ease-in-out;
}
.img-container:hover .store-img {
  transform: scale(1.2);
}
.store-item-icon {
  position: absolute;
  bottom: 0;
  right: 0;
  padding: 0.75rem;
  background: var(--mainYellow);
  border-top-left-radius: 1rem;
  transition: all 1s ease-in-out;
  transform: translate(100%, 100%);
}
.img-container:hover .store-item-icon {
  transform: translate(0, 0);
}
.store-item-icon:hover {
  color: var(--mainWhite);
}
.store-item-value {
  color: --mainYellow;
}
/*end of  store items */
.search-box {
  background: var(--mainPink);
  color: var(--mainBlack);
}

 

 

 

 

 

위 코드는 아래 링크에 있는 자바스크립트 프로젝트를 활용 및 참고하여 작업하였습니다.

https://jsbeginners.com/javascript-projects-for-beginners/#below-list

 

100+ JavaScript Projects for Beginners! [ Solutions Provided! ]

Looking for JavaScript projects to get more JavaScript practice? Here's a list of over 100 javascript projects for beginners!

jsbeginners.com

 

728x90