单击轮播指示器并显示相关幻灯片

Click carousel indicator and show relevant slide

我正在为一个项目构建一个基本的“推荐”轮播。到目前为止,一切都按预期工作,除了使每张相应幻灯片的轮播指示器可点击。幻灯片项目应根据单击的指示器按钮向前或向后移动。

我认为我需要获取指示器按钮的索引并将其与幻灯片的索引相匹配。我一直在思考如何在我的代码中使用它。

<section class="wrapper_carousel flex flex-col justify-center w-full">


            <div class="carousel-data w-full mt-8 mb-16">

                <div class="carousel-item">

                    <p class="text_caption white italic">
                        item1
                    </p>

                    <span class="caption-author white">
                        - author
                    </span>

                </div>

               <!-- carousel items 2 - 6 same as above -->

            </div>

            <div class="carousel-indicators flex items-center">
                 <!-- buttons generated w javascript -->
            </div>

            <div class="carousel-controls flex justify-end mt-auto">
                <button type="button" class="button_carousel-prev"><i class="fas fa-caret-left"></i></button>
                <button type="button" class="button_carousel-next ml-1"><i class="fas fa-caret-right"></i></button>
            </div>

        </section>
.carousel-item {
    opacity: 0;
    position: absolute;
    z-index: 500;
    transition: 500ms ease-in-out;
}

.active-slide {
    opacity: 1;
    position: relative;
    z-index: 1000;
}

.next, .prev {
    z-index: 900;
}

.next {
    animation: animate-right 500ms;
}

.prev {
    animation: animate-left 500ms;
}

@keyframes animate-right {
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(100%);
    }
  }

  @keyframes animate-left {
    100% {
        transform: translateX(-100%);
    }
    0% {
        transform: translateX(0);
    }
  }

.carousel-indicators {
    margin: 0 auto;
}

.carousel-indicators button {
    width: 50px;
    height: 8px;
    background: var(--mid-grey);
    margin-left: 8px;
}

.carousel-indicators button:first-of-type {
    margin-left: 0;
}

.carousel-controls button {
    background: var(--yellow);
    padding: 24px;
    font-size: var(--text_md);
    width: 60px;
    max-width: 100%;
    height: 60px;
    max-height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}

.carousel-controls button .fas {
    line-height: 1em;
    font-size: 1.25em;
    pointer-events: none;
}

button.current-indicator {
    background: var(--yellow);
}

let position = 0;
const slides = document.querySelectorAll('.carousel-item');
const lastSlide = document.querySelector('.carousel-item:last-of-type');
const totalSlides = slides.length;
const indicatorContainer = document.querySelector('.carousel-indicators');
const indicatorButtons = [];

function initialSlide() {

    if (position == 0) {
        slides[position].classList.add('active-slide');
    }

}

function setIndicators() {

    if (indicatorContainer !== null) {
        for (let i = 0; i < totalSlides; i++) {
            const button = document.createElement('button');
            button.setAttribute('type', 'button');
            indicatorContainer.appendChild(button);
            indicatorButtons.push(button);
        }

        indicatorButtons[0].classList.add('current-indicator');

    }

}

window.onload = function (event) {
    initialSlide();
    setIndicators();
  };

  function updateIndicators() {

    indicatorButtons.forEach( function(element, index){

        if (index === position) {
            element.classList.add('current-indicator');
        } else {
            element.classList.remove('current-indicator');
        }

    });
}

  function updatePosition() {

    for (let slide of slides) {
        slide.classList.remove('active-slide');
        slide.classList.remove('next');
        slide.classList.remove('prev');
    }

    slides[position].classList.add('active-slide');

    updateIndicators();

  }

  function animateRight() {

      if (position === 0) {
        lastSlide.classList.add('next');
      } else {
        slides[position - 1].classList.add('next');
      }
 
  }

  function animateLeft() {

      if (position === totalSlides - 1) {
          slides[0].classList.add('prev');
      } else {
        slides[position + 1].classList.add('prev');
      }
    
  }

  function moveForward() {

      if (position === totalSlides - 1) {
          position = 0;
      } else {
            position++;
      }

      updatePosition();
      animateRight();
  }

  function moveBack() {

    if (position === 0) {
        position = totalSlides - 1;
    } else {
          position--;
    }

    updatePosition();
    animateLeft();
}

document.addEventListener('click', function (event) {
    if (event.target.matches('.button_carousel-next')) {
        moveForward();
    }

    if (event.target.matches('.button_carousel-prev')) {
        moveBack();
    }

    if (event.target.matches('.carousel-indicators button')) {
        
    }

}, false);

你可以这样做:

在此处添加一行:

function setIndicators() {
...
button.setAttribute('type', 'button');
button.setAttribute('btindex', i); // <--
indicatorContainer.appendChild(button);

然后事件侦听器中的最后一条语句将是:

if (event.target.matches('.carousel-indicators button')) {
    moveSelected(parseInt(event.target.getAttribute('btindex')));
}

新方法将是:

function moveSelected(selectedId) {

    var prevPos = position;
    position = selectedId;

    updatePosition();

    if (position > prevPos) {
        animateRight();
    }else if (position < prevPos) {
        animateLeft();
    }
}