无限水平滑块为prev和next

时间:2018-06-05 14:19:11

标签: javascript css

我有一个滑块,可以有不确定数量的项目,可以用两个按钮滚动。

这个上一个和下一个函数都具有相同的基本思想,即在div的结尾或开始处获取所需的项目和位置,然后使用margin-left为其设置动画。请参阅下面的代码。

问题:只要慢慢按下按钮,动画就会相同。 但是,由于某些原因,如果快速按下按钮,这两个功能的动画会有所不同。

对于下一个功能,它是一个步进动画。 对于prev动画,它是一个平滑的动画,但在转换过程中它与邻居项目重叠。



var slider = document.getElementById('wrapper');
var currentPosition = 0;
var elementCount = slider.childElementCount;

(function() {
    let brand = slider.getElementsByClassName('brands-brand')[elementCount - 1];
    slider.insertBefore(brand, slider.firstChild);
    brand.style.marginLeft = '-10%';
})();

window.myFunctionNext = function() {
    let brand = slider.getElementsByClassName('brands-brand')[0];
    brand.style.marginLeft = '0px';
    slider.appendChild(brand);
    slider.getElementsByClassName('brands-brand')[0].style.marginLeft = '-10%';
    start=false;
}

window.myFunctionPrev = function() {
    let brand = slider.getElementsByClassName('brands-brand')[elementCount - 1];
    brand.style.marginLeft = '-10%';
    slider.insertBefore(brand, slider.firstChild);
    slider.getElementsByClassName('brands-brand')[1].style.marginLeft = '0%'; 
}

.brands-wrapper {
  white-space: nowrap;
  overflow: hidden;
  font-size: 0;
  position: relative;
  width: 1000px;
  border: 1px solid black;
  box-sizing: border-box;
  }

.brands-slide {
  position: relative;
  left: 0;
  top: 0;
  box-sizing: border-box;
}

.brands-brand {
  transition: all 0.6s ease;
  display: inline-block;
  z-index: 1;
  width: 10%;
  font-size: medium;
  font-size: initial;
  padding-left: 10px;
  padding-right: 10px;
  border: 1px solid red;
  box-sizing: border-box;
  }
  
  img {
    width: 100%;
    height: 150px;
    object-fit: contain;
  }

<div id="slider" class="brands-wrapper ">
  <div id="wrapper" class="brands-slide animate">
    <div class="brands-brand">
        <img src="http://via.placeholder.com/91x90" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/91x100" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/491x200" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/191x300" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/150x200" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/150x100" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/41x70" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/91x70" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/150x150" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/91x70" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/77x77" alt="brandname" />
    </div>
    <div class="brands-brand">
        <img src="http://via.placeholder.com/88x88" alt="brandname" />
    </div>
  </div>
</div>

<button onclick="myFunctionPrev()">
    Prev
</button>
<button onclick="myFunctionNext()">
Next
</button>
&#13;
&#13;
&#13;

这是我尝试过的其他一些方法的小提琴,但到目前为止还没有任何方法:https://jsfiddle.net/Sirence/rbdLgso7/19/

理想的解决方案是动画像两者一样流畅,但没有重叠。虽然两个动画都表现相同已经很好了。

1 个答案:

答案 0 :(得分:1)

当快速按下Next / Prev按钮时,javascrpit会在CSS转换有机会完成之前改变DOM。当向右滚动时,这会导致异步转换。向左滚动时,在转换完成之前,最左边的元素(仍处于边距转换过程中)将从DOM中移除,因此新的最左边的元素将捕捉到位置。在最左边的元素中没有更改CSS属性,因此不适用任何转换。

您应该能够通过向代码添加控制机制来实现目标,以确保在当前转换完成之前不会修改DOM。

如果将以下javascript添加到现有代码中,则应提供连续同步滚动的机制,直到达到所需的滚动目标。

var animation = 0;                              // Which way and how many tiles to rotate
var animate_active = false;                     // Run status

window.myFunctionStart = function() {
    if ( !animate_active ) {                    // Do not start if already running
        setTimeout(myFunctionAnimate, 1);       // Start callback
        animate_active = true;                  // Sets running flag
    }
}

window.myFunctionAnimate = function() {
    if ( animation < 0 ) {                      // If direction = Prev
        myFunctionPrev();                       // Execute transition
        animation += 1;                         // Itterate towards 0
        setTimeout(myFunctionAnimate, 600);     // Continue callback at 0.6s intervals ( should match css transition )
    }
    else if ( animation > 0 ) {                 // If direction = Next
        myFunctionNext();                       // Execute transition
        animation -= 1;                         // Itterate towards 0
        setTimeout(myFunctionAnimate, 600);     // Continue callback at 0.6s intervals ( should match css transition )
    }
    else animate_active = false;                // If no more animations required, stop callback
}

要使用此代码,下一个和上一个按钮应如下所示。

<button onclick="animation -= 1; myFunctionStart();">Prev</button>
<button onclick="animation += 1; myFunctionStart();">Next</button>

您可能还希望将CSS转换从ease更改为linear,否则转换将不会稳定。