티스토리 뷰

JavaScript

slideshow / sideshow

정낭고 2023. 6. 14. 23:34

Slideshow

🙾  slidesCount = slides.length

- 각 슬라이드 갯수 변수 지정

🙾  슬라이드를 이동 할 때는 함수가 필요

🙾  JS 내용 생성

- 대상.innerText = '내용'

- 대상.innerHTML = '내용'

🙾  크로스브라우징 (modernizr.com)

 

 


▏상단메뉴 고정

- 대상.offsetLeft

- 대상.offsetTop (상단에서의 거리)

- 스크롤양 확인 : window.document.documentElment.scrollTop;

window.pageYOffset;

// deplicated

window.scrollY;

 

▏scroll menu

- 스크롤양 확인 : 대상.scrollTo(0,0)

대상.scrollTo({
	left:0,
    top:0,
    behavior:'smooth'
    })

 

▏shrinking nav bar

🙾  스크롤 효과시 한 번만 반복하는 방법 : 클래스명

- 대상.classList.add('클래스명')

- 대상.classList.remove('클래스명')

- 대상.classList.contains('클래스명') : 조건문

let mainHeader = document.querySelector('#main-header');
let logo = document.querySelector('#logo');
let bigLogo = 'images/logo-shrink.svg';
let smLogo = 'images/logo.svg';

/*
윈도우에 스크롤이 생기면 할 일
스크롤양이 0보다 크다면 mainHeader에 클래스명 shrink를 추가하고 아니라면 shrink를 제거한다.
*/
window.addEventListener('scroll',()=>{
    if(window.scrollY > 0){
        if(!mainHeader.classList.contains('shrink')){
            mainHeader.classList.add('shrink');
            switchImg(bigLogo);
        }
    }else{
        if(mainHeader.classList.contains('shrink')){
        mainHeader.classList.remove('shrink');
        switchImg(smLogo);    
        }
    }
});

function switchImg(newImgPath){
    logo.classList.add('hide');
    setTimeout(()=>{
        logo.setAttribute('src',newImgPath);
        logo.classList.remove('hide');
    },300);
}

 

🙾  스크롤 효과시 한 번만 반복하는 방법 : 별도의 변수명

let mainHeader = document.querySelector('#main-header');
let logo = document.querySelector('#logo');
let bigLogo = 'images/logo-shrink.svg';
let smLogo = 'images/logo.svg';
let excuted = false;

/*
윈도우에 스크롤이 생기면 할 일
스크롤양이 0보다 크다면 mainHeader에 클래스명 shrink를 추가하고 아니라면 shrink를 제거한다.
*/
window.addEventListener('scroll',()=>{
    if(window.scrollY > 0){
            if(excuted == false){
            mainHeader.classList.add('shrink');
            switchImg(bigLogo);
            excuted = true;
        }
    }else{
        if(excuted == true){
        mainHeader.classList.remove('shrink');
        switchImg(smLogo);   
        excuted = false; 
        }
    }
});

function switchImg(newImgPath){
    logo.classList.add('hide');
    setTimeout(()=>{
        logo.setAttribute('src',newImgPath);
        logo.classList.remove('hide');
    },300);
}

 

▏slide show

ex) 1번째 구현

// 변수 지정
let slideWrapper = document.querySelector('.slide-wrapper'), // ul의 부모
slideContainer = document.querySelector('.slide-container'), // ul
slides = document.querySelectorAll('li'), // 각 슬라이드
slideCount = slides.length, //슬라이드 갯수
currentSlideIdx = 0,
pager = slideWrapper.querySelector('.pager'),
timer,
pagerHTML = '', // 공백은 순환
prevBtn = slideWrapper.querySelector('#prev'),
nextBtn = slideWrapper.querySelector('#next');


// <슬라이드가 있으면 가로로 배열하기, 페이저 생성하기>
// slides[0].style.left= '0%'
// for문
/*
if(slideCount > 1){
    for(let i =0; i < slideCount; i++){
        slides[i].style.left= `${i*100}%`;
        // i.style.left = i*100+'%';
    }
}
*/
// forEach문
if(slideCount > 1){
    slides.forEach((item,index)=>{
        item.style.left=`${index*100}%`;
        // pager a 태그 생성
        pagerHTML += `<a href="">${index}</a>`;
    });
}

