필요없는 목록/CSS 스타일

슬라이드 API 없이 코드로 하기 5 / 10 (연속적으로 "위"로 이동)

비밀안 2023. 4. 12. 18:26
클릭

버튼을 클릭하면 명언이 나와요

-

이름이 나와요

최종 완성된 모습

이번거는 슬라이드 4번을 이용해서 위로 올라가는 것을 만들어 보라는 미션입니다.

(JAVASCRIPT, GSAP, JQUERY)

HTML+CSS코드

 <style>
/* slider__wrap */
.slider__wrap {
    width: 100%;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* 이미지가 보이는 영역 */
.slider__img {
    position: relative;
    width: 800px;
    height: 520px;
    overflow: hidden;
}
/* 전체 이미지를 감싸고 있는 부모 : 움직이는 영역 */
.slider__inner {
    display: flex;
    flex-wrap: wrap;
    /* width: 4800px; */
    height: 2600px;
}
/* 개별적인 이미지 */
.slider {
    position: relative;
    width: 800px;
    height: 520px;
}
#header li a {
	line-height: 35px;      
}
</style>
</head>

<body class="img07 bg07 font07">
<header id="header">
    <h1>Javascript Slider Effect05</h1>
    <p>슬라이드 이팩트 : 좌로 움직이기(연속적으로)</p>
    <ul>
        <li><a href="sliderEffect01.html">1</a></li>
        <li><a href="sliderEffect02.html">2</a></li>
        <li><a href="sliderEffect03.html">3</a></li>
        <li><a href="sliderEffect04.html">4</a></li>
        <li class="active"><a href="sliderEffect05.html">5</a></li>
        <li><a href="sliderEffect06.html">6</a></li>
    </ul>
</header>
 <!-- //header -->
 <main id="main">
    <div class="slider__wrap">
        <div class="slider__img">
            <div class="slider__inner">
                <div class="slider s1"><img src="./img/slider_bg07b.jpg" alt="이미지1"></div>
                <div class="slider s2"><img src="./img/slider_bg08b.jpg" alt="이미지2"></div>
                <div class="slider s3"><img src="./img/slider_bg03b.jpg" alt="이미지3"></div>
                <div class="slider s4"><img src="./img/slider_bg04b.jpg" alt="이미지4"></div>
                <div class="slider s5"><img src="./img/slider_bg06b.jpg" alt="이미지5"></div>
            </div>
        </div>
    </div>
</main> 
<!-- //main -->
<footer id="footer">
    <a href="mailto:skadldldl123@gmail.com">mailto:skadldldl123@gmail.com</a>
</footer>
<!-- //footer -->
</body>

코드 설명

(역시나 슬라이드 2번을 재탕 중이네요)

1.div태그인 slider__wrap은 전체 내용물을 이동 시켜줍니다.

(이번것도 align-items는 먹히지 않아서 height값을 부여해서 가운데로 이동하였습니다.)

2.div태그인 slider__img는 이제 보여줄 width만큼만 주고 overflow로 잘라줍니다.

(주렁 주렁 달고온 것들을 눈에 안보여주게 하고. 그것들을 translateX로 width값만큼 이동을 시켜주면 됩니다.)

3.div태그인 slider__inner는 .slider의 모든 width값을 합한만큼 줍니다.

(display:flex를 주면 좌->우로 주렁 주렁 달고 옵니다. + flex-wrap 필수)

4.div태그인 slider는 각각 width를 줍니다.

 

JAVASCRIPT+GSAP+JQUERY코드

<script>
// 선택자 
const sliderWrap = document.querySelector(".slider__wrap");
const sliderImg = sliderWrap.querySelector(".slider__img");      //보여지는 영역
const sliderInner = sliderWrap.querySelector(".slider__inner"); //움직이는 영역
const slider = sliderWrap.querySelectorAll(".slider");          //개별 영역

let currentIndex = 0;                               //현재 보이는 이미지
let sliderCount = slider.length;                    //이미지 갯수
let sliderInterval = 3000;                          //이미지 간격 시간
let sliderHeight = slider[0].offsetHeight;            //이미지 가로값
// let sliderClone = sliderInner.firstChild;
let sliderClone = sliderInner.firstElementChild.cloneNode(true);    //첫번쨰 이미지 복사해서 마지막에 놓음

// 복사한 첫번째 이미지 마지막에 붙여넣기
sliderInner.appendChild(sliderClone);

// 4번 --> 제이쿼리 --> GSAP
// 5번 --> 위로 가기(연속적으로) -->> 제이쿼리 --> GSAP
// function sliderEffect(){
//     currentIndex++;

//     sliderInner.style.transition = "all 0.6s";
//     sliderInner.style.transform ="translateY(-"+ (sliderHeight * currentIndex) +"px)";

