首页 > 解决方案 > 为什么这个滑块会带入滑块下方的内容,然后再向上?

问题描述

我在下面的片段中有一个滑块。如果您运行它,您会注意到当您浏览滑块时,内容进入滑块下方,然后向上进入滑块容器。

我该如何解决这个问题,让它在不破坏内容的情况下左右滑动?

class Slider {
  constructor(sliderElem) {
    this.slider = sliderElem;
    this.sliderItems = sliderElem.getElementsByClassName("testimonial__item");
    this.nextBtn = sliderElem.querySelector(
      ".testimonial__slider-control-next"
    );
    this.prevBtn = sliderElem.querySelector(
      ".testimonial__slider-control-prev"
    );
    this.currentIndex = 0;
    this.prevItemIndex = this.sliderItems.length - 1;
    this.nextItemIndex = 1;
    this.isSliding = false;

    // Set Item Indexs if active class is specified on an element other than the first.
    for (let i = 0; i < this.sliderItems.length; i++) {
      if (this.sliderItems[i].classList.contains("active")) {
        this.currentIndex = i;
        if (i + 1 === this.sliderItems.length) {
          this.nextItemIndex = 0;
        }
        this.nextItemIndex = i + 1;
        if (i !== 0) {
          this.prevItemIndex = i - 1;
        }
        break;
      }
    }
    this.setEventListeners();
  }
  setEventListeners() {
    this.prevBtn.addEventListener("click", () => {
      this.prev();
    });
    this.nextBtn.addEventListener("click", () => {
      this.next();
    });
  }
  setIndices(direction) {
    let index;
    if (direction === "NEXT") {
      index =
        this.currentIndex === this.sliderItems.length - 1 ?
        0 :
        this.currentIndex + 1;
    }
    if (direction === "PREV") {
      index =
        this.currentIndex === 0 ?
        this.sliderItems.length - 1 :
        this.currentIndex - 1;
    }
    if (index === 0) {
      this.currentIndex = index;
      this.nextItemIndex = index + 1;
      this.prevItemIndex = this.sliderItems.length - 1;
    } else if (index === this.sliderItems.length - 1) {
      this.currentIndex = this.sliderItems.length - 1;
      this.nextItemIndex = 0;
      this.prevItemIndex = this.currentIndex - 1;
    } else {
      this.currentIndex = index;
      this.nextItemIndex = index + 1;
      this.prevItemIndex = index - 1;
    }
  }
  next() {
    if (this.isSliding) return;
    this.isSliding = !this.isSliding;
    this.sliderItems[this.nextItemIndex].classList.add("next-item");
    setTimeout(() => {
      this.sliderItems[this.currentIndex].classList.add("slide-next");
      this.sliderItems[this.nextItemIndex].classList.add("slide-end");
      this.sliderItems[this.nextItemIndex].classList.add("active");
    }, 20);
    setTimeout(() => {
      this.sliderItems[this.nextItemIndex].classList.remove(
        "next-item",
        "slide-end"
      );
      this.sliderItems[this.currentIndex].classList.remove(
        "slide-next",
        "active"
      );
      this.setIndices("NEXT");
      this.isSliding = false;
    }, 400);
  }
  prev() {
    if (this.isSliding) return;
    this.isSliding = !this.isSliding;
    this.sliderItems[this.prevItemIndex].classList.add("prev-item");
    setTimeout(() => {
      this.sliderItems[this.currentIndex].classList.add("slide-prev");
      this.sliderItems[this.prevItemIndex].classList.add("slide-end");
      this.sliderItems[this.prevItemIndex].classList.add("active");
    }, 20);
    setTimeout(() => {
      this.sliderItems[this.prevItemIndex].classList.remove(
        "prev-item",
        "slide-end"
      );
      this.sliderItems[this.currentIndex].classList.remove(
        "slide-prev",
        "active"
      );
      this.setIndices("PREV");
      this.isSliding = false;
    }, 400);
  }
}

const slider = new Slider(document.querySelector(".testimonial__slider"));
.container {
  padding: 2em;
}

