试图创建连续的JavaScript滑块

时间:2017-06-29 16:04:40

标签: javascript html css slider

我的滑块的问题是当它到达最后一张幻灯片时我点击下一张它跳过两张幻灯片到达第一张幻灯片。同样,当我在第一张幻灯片上并单击上一张时,它会跳过幻灯片以转到最后一张幻灯片。我想说的是,当我到达最后一张幻灯片并单击NEXT时,第一张幻灯片将从右到左。 (第一张幻灯片上PREVIOUS按钮的类似概念)。我尝试使用insertBefore()appendChild()作为幻灯片,但无法弄清楚...

这是我的代码:



// Slider
const slider_wrapp = document.querySelector('.tract-slider');
const slider = document.querySelector('.tract-slider-wrapp');
var slide = document.getElementsByClassName('tract-slide');

const leftBtn = document.querySelector('.slide-left');
const rightBtn = document.querySelector('.slide-right');

let swWidth = slider_wrapp.clientWidth;
let sliderWidth = swWidth * slide.length;
let slideWidth = 0;

slider.style.width = sliderWidth + "px";

for (var i = 0; i < slide.length; i++) {
  slide.item(i).style.width = swWidth + "px";
}

function moveRight() {
  slideWidth === sliderWidth - swWidth ? slideWidth = 0 : slideWidth += swWidth;
  slider.style.transform = "translateX(" + (-slideWidth) + "px)";

}

function moveLeft() {
  slideWidth === 0 ? slideWidth = sliderWidth - swWidth : slideWidth -= swWidth;
  slider.style.transform = "translateX(" + (-slideWidth) + "px)";
}

rightBtn.addEventListener("click", function() {
  moveRight();
});

leftBtn.addEventListener("click", function() {
  moveLeft();
});
&#13;
.tract-slider {
  width: 100%;
  height: 75vh;
  position: relative;
  overflow: hidden;
}

.tract-slider-wrapp {
  height: 100%;
  position: relative;
  -webkit-transition: all 350ms cubic-bezier(.08, .13, 0, .81);
  -o-transition: all 350ms cubic-bezier(.08, .13, 0, .81);
  transition: all 350ms cubic-bezier(.08, .13, 0, .81);
}

.tract-slide {
  height: 100%;
  float: left;
  position: relative;
  display: block;
  background-position: center;
  -webkit-background-size: cover;
  background-size: cover;
}

.tract-slide:nth-child(1) {
  background-image: url("https://static.pexels.com/photos/126282/pexels-photo-126282.jpeg");
}

.tract-slide:nth-child(2) {
  background-image: url("https://static.pexels.com/photos/29017/pexels-photo-29017.jpg");
}

.tract-slide:nth-child(3) {
  background-image: url("https://static.pexels.com/photos/70760/dandelion-dandelion-seeds-taraxacum-fluffy-70760.jpeg");
}

.tract-slider-control {
  position: absolute;
  left: 0;
  bottom: 0;
  background: #ffffff;
  padding: 1em;
}

.tract-slider-btn {
  display: inline-block;
  cursor: pointer;
  margin-left: 1em;
}

.tract-slider-btn:nth-child(1) {
  margin-left: 0;
}
&#13;
<div class="tract-slider">
  <div class="tract-slider-wrapp">
    <div class="tract-slide"></div>
    <div class="tract-slide"></div>
    <div class="tract-slide"></div>
  </div>
  <div class="tract-slider-control">
    <div class="tract-slider-btn slide-left">Prev</div>
    <div class="tract-slider-btn slide-right">Next</div>
  </div>
</div>
&#13;
&#13;
&#13;

PS。请使用JavaScript解决方案

1 个答案:

答案 0 :(得分:2)

创建无限滑块意味着您需要在DOM中移动幻灯片,以便给出连续轨道的印象。

你需要改变的第一件事就是将他们的背景与他们在DOM中的位置联系起来。如果我们想要从第一张幻灯片滑回到最后一张幻灯片,我们需要拍摄最后一张幻灯片,在第一张幻灯片之前添加,但考虑到您当前的CSS,这将改变所有幻灯片的背景,因为它们目前已被限制为他们在DOM中的位置(...:nth-child {background-image:...} ...)。

需要改变的第二件事是将幻灯片放入滑块轨道。如果他们浮动,每当我们更改订单时,所有其他幻灯片都会受到影响。通过使用position:absolute定位它们,每个幻灯片独立移动而不影响其他幻灯片,因此在保持控制的同时更容易重新排列它们。

长话短说,我从头开始并将所有方法放在一个对象中:theSlider

reset()函数执行繁重的工作:它将before类放在第一个元素上,current放在第二个元素上,after放在所有其余元素上。所以你必须把#34;最后一个&#34;首先滑动,因为滑块将以&#34; current&#34;之前附加的方式开始。之一。

通过将go-leftgo-right类应用于轨道来完成滑动。转换完成后,我只是将第一张/最后一张幻灯片移动到新位置,具体取决于大小写,然后再次运行reset()(删除所有类并根据新位置重新应用它们)。
动画由CSS处理。所有JavaScript都是应用/删除类并在DOM中移动幻灯片。

