웹 페이지에서 슬라이드와 탭 구현하기
슬라이드 구현
<!-- 슬라이드 -->
<div class="backgroundSlide">
<div class="slides">
<div class="backgroundImg">
<img src="./img/cozastore-master/images/slide-01.jpg" alt="">
</div>
<div class="backgroundImg">
<img src="./img/cozastore-master/images/slide-02.jpg" alt="">
</div>
<div class="backgroundImg">
<img src="./img/cozastore-master/images/slide-03.jpg" alt="">
</div>
</div>
</div>
<div class="slide_btn">
<button id="prev"><i class="fa-solid fa-caret-left"></i></button>
<button id="next"><i class="fa-solid fa-caret-right"></i></button>
</div>
슬라이드 html
.backgroundSlide {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
}
.slides {
display: flex;
width: 100%;
}
#prev, #next {
position: absolute;
top: 50%;
font-size: 50px;
background-color: inherit;
border-style: none;
cursor: pointer;
color: rgb(163, 163, 160);
}
#prev {
left: 5%;
}
#next {
right: 5%;
}
.backgroundImg {
width: 100%;
display: flex;
flex: 0 0 33%;
height: 999px;
margin: 0;
}
.backgroundImg img{
display: block;
}
슬라이드 css
const slides = document.querySelector('.slides');
const slide = document.querySelectorAll('.backgroundImg');
const prev = document.querySelector('#prev');
const next = document.querySelector('#next');
let index = 0;
slides.style.transition = 'transform 0.3s ease-in-out';
function moveslide() {
slides.style.transform = `translateX(-${index*100}%)`;
updateText();
}
prev.addEventListener('click', function(){
if(index <= 0) {
index = slide.length-1;
} else {
index -=1;
}
moveslide();
})
next.addEventListener('click', function(){
if(index === slide.length-1) {
index = 0;
} else {
index += 1;
}
moveslide();
})
function updateText() {
let upper = document.querySelector('.banner_text span');
let center = document.querySelector('.banner_text h2');
if(index == 0) {
upper.innerHTML = `Women Collection 2018`;
center.innerHTML = `NEW SEASON`;
} else if (index == 1) {
upper.innerHTML = `Men New-Season`;
center.innerHTML = `JACKETS & COATS`;
} else {
upper.innerHTML = `Men Collection 2018`;
center.innerHTML = `NEW ARRIVALS`;
}
}
슬라이드 js
확실히 슬라이드를 js로 구현하니까 html과 css 코드가 굉장히 간결해졌다.
슬라이드의 핵심은 prev와 next 버튼을 구현해서 인덱스 값을 더하고 빼고 하는게 다 인데,
여기다가 슬라이드 길이보다 인덱스가 커지거나 작아질때만 잘 붙이면 된다.
추가로 슬라이드마다 배너텍스트가 다르길래 일일히 html과 css로 넣을수도 있지만
js를 활용해보려고 인덱스 값을 반영해서 동적으로 배너텍스트를 바꾸는 기능도 넣어보았다.
이때 슬라이드는 버튼을 눌러서 인덱스 값이 바뀔때 업데이트 되어 슬라이드가 바뀌게 되는데,
텍스트의 경우에는 따로 moveslide를 동작시킬수가 없기 때문에 updateText 함수를 만들어서
버튼 클릭 이벤트에 각각 넣어서 구현했다.
탭기능
<!-- 프로덕트 파트 -->
<div class="product_area">
<div class="product_content">
<div class="product_title">
<h3>PRODUCT OVERVIEW</h3>
</div>
<div class="tab_line">
<div class="product_tabs">
<button id="all" class="tab">All Products</button>
<button id="women" class="tab">Women</button>
<button id="men" class="tab">Men</button>
<button id="bag" class="tab">Bag</button>
<button id="shoes" class="tab">Shoes</button>
<button id="watches" class="tab">Watches</button>
</div>
<div class="filter_search">
<a href="#" class="filter"><i class="fa-solid fa-filter"></i> Filter</a>
<a href="#" class="search"><i class="fa-solid fa-magnifying-glass"></i> Search</a>
</div>
</div>
<!-- 프로덕트 박스 컨테이너 -->
<div class="product_con">
<div class="product_box all women">
<div class="product_img" id="more">
<img src="./img/cozastore-master/images/product-01.jpg" alt="product-01">
<div id="moreOption">
<a id="option" href="#">
Quick View
</a>
</div>
</div>
<div class="product_text">
<a href="#">Esprit Ruffle Shirt</a>
<span>$16.64</span>
</div>
<div class="product_heart">
<img src="./img/cozastore-master/images/icons/icon-heart-01.png" alt="">
<img src="./img/cozastore-master/images/icons/icon-heart-02.png" alt="">
</div>
</div>
탭기능 html
.product_box {
width: 345px;
padding: 0 15px 35px;
display: flex;
justify-content: center;
flex-direction: column;
}
.product_box img {
width: 315px;
height: auto;
}
.product_text {
width: 315px;
height: auto;
padding: 14px 0 0;
}
.product_text a {
color: #999999;
font-size: 14px;
padding: 0 0 6px;
display: block;
}
.product_text span {
color: #666666;
font-size: 14px;
}
.product_heart {
display: none;
}
.product_con {
width: 100%;
display: flex;
flex-wrap: wrap;
}
#option {
width: 139px;
height: 40px;
color: #222222;
display: flex;
padding: 0 15px;
background-color: #ffffff;
border-radius: 20px;
justify-content: center;
margin: 0 auto;
line-height: 40px;
position: absolute;
bottom: -100%;
left: 50%;
transform: translateX(-50%);
transition: 0.5s ease-in-out;
}
.product_box {
overflow: hidden;
}
.product_img img:hover {
scale: 1.1;
transition: 0.5s ease-in-out;
cursor: pointer;
}
#more:hover #option{
bottom: 20%;
transition: 0.5s ease-in-out;
}
#option:hover {
background-color: #222222;
color: #ffffff;
}
.product_img {
position: relative;
overflow: hidden;
}
탭기능 css
const tabs = document.querySelectorAll('.tab');
const contents = document.querySelectorAll('.product_box');
activateTab(tabs[0]);
showTabContent('all');
for(let i = 0; i < tabs.length; i++) {
tabs[i].addEventListener('click', tabIdCalculator);
}
function tabIdCalculator() {
let tabId = this.getAttribute('id');
activateTab(this);
showTabContent(tabId);
}
function activateTab(tab) {
for(let i = 0; i < tabs.length; i++) {
tabs[i].style.textDecoration='none';
tabs[i].style.color='#888888'
}
tab.style.color='#222222'
tab.style.textDecoration='underline'
}
function showTabContent(tabId) {
if(tabId == 'all') {
contents.forEach((content) => {
content.style.display='block'
});
}else {
contents.forEach((content) => {
content.style.display = content.classList.contains(tabId) ? 'block' : 'none'})
}
}
탭기능 js
탭 기능은 js를 적용하더라도 분량이 꽤 된다.
탭의 핵심은 탭은 '탭 메뉴'와 '탭 컨텐츠'로 이루어져 있고, 탭 메뉴를 누르면 해당하는 탭 컨텐츠가 보이게 되는 것이다.
그렇게 하기 위해 먼저 탭 메뉴와 탭 컨텐츠 요소들을 따로 변수로 선언해두고,
tabs를 노드리스트 기능을 활용해서 순회를 한다.(for 대신 forEach 사용가능)
tabs를 순회해서 활성화된 탭의 id를 또 따로 저장해둔다.
그렇게해서 함수를 통해 활성화된 탭의 id와 tabs를 순회하여 얻은 값을 각각의 tab과 비교하여
활성화 된 tab을 찾아내고, 설정해둔 값을 적용한다.
그런다음에 또 다른 함수에 id 값을 저장해둔것을 all인지 아닌지 대조한다.
all이면 모든 탭컨텐츠를 블록(보이게)상태로 하고, all이 아니라면
활성화 된 탭 메뉴 id에 해당하는 탭 컨텐츠만 블록상태로 만든다.
웹 페이지에 실제로 탭과 슬라이드를 js로 적용해보니까 알게된것은
생각보다 로딩으로 인한 에러가 잦다는것이다.
html에서 js를 연결할때 <script src="script.js">만 하니까 생기던 에러가 뒤에 defer을 적어주니 해결됐던 경우가 꽤 많은거같다.