필요없는 목록/CSS 스타일

슬라이드 API 없이 코드로 하기 6 / 10 (버튼 클릭)

비밀안 2023. 4. 13. 19:24
클릭

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

-

이름이 나와요

최종 완성된 모습

닷버튼을 클릭하면 슬라이드가 이동을 합니다.

Next와 Prev버튼은 선생님이 해주셨습니다.

 

HTML+CSS코드

<style>
/* slider__wrap */
.slider__wrap {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 800px;
    height: 450px;
    box-shadow: 0 50px 100px rgba(0,0,0,0.4);
}
.slider__img {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.slider__img img {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transform: scale(1.1);
    transition: all 500ms ease-in-out;
}
.slider__img img.active {
    opacity: 1;
    transform: scale(1);
}
.slider__thumb {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, 150px);
    width: 100px;
    display: flex;
    justify-content: center;
    gap: 10px;
}
.slider__thumb img {
    cursor: pointer;
    border: 2px #fff transparent;
}
.slider__thumb img.active {
    cursor: pointer;
    border: 2px solid #fff;
}
.slider__btn a {
    position: absolute;
    top: 0;
    width: 40px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 12px;
    color: #fff;
    background-color: rgba(0,0,0,0.2);
    transition: all 300ms ease-in-out;
}
.slider__btn a.next {
	right: 0;
}
.slider__btn a:hover {
	background-color: rgba(0,0,0,0.5);
}
</style>
</head>

<body class="img07 bg07 font07">
    <header id="header">
        <h1>Javascript Slider Effect07</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><a href="sliderEffect05.html">5</a></li>
            <li><a href="sliderEffect06.html">6</a></li>
            <li class="active"><a href="sliderEffect07.html">7</a></li>
        </ul>
    </header>
     <!-- //header -->
     <main id="main">
        <div class="slider__wrap">
            <div class="slider__img"></div>
            <div class="slider__thumb"></div>
            <div class="slider__btn">
                <a href="#" class="prev" title="이전이미지">prev</a>
                <a href="#" class="next" title="다음이미지">next</a>
            </div>
        </div>
    </main> 
    <!-- //main -->

    <footer id="footer">
        <a href="mailto:skadldldl123@gmail.com">mailto: skadldldl123@gmail.com</a>
    </footer>
    <!-- //footer -->
</body>

코드설명