&#13;
&#13;
var theSlider = {
  track : document.querySelector('.tract-slider-wrapp'),
  // has to match `transition-duration` in CSS:
  duration : 600,
  reset : function() {
    var slides = document.querySelectorAll('.tract-slider-wrapp > div');
    for (var i = 0; i < slides.length; i++) {
      slides[i].className = '';
      slides[i].classList.add(i > 1? 'after' : (i ? 'current':'before'))
    }
  },
  init : function() {
    theSlider.reset();
    theSlider.track.classList.remove('not-loaded')
  },
  next : function() {
    theSlider.track.classList.add('go-right');
    setTimeout(function(){
      var firstSlide = document.querySelector('.tract-slider-wrapp > div:first-child');
      theSlider.track.appendChild(firstSlide);
      theSlider.reset();
      theSlider.track.classList.remove('go-right')
    },theSlider.duration)
  },
  prev : function() {
    theSlider.track.classList.add('go-left');
    setTimeout(function() {
      var lastSlide = document.querySelector('.tract-slider-wrapp > div:last-child');
      theSlider.track.insertBefore(lastSlide, theSlider.track.firstChild);
      theSlider.reset();
      theSlider.track.classList.remove('go-left')
    },theSlider.duration)
  },
  prevButton : document.querySelector('.slide-left'),
  nextButton : document.querySelector('.slide-right')
};
window.addEventListener("load", theSlider.init);
theSlider.prevButton.addEventListener('click', theSlider.prev);
theSlider.nextButton.addEventListener('click', theSlider.next);
&#13;
.tract-slider {
  width: 100%;
  height: 75vh;
  position: relative;
  overflow: hidden;
  background-color: #f5f5f5;
}

.tract-slider-wrapp {
  height: 100%;
  transition: all 350ms cubic-bezier(.08, .13, 0, .81);
  opacity: 1;
}
.tract-slider-wrapp.not-loaded {
  opacity: 0;
}

.tract-slider-wrapp>div {
  height: 100%;
  position: absolute;
  background: transparent no-repeat 50% 50% /cover;
  width: 100%;
}
.tract-slider-wrapp > div.before {
  margin-left: -100%;
}
.tract-slider-wrapp > div.current + div {
  margin-left: 100%;
}
.tract-slider-wrapp > div.after ~ div {
  opacity: 0;
}
.tract-slider-control {
    position: absolute;
    width: 100%;
    z-index: 1;
    top: 50%;
    display: flex;
    justify-content: space-between;
    transform: translateY(-50%);
}
.tract-slider-control div {
  background-color: rgba(0,0,0,.35);
  padding: .5rem 1rem;
  color: white;
  cursor: pointer;
}
.tract-slider-control :first-child {
  border-radius: 0 17px 17px 0;
}
.tract-slider-control :last-child { 
  border-radius: 17px 0 0 17px;
}
body {
  margin: 0;
}
.go-right div {
  transform: translateX(-100%);
}
.go-left div {
  transform: translateX(100%);
}
.go-right div, .go-left div {
  transition-property: transform;
  transition-timing-function: cubic-bezier(.4,0,.2,1);
  /* has to match `duration` in js: */
  transition-duration: 600ms;
}
&#13;
<div class="tract-slider">
  <div class="tract-slider-wrapp not-loaded">
    <div style="background-image:url('https://static.pexels.com/photos/126282/pexels-photo-126282.jpeg')"></div>
    <div style="background-image:url('https://static.pexels.com/photos/29017/pexels-photo-29017.jpg')"></div>
    <div style="background-image:url('https://static.pexels.com/photos/70760/dandelion-dandelion-seeds-taraxacum-fluffy-70760.jpeg')"></div>
  </div>
  <div class="tract-slider-control">
    <div class="tract-slider-btn slide-left">Prev</div>
    <div class="tract-slider-btn slide-right">Next</div>
  </div>
</div>
&#13;
&#13;
&#13;

如果要更改动画持续时间,则需要在js和css中更改动画持续时间 目前唯一的限制是它需要至少3张幻灯片才能工作。我想它可以通过以下方式调整为只使用两张幻灯片:克隆&#34;非活动&#34;滑入第三个位置,转换后删除克隆并克隆另一个。

ToDo's:

  • 前缀CSS,因此可以在更多浏览器中使用
  • .classList.add('whatever')替换为.className += ' whatever'
    .classList.remove('whatever') .className.replace('whatever', '') "dependencies": { "body-parser": "latest", "eris-contracts": "latest", "express": "latest", "mongodb": "latest", "promise": "latest", "rootpath": "latest" } 如果你想向IE展示一些爱情。

我告诉上面的事情只是告诉你:如果你想要开始,不要重新发明轮子。

你使用vanilla javascript很棒。但是迟早你最终会为常见事情编写自己的包装。根据您的/有多好,您将编写自己的,有限的自定义版本的jQuery。请允许我对事物进行透视:Google将一个精简版的jQu​​ery包含在AngularJS中。它很好。

作为一名开发人员,您没有机会撰写更好,更精简和经过测试的版本。此外,你不必这样做。使用你的技能和能力继续前进,而不是侧身。