pager.innerHTML = pagerHTML;
pagerBtn = pager.querySelectorAll('a');


// <슬라이드 이동 함수(이동, 페이저 업데이트, 슬라이드 활성화)>
// moverSlide(2)
// num 1, slideContainer.style.left = '-100%'
// num 2, slideContainer.style.left = '-200%'
function moveSlide(num){
    slideContainer.style.left = `${-num*100}%`;
    // -num * 100 + '%';
    currentSlideIdx = num;


// <마지막이면 다음버튼에 disable 클래스명 추가 아니라면 클래스명 제거>
if(currentSlideIdx === slideCount -1){
    nextBtn.classList.add('disabled');
} else{
    nextBtn.classList.remove('disabled');
}


// <처음이면 이전 버튼이 사라지고, 처음이 아니라면 다시 보이도록>
if(currentSlideIdx === 0){
    prevBtn.classList.add('disabled');
} else{
    prevBtn.classList.remove('disabled');
}


// 모든 슬라이스에서 active를 제거하고, 지금 보고 있는 슬라이드에 active를 추가
for(sl of slides){
    sl.classList.remove('active');
}
    slides[currentSlideIdx].classList.add('active');
    //모든 페이저에서 active를 제거하고, 현재 슬라이드 번호의 pager에 active를 추가
    for(pg of pagerBtn){
        pg.classList.remove('active');
    } 
        pagerBtn[currentSlideIdx].classList.add('active');
}

moveSlide(0);


// <좌우 버튼 클릭으로 슬라이드 이동시키기>
// nextBtn 버튼을 클릭하면 할 일, 현재 슬라이드 번호에 +1한 숫자를 moveSlide에 넘긴다
nextBtn.addEventListener('click',()=>{
    // 마지막이 아니라면
    if(currentSlideIdx < slideCount -1){    
        moveSlide(currentSlideIdx +1);
    }
})


// <이전 버튼을 클릭하면 할 일, 처음이 아니라면>
prevBtn.addEventListener('click',()=>{
    if(currentSlideIdx > 0){    
        moveSlide(currentSlideIdx -1);
    }
});


// <페이저로 슬라이드 이동하기>
/* pagerBtn를 클릭하면 할 일
링크의 기본 속성 막기
moveSlide에 클릭한 그 요소의 인덱스 번호를 넘긴다.
*/
pagerBtn.forEach((item, idx)=>{
    item.addEventListener('click',(e)=>{
        e.preventDefault();
        moveSlide(idx);
    });
});


// <자동 슬라이드>
// let timer은 지역 변수이기 때문에 함수 안에서만 활동하기 때문에 변수 timer은 따로 잡아줘야지만 밑에도 작동 가능
function autoSlide(){
    timer = setInterval(()=>{
        // let nextIdx = currentSlideIdx + 1;
        let nextIdx = (currentSlideIdx + 1) % slideCount;
        moveSlide(nextIdx);
    },3000);
}
autoSlide();


// sliderWrapper mouseenter 이벤트가 일어나면 자동 슬라이드 멈추기
slideWrapper.addEventListener('mouseenter',()=>{
    clearInterval(timer);
});
slideWrapper.addEventListener('mouseleave',()=>{
    clearInterval(timer);
});

ex) 2번째 구현

// 변수 지정
let slideWrapper = document.querySelector('.slide-wrapper'), // ul의 부모
slideContainer = document.querySelector('.slide-container'), // ul
slides = document.querySelectorAll('li'), // 각 슬라이드
slideCount = slides.length, //슬라이드 갯수
currentSlideIdx = 0,
pager = slideWrapper.querySelector('.pager'),
timer,
pagerHTML = '', // 공백은 순환
slideWidth = document.body.offsetWidth;
prevBtn = slideWrapper.querySelector('#prev'),
nextBtn = slideWrapper.querySelector('#next');

window.addEventListener('resize',()=>{
    slideWidth = document.body.offsetWidth;
    console.log(slideWidth);
    setSlide();
    clearInterval(timer);
});