//     // 마지막 이미지에 위치 했을 때
//     if(currentIndex === sliderCount){
//         // alert("asd");
//         // 1번만 실행
//         setTimeout(() => {
//             sliderInner.style.transition = "0s";
//             sliderInner.style.transform ="translateY(0px)";
//         }, 700);
//         currentIndex = 0;
//     }

//     console.log(sliderHeight * currentIndex)
// }
// // 해당 시간동안 sliderEffect 함수를 실행 시키는 코드
// setInterval(sliderEffect, sliderInterval);
</script>

<!-- GSAP CDN  -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script>
// setInterval(() => {
//     currentIndex++;

//     gsap.to(sliderInner, {
//         y:-(sliderHeight * currentIndex),
//         duration: 1
//     });

//     if(currentIndex === sliderCount){
//         setTimeout(() => {
//             gsap.to(sliderInner, {
//                 y:0,
//                 duration: 0
//             });
//         }, 70);
//         currentIndex = 0;
//     }

//     console.log(sliderHeight * currentIndex);
// }, 1000);
</script>

<!-- jQuery -->
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<script>
setInterval(() => {
    currentIndex++;

    $(".slider__inner").css("position", "relative");
    $(".slider__inner").animate( {top:-(sliderHeight * currentIndex)}, 1000);

    if(currentIndex === sliderCount){
        // alert("asd");
        // 1번만 실행
        setTimeout(() => {
            $(".slider__inner").animate( {top:-(sliderHeight * currentIndex)}, 0);
            // $(".slider__inner").style.transform ="translateX(0px)";
        }, 700);
        currentIndex = 0;
    }
}, 1000);
</script>

코드설명

1.

// 선택자 
const sliderWrap = document.querySelector(".slider__wrap");
const sliderImg = sliderWrap.querySelector(".slider__img");      //보여지는 영역
const sliderInner = sliderWrap.querySelector(".slider__inner"); //움직이는 영역
const slider = sliderWrap.querySelectorAll(".slider");          //개별 영역
const sliderDot = sliderWrap.querySelector(".slider__dot");     //닷 메뉴
const sliderBtn = sliderWrap.querySelectorAll(".slider__btn a");//버튼

querySelector()로 아이디, 클래스, 태그를 찾습니다.

 

2.

let currentIndex = 0;                               //현재 보이는 이미지
let sliderCount = slider.length;                    //이미지 갯수
let sliderInterval = 3000;                          //이미지 간격 시간
let sliderHeight = slider[0].offsetHeight;            //이미지 가로값
// let sliderClone = sliderInner.firstChild;
let sliderClone = sliderInner.firstElementChild.cloneNode(true);    //첫번쨰 이미지 복사해서 마지막에 놓음

// 복사한 첫번째 이미지 마지막에 붙여넣기
sliderInner.appendChild(sliderClone);

1.currentIndex는 0을 저장합니다.(나중에 setInterval을 통해서 1씩 증가 시킬 예정입니다.)

2.sliderCount는 div태그 .slider에 저장된 이미지의 개수입니다.(현재 5장)

3.sliderInterval은 setInterval을 돌릴때 지정할 시간입니다.

4.sliderWidth는 div태그 .slider의 0번지의 width값을 가져와서 데이터를 저장합니다.

(모든 .slider의 width값은 똑같이 800px입니다.)

5.sliderClone은 div태그 .slider__inner에는 div태그 .slider 이미지가 저장되어있습니다. 

(그중 0번지의 slider만 가져옵니다.)

(이유는 슬라이드가 마지막으로 넘어오고 다시 0번지로 오면 그때 첫번째 이미지를 보여주기 위해서 입니다.)

6.sliderInner.appendChild는 div태그인 .slider__inner의 마지막에 5번을 통해 가져온 slider의 0번지를 저장합니다.

cloneNode() 메서드는 DOM 요소를 복제하여 새로운 요소를 생성하는 메서드입니다. 이 메서드는 다음과 같은 두 가지 인수를 받습니다.

cloneNode 메서드를 사용하면 기존 DOM 요소를 쉽게 복제하여 새로운 요소를 생성할 수 있습니다.
  1. deep : 복제할 요소의 하위 요소를 함께 복제할지 여부를 지정하는 Boolean 값입니다. true로 지정하면 하위 요소까지 모두 복제합니다. false로 지정하면 복제할 요소만 복제합니다. 이 인수는 생략 가능합니다. 기본값은 false입니다.
  1. element : 복제한 요소를 삽입할 위치를 지정하는 DOM 요소입니다. 이 인수는 생략 가능합니다.
appendChild() 메서드는 DOM 요소의 자식 노드 리스트의 마지막에 새로운 자식 노드를 추가하는 메서드입니다. 이 메서드는 다음과 같은 하나의 인수를 받습니다.
  1. newChild : 추가할 자식 노드입니다. 이는 반드시 Node 객체여야 합니다.
