主要思路

image.png
我们需要一个动画函数,他能向左或者向右移动;
当取最后的一个临界的时候,(比如6转向1,将屏幕快速切换到最左边的6)再调用函数动画。
总体预览链接

主要知识点

初始化操作

元素获取

  1. //主要操作动画的元素和每页元素的宽度
  2. let target = document.getElementById("main");
  3. let target_Width = document.getElementById("container").offsetWidth;
  4. // 三个主要的事件
  5. let icon = document.getElementsByClassName('icon')[0];
  6. let preEle = document.getElementsByClassName("pre")[0];
  7. let nextEle = document.getElementsByClassName("next")[0];

全局变量

  1. let currentIndex = 1;
  2. let iconsIndex = 1;
  3. let time,
  4. globTime ; // 全局定时器
  • 这里我们希望他能动态的根据元素的多少创建原点,
  • 并且为ul元素设置总体的宽度
  • 由于我们为了结构在ul的头部多设置了一个li所以需要设置他的left值; ``` (function(){
    1. target.style.width = target.children.length * target_Width + 'px';
    2. let str = "";
    3. for (let i =0 ;i< target.children.length - 2; i++){
    4. str += `<div class="icons"><div class="a" data-value = ${i}></div></div>`;
    5. }
    6. icon .innerHTML = str;
    7. icon.children[currentIndex - 1].children[0].classList.add("active")
    })();
  1. <a name="S3Dna"></a>
  2. ### 通过类名操控显示的下标

let addIconClass = function(){ icon.children[iconsIndex -1].children[0].classList.remove(‘active’); icon.children[currentIndex -1].children[0].classList.add(“active”); iconsIndex = currentIndex; };

  1. <a name="BaX4x"></a>
  2. ### animation动画实现
  3. 我们不用定义往左或者往右,只需要给出目标的index值就可以了;
  1. /**
  2. * 动画
  3. * @param index 元素的索引
  4. */
  5. let animation = function (index) {
  6. clearInterval(globTime);
  7. let start = parseInt(target.style.left);
  8. let move = 0;
  9. let total = - parseFloat(target.style.left) - index * target_Width;
  10. let step = Math.ceil(total / 100);
  11. addIconClass();
  12. console.log( target.style.left);
  13. clearInterval(time);
  14. // debugger;
  15. time = setInterval(function () {
  16. move += step;
  17. if(Math.abs(move) > Math.abs(total)){
  18. // console.log(move , total);
  19. target.style.left = total + start +'px';
  20. clearInterval(time);
  21. globTime = setInterval(moveRight,2000)
  22. }else {
  23. target.style.left = move + start +'px';
  24. }
  25. },16);
  26. };
  1. <a name="EmvZ3"></a>
  2. ### 三个控件触发器
  3. 这里我们将向左的动画抽取出来留作全局的自动播放复用;
  4. <a name="UoB6k"></a>
  5. #### pre
  1. let moveLeft = function(){
  2. if (currentIndex === 1){
  3. currentIndex = target.children.length - 1;
  4. target.style.left = -(currentIndex * target_Width) + 'px';
  5. }
  6. animation( -- currentIndex);
  7. };
  8. preEle.addEventListener('click',moveLeft);
  1. <a name="rRlGK"></a>
  2. #### next
  1. let moveRight = function () {
  2. if (currentIndex === target.children.length - 2){
  3. currentIndex = 0;
  4. target.style.left = -(currentIndex * target_Width) + 'px';
  5. }
  6. animation(++ currentIndex);
  7. };
  8. nextEle.addEventListener('click',moveRight);
  1. <a name="cYr5r"></a>
  2. #### icon
  1. icon.addEventListener("click",function (e) {
  2. if (e.target['className'] === 'a'){
  3. currentIndex = parseInt(e.target['dataset'].value) + 1;
  4. animation(currentIndex)
  5. }
  6. });

```

自动播放

globTime = setInterval( moveRight,2000)

真正的妙用不是函数的复用;而是在animation动画那;
如果我们设置一个全局的定时器,让他每隔2s执行一次;那么我们就会发现一个问题;当我们点击一个按钮后定时器还在执行;那我们就会想到在每个函数的开始清空定时器然后函数执行完成再开启它,既然他们都是由animation一起工作的,那么为什么不放在一起呢;这时实际的动画世间就是2s+动画时间,同样的每次操作都会使得icon的下标改变,那么也可以将改变下标的操作一起放到animation中;