// <슬라이드가 있으면 가로로 배열하기, 페이저 생성하기>
// slides[0].style.left= '0%'
// for문
/*
if(slideCount > 1){
    for(let i =0; i < slideCount; i++){
        slides[i].style.left= `${i*100}%`;
        // i.style.left = i*100+'%';
    }
}
*/
function setSlide(){
// forEach문
if(slideCount > 1){
    let containerWidth = slideWidth * slideCount
    slideContainer.style.width = `${containerWidth}px`;

    slides.forEach((item,index)=>{
        item.style.width = `${slideWidth}px`;
        // pager a 태그 생성
        pagerHTML += `<a href="">${index}</a>`;
    });
}
    /*
    현재 슬라이드의 너비(body의 너비)를 변수명 slideWidth에 저장
    // slideContainer의 너비를 slideWidth * slideCount
    */
}
setSlide();

pager.innerHTML = pagerHTML;
pagerBtn = pager.querySelectorAll('a');


// <슬라이드 이동 함수(이동, 페이저 업데이트, 슬라이드 활성화)>
// moverSlide(2)
// num 1, slideContainer.style.left = '-100%'
// num 2, slideContainer.style.left = '-200%'
function moveSlide(num){
    slideContainer.style.transform = `translateX(${-num*slideWidth}px)`;
    // -num * 100 + '%';
    currentSlideIdx = num;
    
updateNav();
}

// moveSlide(0);
updateNav();

function updateNav(){
    // <마지막이면 다음버튼에 disable 클래스명 추가 아니라면 클래스명 제거>
if(currentSlideIdx === slideCount -1){
    nextBtn.classList.add('disabled');
} else{
    nextBtn.classList.remove('disabled');
}
// <처음이면 이전 버튼이 사라지고, 처음이 아니라면 다시 보이도록>
if(currentSlideIdx === 0){
    prevBtn.classList.add('disabled');
} else{
    prevBtn.classList.remove('disabled');
}
// 모든 슬라이스에서 active를 제거하고, 지금 보고 있는 슬라이드에 active를 추가
for(sl of slides){
    sl.classList.remove('active');
}
    slides[currentSlideIdx].classList.add('active');
    //모든 페이저에서 active를 제거하고, 현재 슬라이드 번호의 pager에 active를 추가
    for(pg of pagerBtn){
        pg.classList.remove('active');
    } 
        pagerBtn[currentSlideIdx].classList.add('active');
}


// <좌우 버튼 클릭으로 슬라이드 이동시키기>
// nextBtn 버튼을 클릭하면 할 일, 현재 슬라이드 번호에 +1한 숫자를 moveSlide에 넘긴다
nextBtn.addEventListener('click',()=>{
    // 마지막이 아니라면
    if(currentSlideIdx < slideCount -1){    
        moveSlide(currentSlideIdx +1);
    }
})


// <이전 버튼을 클릭하면 할 일, 처음이 아니라면>
prevBtn.addEventListener('click',()=>{
    if(currentSlideIdx > 0){    
        moveSlide(currentSlideIdx -1);
    }
});


// <페이저로 슬라이드 이동하기>
/* pagerBtn를 클릭하면 할 일
링크의 기본 속성 막기
moveSlide에 클릭한 그 요소의 인덱스 번호를 넘긴다.
*/
pagerBtn.forEach((item, idx)=>{
    item.addEventListener('click',(e)=>{
        e.preventDefault();
        moveSlide(idx);
    });
});


// <자동 슬라이드>
// let timer은 지역 변수이기 때문에 함수 안에서만 활동하기 때문에 변수 timer은 따로 잡아줘야지만 밑에도 작동 가능
function autoSlide(){
    timer = setInterval(()=>{
        // let nextIdx = currentSlideIdx + 1;
        let nextIdx = (currentSlideIdx + 1) % slideCount;
        moveSlide(nextIdx);
    },3000);
}
//autoSlide();


// sliderWrapper mouseenter 이벤트가 일어나면 자동 슬라이드 멈추기
slideWrapper.addEventListener('mouseenter',()=>{
    clearInterval(timer);
});
slideWrapper.addEventListener('mouseleave',()=>{
    clearInterval(timer);
});

ex) 3번째 구현

// 변수 지정
let slideWrapper = document.querySelector('.slide-wrapper'), // ul의 부모
slideContainer = document.querySelector('.slide-container'), // ul
slides = document.querySelectorAll('li'), // 각 슬라이드
slideCount = slides.length, //슬라이드 갯수
currentSlideIdx = 0,
pager = slideWrapper.querySelector('.pager'),
timer,
pagerHTML = '', // 공백은 순환
prevBtn = slideWrapper.querySelector('#prev'),
nextBtn = slideWrapper.querySelector('#next');