appendChild 메서드를 사용하여 이 div 요소의 자식 노드로 span 요소를 추가합니다.

 

3.JAVASCRIPT 활용

function sliderEffect(){
 currentIndex++;

 sliderInner.style.transition = "all 0.6s";
 sliderInner.style.transform ="translateY(-"+ (sliderHeight * currentIndex) +"px)";

 // 마지막 이미지에 위치 했을 때
 if(currentIndex === sliderCount){
     // alert("asd");
     // 1번만 실행
     setTimeout(() => {
         sliderInner.style.transition = "0s";
         sliderInner.style.transform ="translateY(0px)";
     }, 700);
     currentIndex = 0;
 }

 console.log(sliderHeight * currentIndex)
}
// 해당 시간동안 sliderEffect 함수를 실행 시키는 코드
setInterval(sliderEffect, sliderInterval);

1.currentIndex에는 0이 저장되어있습니다. 함수가 실행 될때마다 값 1을 증가시킵니다.

2.div태그 .slider__inner에는 모든 div태그 .slider의 height값을 갖고있습니다.(2600px)

(div태그 .slider__img에서 원하는 height값을 주고 overflow로 가려서 안보입니다.)

2-2.div태그 .slider__inner의 height값을 520px만큼 이동시켜줘서 이동하는 것처럼 효과를 보여줍니다.

3.if문으로 currentIndex의 1씩 증가된 값이 // sliderCount(이미지의 총갯수)와 같으면 실행이 됩니다

(div태그 .slider__inner의 style을 0으로 맞춥니다.)

4.그리고 currentIndex의 값을 0으로 만듭니다.

(이렇게 해주면 슬라이드의 마지막에 도착했을때. 자연스럽게 0번지의 이미지부터 시작하기 위함입니다.)

5.setInterval(함수, 시간);을 활용해서 일정 시간마다 함수가 실행되게 했습니다.

 

setTimeout() setTimeout 함수는 일정 시간이 지난 후에 함수를 실행하도록 예약하는 JavaScript 내장 함수입니다. 이 함수는 두 개의 인자를 받습니다.
첫 번째 인자는 실행될 함수이며, 두 번째 인자는 함수 실행을 예약하고 싶은 시간(밀리초 단위)입니다.

4.GSAP활용

<!-- GSAP CDN  -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script>
    // setInterval(() => {
    //     currentIndex++;

    //     gsap.to(sliderInner, {
    //         y:-(sliderHeight * currentIndex),
    //         duration: 1
    //     });

    //     if(currentIndex === sliderCount){
    //         setTimeout(() => {
    //             gsap.to(sliderInner, {
    //                 y:0,
    //                 duration: 0
    //             });
    //         }, 70);
    //         currentIndex = 0;
    //     }

    //     console.log(sliderHeight * currentIndex);
    // }, 1000);
</script>

1.currentIndex의 값은 0입니다. 이걸 일정 시간마다 1씩 증가 시킵니다.

2.gsap.to(대상, {속성:값});

3.gsap에서는 translateY가 없습니다. 그래서 y를 사용했습니다.

(-800px / -1600px / -2400px / -3200px / 4000px)

4.if문으로 currentIndex의 1씩 증가된 값이 // sliderCount(이미지의 총갯수)와 같으면 실행이 됩니다

(div태그 .slider__inner의 style을 0으로 맞춥니다.)

5.그리고 currentIndex의 값을 0으로 만듭니다.

(이렇게 해주면 슬라이드의 마지막에 도착했을때. 자연스럽게 0번지의 이미지부터 시작하기 위함입니다.)

 

5.JQUERY 활용

<!-- jQuery -->
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<script>
setInterval(() => {
    currentIndex++;

    $(".slider__inner").css("position", "relative");
    $(".slider__inner").animate( {top:-(sliderHeight * currentIndex)}, 1000);

    if(currentIndex === sliderCount){
        // alert("asd");
        // 1번만 실행
        setTimeout(() => {
            $(".slider__inner").animate( {top:-(sliderHeight * currentIndex)}, 0);
            // $(".slider__inner").style.transform ="translateX(0px)";
        }, 700);
        currentIndex = 0;
    }
}, 1000);
</script>

1.currentIndex의 값은 0입니다. 이걸 일정 시간마다 1씩 증가 시킵니다.

2.div태그 .slider__inner을 찾고 animate속성을 지정합니다.

(jQuery에는 translateY가 없어서 top을 사용했습니다.)

3.if문을 통해서 currentIndex의 값이 1씩 증가되어서 이미지의 총갯수5개와 똑같다면 

  div태그 .slider__inner의 속성을 0으로 초기화 합니다.

4.그리고 currentIndex의 값을 0으로 만듭니다.

 

슬라이더 4번과 너무 비슷해서 설명글이 중복이 되네요