(이번것도 HTML을 슬라이드 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코드

<script>
// 선택자 
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");//버튼

let currentIndex = 0;                               //현재 보이는 이미지
let sliderCount = slider.length;                    //이미지 갯수
let sliderInterval = 3000;                          //이미지 간격 시간
let sliderWidth = slider[0].offsetWidth;            //이미지 가로값
let dotIndex = "";

function init(){
    //이미지 갯수 만큼 닷메뉴 생성
    slider.forEach(() => dotIndex += "<a href='#' class='dot cli'>이미지</a>");
    sliderDot.innerHTML = dotIndex;

    //첫번째 닷메뉴 활성화 표시
    sliderDot.firstChild.classList.add("active");


    // 닷버튼 클릭
    // ~_~ ... ~_~
    let dotClick = sliderWrap.querySelectorAll(".cli");
    dotClick.forEach((el, index) => {
        dotClick[index].addEventListener("click", () => {
            gotoSlider(index);
        });
    });
}
init();

// 이미지 이동시키기
function gotoSlider(num){
    // 400ms : 4초
    sliderInner.style.transition = "all 400ms";
    sliderInner.style.transform = "translateX(" + (-sliderWidth*num) +"px)";
    currentIndex = num;

    // 닷 메뉴 활성화 하기
    let dotActive = document.querySelectorAll(".slider__dot .dot");
    dotActive.forEach((active) => { active.classList.remove("active"); });
    dotActive[num].classList.add("active");
}

// next + prev 버튼을 클릭
sliderBtn.forEach((btn, index) => {
    btn.addEventListener("click", () => {
        let prevIndex = (currentIndex+(sliderCount-1)) % sliderCount;
        let nextIndex = (currentIndex+1) % sliderCount;

        if(btn.classList.contains("prev")){
            gotoSlider(prevIndex);
        }
        else {
            gotoSlider(nextIndex);
            console.log("asd");
        }
    });
});
    </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 sliderWidth = slider[0].offsetWidth;            //이미지 가로값
let dotIndex = "";

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

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

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

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

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

5.dotIndex=""는 이제 html태그의 코드가 들어갈 곳입니다.

 

3.

 function init(){
//이미지 갯수 만큼 닷메뉴 생성
slider.forEach(() => dotIndex += "<a href='#' class='dot click'>이미지</a>");
sliderDot.innerHTML = dotIndex;

//첫번째 닷메뉴 활성화 표시
sliderDot.firstChild.classList.add("active");


// 닷버튼 클릭
// ~_~ ... ~_~
let dotClick = sliderWrap.querySelectorAll(".click");
dotClick.forEach((el, index) => {
    dotClick[index].addEventListener("click", () => {
        gotoSlider(index);
    });
});
}
init();

1.slider에는 각각의 이미지 5장이 들어가 있습니다.

2.slider로 forEach문으로 불러와서 a태그를 5번 실행합니다.

3.dotIndex에 저장된 태그를 div태그인 .slider__dot의 HTML로 넣읍니다.

4.sliderDot.firstChild.classList.add("active");는 div태그인 .slider__dot의 첫번째 태그에 active클래스를 먼저 줍니다.

5.let dotClick은 dotIndex에 저장된 a태그의 이름은 .click클래스를 찾습니다.

6.dotIndex에 저장된 a태그의 .click클래스를 가진 것을 클릭했다면 해당 태그의 번지를 가져옵니다.

그리고 그 번지를 gotoSlider()에 전달합니다.

7.init()은 함수 실행문입니다.

(이 방법이 가독성이 좋아 보여서 작성을 해봤습니다.)

 

4.

// 이미지 이동시키기
function gotoSlider(num){
    // 400ms : 4초
    sliderInner.style.transition = "all 400ms";
    sliderInner.style.transform = "translateX(" + (-sliderWidth*num) +"px)";
    currentIndex = num;

    // 닷 메뉴 활성화 하기
    let dotActive = document.querySelectorAll(".slider__dot .dot");
    dotActive.forEach((active) => { active.classList.remove("active"); });
    dotActive[num].classList.add("active");
}

1. 3번에서 받은 index의 값을 매개변수를 받아왔습니다.

2. translateX()은 sliderWidth의 값 800과 매개변수로 받은 값을 곱해서 그만큼 이동시킵니다.

3. let dotActive는 .dot클래스를 찾습니다.

4. dotActive.forEach로 태그를 가져옵니다.

5. .dot클래스에 있는 .active클래스를 전부 지웁니다.

6. .dot클래스의 해당 번지에 active 클래스를 줍니다.

(함수의 매개변수로 받는 값은 .dot클래스를 클릭할때마다 함수에 매개변수로 전달합니다.)

 

 

5.

// next + prev 버튼을 클릭
sliderBtn.forEach((btn, index) => {
    btn.addEventListener("click", () => {
        let prevIndex = (currentIndex+(sliderCount-1)) % sliderCount;
        let nextIndex = (currentIndex+1) % sliderCount;

        if(btn.classList.contains("prev")){
            gotoSlider(prevIndex);
        }
        else {
            gotoSlider(nextIndex);
            console.log("asd");
        }
    });
});

1. sliderBtn은 div태그인 .slider__btn 안에 있는 a태그입니다.

2. forEach문으로 태그와 인덱스 번호를 가져옵니다.

3. a태그의 클릭했으면 if문을 통해 비교합니다.

4. prev라는 이름을 가지면 if문을 실행시키고.

5. 아니라면 else문을 실행시킵니다.

contains() 클래스가 있는지 없는지 검사합니다.
있으면 true / 없으면 false를 반환합니다.