// <슬라이드가 있으면 가로로 배열하기, 페이저 생성하기>
// slides[0].style.left= '0%'
// for문
/*
if(slideCount > 1){
    for(let i =0; i < slideCount; i++){
        slides[i].style.left= `${i*100}%`;
        // i.style.left = i*100+'%';
    }
}
*/
// forEach문
if(slideCount > 1){
    slides.forEach((item,index)=>{
        item.style.top=`${index*100}%`;
        // pager a 태그 생성
        pagerHTML += `<a href="">${index}</a>`;
    });
}

pager.innerHTML = pagerHTML;
pagerBtn = pager.querySelectorAll('a');


// <슬라이드 이동 함수(이동, 페이저 업데이트, 슬라이드 활성화)>
// moverSlide(2)
// num 1, slideContainer.style.left = '-100%'
// num 2, slideContainer.style.left = '-200%'
function moveSlide(num){
    slideContainer.style.top = `${-num*100}%`;
    // -num * 100 + '%';
    currentSlideIdx = num;


// <마지막이면 다음버튼에 disable 클래스명 추가 아니라면 클래스명 제거>
if(currentSlideIdx === slideCount -1){
    nextBtn.classList.add('disabled');
} else{
    nextBtn.classList.remove('disabled');
}


// <처음이면 이전 버튼이 사라지고, 처음이 아니라면 다시 보이도록>
if(currentSlideIdx === 0){
    prevBtn.classList.add('disabled');
} else{
    prevBtn.classList.remove('disabled');
}


// 모든 슬라이스에서 active를 제거하고, 지금 보고 있는 슬라이드에 active를 추가
for(sl of slides){
    sl.classList.remove('active');
}
    slides[currentSlideIdx].classList.add('active');
    //모든 페이저에서 active를 제거하고, 현재 슬라이드 번호의 pager에 active를 추가
    for(pg of pagerBtn){
        pg.classList.remove('active');
    } 
        pagerBtn[currentSlideIdx].classList.add('active');
}

moveSlide(0);


// <좌우 버튼 클릭으로 슬라이드 이동시키기>
// nextBtn 버튼을 클릭하면 할 일, 현재 슬라이드 번호에 +1한 숫자를 moveSlide에 넘긴다
nextBtn.addEventListener('click',()=>{
    // 마지막이 아니라면
    if(currentSlideIdx < slideCount -1){    
        moveSlide(currentSlideIdx +1);
    }
})


// <이전 버튼을 클릭하면 할 일, 처음이 아니라면>
prevBtn.addEventListener('click',()=>{
    if(currentSlideIdx > 0){    
        moveSlide(currentSlideIdx -1);
    }
});


// <페이저로 슬라이드 이동하기>
/* pagerBtn를 클릭하면 할 일
링크의 기본 속성 막기
moveSlide에 클릭한 그 요소의 인덱스 번호를 넘긴다.
*/
pagerBtn.forEach((item, idx)=>{
    item.addEventListener('click',(e)=>{
        e.preventDefault();
        moveSlide(idx);
    });
});



// <자동 슬라이드>
// let timer은 지역 변수이기 때문에 함수 안에서만 활동하기 때문에 변수 timer은 따로 잡아줘야지만 밑에도 작동 가능
function autoSlide(){
    timer = setInterval(()=>{
        // let nextIdx = currentSlideIdx + 1;
        let nextIdx = (currentSlideIdx + 1) % slideCount;
        moveSlide(nextIdx);
    },3000);
}
autoSlide();

// sliderWrapper mouseenter 이벤트가 일어나면 자동 슬라이드 멈추기
slideWrapper.addEventListener('mouseenter',()=>{
    clearInterval(timer);
});
slideWrapper.addEventListener('mouseleave',()=>{
    clearInterval(timer);
});

 

 

 

 

 

 

'JavaScript' 카테고리의 다른 글

accordion / modal / back to top  (0) 2023.06.14
event & tab  (0) 2023.06.08
Selector (선택자)  (0) 2023.06.07
Timer & Math  (0) 2023.06.05
문자열 (IndexOf, Search / concat / replace / slice / split / length)  (0) 2023.06.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/12   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함