首页 > 解决方案 > Javascript interfering with CSS Transition

问题描述

I've recently started work on a basic landing-page website. Part of the page is a basic image slider with both the auto-nav and the manual nav being powered by JS. I got everything working but for one thing: I just can't figure out how to get the smooth transition between images - as seen in this example - to work. I figured out the problem after reading some related questions on Stackoverflow: To make the Slideshow work I'm using slides[i].style.display = "none"; and slides[slideIndex-1].style.display = "block"; to update the css code handling the 'display' element - this over rights the 'transition: 2s' css code one would need for the simple slide animation as seen in the video. As I'm terribly new to Web development I could not wrap my head around possible solutions posted here on Stackoverflow and would really appreciate anyone that could help me out with an answer to my specific problem or an alternative way to solve it.

Cheers, Jerome

var slideIndex = 1;
showSlides(slideIndex);

// Next/previous controls
function plusSlides(n) {
  showSlides(slideIndex += n);
}

// Thumbnail image controls
function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("item");
  var dots = document.getElementsByClassName("dot");
  if (n > slides.length) {
    slideIndex = 1
  }
  if (n < 1) {
    slideIndex = slides.length
  }
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }
  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace(" active", "");
  }
  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className += " active";
}

//automatic

var slideIndexAuto = 0;
showSlidesAuto();

function showSlidesAuto() {
  var i;
  var slides = document.getElementsByClassName("item");
  var dots = document.getElementsByClassName("dot");
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
    dots[i].className = dots[i].className.replace(" active", "");
  }
  slideIndexAuto++;
  if (slideIndexAuto > slides.length) {
    slideIndexAuto = 1
  }
  slides[slideIndexAuto - 1].style.display = "block";
  dots[slideIndexAuto - 1].className += " active";
  setTimeout(showSlidesAuto, 5000);
}
.slider {
  width: 65%;
  max-width: 940px;
  height: 500px;
  border-radius: 0.25rem;
  position: relative;
  overflow: hidden;
}

.slider .left-slide,
.slider .right-slide {
  position: absolute;
  height: 40px;
  width: 40px;
  background-color: #444444;
  border-radius: 50%;
  color: #ffffff;
  font-size: 20px;
  top: 50%;
  cursor: pointer;
  margin-top: -20px;
  text-align: center;
  line-height: 40px;
}

.slider .left-slide:hover,
.slider .right-slide:hover {
  box-shadow: 0px 0px 10px black;
  background-color: #29a8e2;
}

.slider .left-slide {
  left: 30px;
}

.slider .right-slide {
  right: 30px;
}

.slider .slider-items .item img {
  width: 100%;
  height: 500px;
  display: block;
}

.slider .slider-items .item {
  position: relative;
  transition: 4s;
}

.slider .slider-items .item .caption {
  position: absolute;
  width: 100%;
  height: 100%;
  bottom: 0px;
  left: 0px;
  background-color: rgba(0, 0, 0, .5);
}
<div class="slider">
  <div class="slider-items">
    <div class="item fade">
      <img src="/images/cs-slider-high.jpg" />
      <div class="caption">
        <p class="caption-text">COMING</p>
        <p class="caption-text">OKTOBER 10th</p>
      </div>
    </div>

    <div class="item fade">
      <img src="/images/building-slider.jpg" />
      <div class="caption">
        <p class="caption-text-2">Blackstoneroad 109</br>
        </p>
      </div>
    </div>
    <div class="item fade">
      <img src="/images/kontact-slider.jpg" />
      <div class="caption">
        <p class="caption-text-3">Coffee<br>Drinks<br>Food<br>& More</p>
      </div>
    </div>
    <div class="item fade">
      <img src="/images/seminar-slider.jpg" />
      <div class="caption">
        <p class="caption-text-3">Seminar Rooms<br>Inspiration<br>Shopping<br>& More</p>
      </div>
    </div>

  </div>

  <!-- Next and previous buttons -->
  <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
  <a class="next" onclick="plusSlides(1)">&#10095;</a>

</div>

<!-- The dots/circles -->
<div class="align-text-center">
  <span class="dot" onclick="currentSlide(1)"></span>
  <span class="dot" onclick="currentSlide(2)"></span>
  <span class="dot" onclick="currentSlide(3)"></span>
  <span class="dot" onclick="currentSlide(3)"></span>
</div>

标签: javascripthtmlcss

解决方案


这是怎么回事:http: //jsfiddle.net/lharby/qox05y96/

为简化起见,我去掉了点动画(尽管该代码更接近您想要的效果)。

这是简化的JS:

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("item");
  var dots = document.getElementsByClassName("dot");
  if (n > slides.length) {
    slideIndex = 1
  }
  if (n < 1) {
    slideIndex = slides.length
  }
  for (i = 0; i < slides.length; i++) {
    slides[i].classList.remove('active'); // this is updated
  }
  slides[slideIndex - 1].className += " active";
}

//automatic
var slideIndexAuto = 0;
showSlidesAuto();

function showSlidesAuto() {
  var i;
  var slides = document.getElementsByClassName("item");
  var dots = document.getElementsByClassName("dot");
  for (i = 0; i < slides.length; i++) {
    slides[i].classList.remove('active'); // this is updated
    
  }
  slideIndexAuto++;
  if (slideIndexAuto > slides.length) {
    slideIndexAuto = 1
  }
  slides[slideIndexAuto - 1].classList.add('active'); // this is updated
  setTimeout(showSlidesAuto, 4000);
}

这意味着我们还必须更改 css。display none/block使用css 过渡更难制作动画。所以我用过opacity: 0/1and visibility: hidden/visible。然而,另一个权衡是项目元素不能相对定位,这会将它们堆叠在一起(或并排)通常用于动画幻灯片,您将为每张幻灯片使用绝对位置,但我意识到这会导致您另一个问题。

CSS:

.slider .slider-items .item {
    visibility: hidden;
    opacity: 0;
    transition: 4s;
}

.slider .slider-items .item.active {
    visibility: visible;
    opacity: 1;
    transition: 4s;
}

至少现在所有的 css 都在 css 中处理,而 js 纯粹添加或删除了一个类名,我觉得这使得更新更容易一些。


推荐阅读