.testimonial {
  display: flex;
  flex-direction: column;
  /* slide animation */
}
.testimonial__slider {
  margin-top: 2rem;
  height: auto;
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
}
.testimonial .arrows {
  display: flex;
  margin-right: auto;
  margin-top: 2rem;
}
@media (min-width: 768px) {
  .testimonial .arrows {
    margin-right: unset;
    margin-left: auto;
    margin-top: unset;
  }
}
.testimonial__controls {
  display: flex;
  flex-direction: column;
  margin-bottom: 2rem;
}
@media (min-width: 768px) {
  .testimonial__controls {
    display: flex;
    flex-direction: row;
    align-items: center;
  }
}
.testimonial__slider .testimonial__item.active, .testimonial__slider .testimonial__item.prev-item, .testimonial__slider .testimonial__item.next-item {
  display: flex;
}
.testimonial__img {
  min-width: 40%;
}
.testimonial__img img {
  height: 100%;
}
.testimonial__slider .testimonial__item {
  height: 100%;
  width: 100%;
  display: none;
  transition: transform 0.2s ease;
}
.testimonial__item {
  background: #F2F5F9;
  display: flex;
  flex-direction: column;
  transition: all 0.2s ease;
}
@media (min-width: 576px) {
  .testimonial__item {
    display: flex;
    flex-direction: row;
  }
}
.testimonial__content {
  display: flex;
  flex-direction: column;
  padding: 2.75rem 2.5rem 2.5rem;
  justify-content: space-between;
}
.testimonial__credits {
  display: flex;
  flex-direction: column;
  margin-top: 2rem;
  border-left: 4px solid #005fec;
  padding-left: 0.75rem;
}
.testimonial__name {
  margin-bottom: 0.5rem;
}
.testimonial__item.prev-item, .testimonial__item.active.slide-next {
  transform: translateX(-100%);
}
.testimonial__item.active.slide-prev, .testimonial__item.next-item {
  transform: translateX(100%);
}
.testimonial__item.prev-item.slide-end, .testimonial__item.next-item.slide-end {
  transform: translateX(0);
}
.testimonial__slider-control-prev, .testimonial__slider-control-next {
  cursor: pointer;
  display: flex;
}
.testimonial__slider-control-prev {
  left: 20px;
  margin-right: 1.25rem;
}
.testimonial__slider-control-prev:hover {
  opacity: 1;
}
.testimonial__slider-control-next {
  right: 20px;
}
.testimonial__slider-control-next:hover {
  opacity: 1;
}
<div class="container">
  <div class="testimonial">
    <div class="testimonial__slider">
      <div class="testimonial__controls">
        <h3>Lorem ipsum dolor sit amet.</h3>
        <div class="arrows">
          <span class="testimonial__slider-control-prev" role="button">
            <img aria-hidden="true" src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Feather-arrows-arrow-left.svg/768px-Feather-arrows-arrow-left.svg.png" height="25" width="25" alt="Previous Slide Button">
          </span>
          <span class="testimonial__slider-control-next" role="button">
            <img aria-hidden="true" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Feather-arrows-arrow-right.svg/1200px-Feather-arrows-arrow-right.svg.png" height="25" width="25" alt="Next Slide Button">
          </span>
        </div>
      </div>
      <div class="testimonial__item active">
        <div class="testimonial__img">
          <img class="img-fluid" src="https://nextivaweb.imgix.net/heroes/case-study/Case-Study-Conan-hero.jpg?w=336&h=412&auto=format&crop=focalpoint&fit=crop&fp-x=.75&fp-z=1.3&fp-y=.39" alt="">
        </div>
        <div class="testimonial__content">
          <div class="testimonial__text">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti laboriosam fugiat perferendis blanditiis, dignissimos temporibus sunt aliquam sequi quia! Deleniti earum quibusdam dolorem accusantium ipsum?</p>
          </div>
          <div class="testimonial__credits">
            <span class="testimonial__name kicker kicker--bold">Lorem, ipsum.</span>
            <span class="testimonial__position kicker kicker--light">Lorem ipsum dolor sit amet,
              Burbank,
              CA</span>
          </div>
        </div>
      </div>
      <div class="testimonial__item">
        <div class="testimonial__img">
          <img class="img-fluid" src="https://sandbox-uploads.imgix.net/u/1630477471-dd0cd5b16967417586c822d6dabcb995?w=336&h=412&auto=format" alt="">
        </div>
        <div class="testimonial__content">
          <div class="testimonial__text">
            <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Architecto veniam eos, omnis commodi doloribus dignissimos at ad quia asperiores nulla.</p>
          </div>
          <div class="testimonial__credits">
            <span class="testimonial__name kicker kicker--bold">Lorem, ipsum.</span>
            <span class="testimonial__position kicker kicker--light">Lorem ipsum dolor sit amet.</span>
          </div>
        </div>
      </div>
      <div class="testimonial__item">
        <div class="testimonial__img">
          <img class="img-fluid" src="https://sandbox-uploads.imgix.net/u/1630477587-e54d61f4eef5e36c72dccd1fc0463514?w=336&h=412&auto=format" alt="">
        </div>
        <div class="testimonial__content">
          <div class="testimonial__text">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit nesciunt aliquam cum commodi perferendis, iusto numquam eum neque nulla natus adipisci facere officiis.</p>
          </div>
          <div class="testimonial__credits">
            <span class="testimonial__name kicker kicker--bold">Lorem, ipsum.</span>
            <span class="testimonial__position kicker kicker--light">Lorem ipsum dolor sit amet,
              Burbank,
              CA</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

标签: javascriptcss

解决方案


display: flexdisplay: block除非另有说明,否则使用 的某些属性。其中之一是它占据了整个水平空间并将同一空间中的其他项目向下推到它们自己的行中。

在 __item 离开屏幕之前,您的 .active 类不会删除显示。因为它们是相对定位的,所以它们必须尊重所有其他 __items 的相对位置。

需要大量额外定义的更简单的方法是使用position: absolute; top: 0;,然后相应地摆弄其他东西。你也可以试试 inline-flex。但是,我对此不太熟悉,所以我从这里开始,他们很好地解释了容器和项目之间的区别:

https://stackoverflow.com/a/27459133/6775641


推荐阅读