在一些项目开发中,我们经常需要使用到轮播图,但是没有深入学习的情况下做轮播图是非常困难的。
image.png

思路

分成小问题来解决

1. 动态生成序号12345

image.png
页面有多少li(图片),就有多少序号

2. 点击序号、显示高亮、切换图片

2.1 给序号注册onclick事件
2.2 取消其他序号高亮显示,让当前点击的序号高亮显示
2.3 点击序号,动画的方式切换到当前点击的图片位置(设置自定义属性,记录当前索引,有了索引就可用动画进行移动)
2.gif

3. 鼠标放到盒子上的时候显示左右箭头,移开时候隐藏

onmouseenteronmouseleave
1.gif

4. 实现左右箭头播放上一张下一张(无缝滚动)

3.gif

5. 隔多少时间自动播放

setIntervalelement.click()联合即可实现

代码:

index.html:

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            * {
                padding: 0;
                margin: 0;
                list-style: none;
                border: 0;
            }

            body {
                margin: 0;
                background-color: rgb(55, 190, 89);
            }

            .all {
                width: 500px;
                height: 200px;
                padding: 4px;
                margin: 100px auto;
                position: relative;
                background-color: #fff;
                border-radius: 20px;
            }

            .screen {
                width: 500px;
                height: 200px;
                border-radius: 17px;
                overflow: hidden;
                position: relative;
            }

            .screen li {
                width: 500px;
                height: 200px;
                overflow: hidden;
                float: left;
            }

            .screen ul {
                position: absolute;
                left: 0;
                top: 0px;
                width: 3000px;
            }

            .all ol {
                position: absolute;
                right: 180px;
                bottom: 10px;
                line-height: 20px;
                text-align: center;
            }
            
            .all ol li {
                float: left;
                width: 20px;
                height: 20px;
                background: #fff;
                border-radius: 10px;
                border: 1px solid #ccc;
                margin-left: 10px;
                cursor: pointer;
                opacity: 0.5;
                /* 透明度 */
            }

            .all ol li.current {
                opacity: 1.0;
            }

            #arr {
                display: none;
                z-index: 1000;

            }

            #arr span {
                width: 40px;
                height: 40px;
                position: absolute;
                left: 5px;
                top: 50%;
                margin-top: -20px;
                background: #000;
                cursor: pointer;
                line-height: 40px;
                text-align: center;
                font-weight: bold;
                font-family: '黑体';
                font-size: 30px;
                color: #fff;
                opacity: 0.5;
                border: 1px solid #fff;
                border-radius: 5px;
            }

            #arr #right {
                right: 5px;
                left: auto;
            }
        </style>
    </head>

    <body>
        <div class="all" id='box'>
            <div class="screen">
                <ul>
                    <li><img src="images/wf1.jpg" width="500" height="200" /></li>
                    <li><img src="images/wf2.jpg" width="500" height="200" /></li>
                    <li><img src="images/wf3.jpg" width="500" height="200" /></li>
                    <li><img src="images/wf4.jpg" width="500" height="200" /></li>
                    <li><img src="images/wf5.jpg" width="500" height="200" /></li>
                </ul>
                <ol>
                </ol>
            </div>
            <div id="arr"><span id="left">&lt;</span><span id="right">&gt;</span></div>
        </div>
        <script src="common.js"></script>
        <script src="animate.js"></script>
        <script src="index.js"></script>
    </body>

</html>

index.js

//获取元素
var box = my$('box');
var screen = box.children[0];
var ul = screen.children[0];
var ol = screen.children[1]
//获取箭头
var arr = my$('arr');
var arrLeft = my$('left');
var arrRight = my$('right');
var count = ul.children.length; /* 获取图片数量  还没有放cloneLi,所以数值是5*/
var imgWidth = screen.offsetWidth; /* 获取的图片(盒子)的宽高 */
//1.动态生成序号
for (i = 0; i < count; i++) {
    // 在ol内创建li
    var li = document.createElement('li');
    ol.appendChild(li);
    // li内赋予数值
    setInnerText(li, i + 1);
    li.onclick = liClick;
    // 设置标签的自定义属性(创建索引)
    li.setAttribute('index', i);
}

// 2.点击序号,切换,显示高亮
function liClick() {
    // 取消其他的li的高亮,显示当前li高亮
    for (i = 0; i < ol.children.length; i++) {
        var li = ol.children[i];
        li.className = '';
        this.className = 'current';
    }

    // 获取的自定义属性是字符串类型,要转成整数
    var liIndex = parseInt(this.getAttribute('index'));
    animate(ul, -liIndex * imgWidth);
    //使得后面定义的全局变量index等于li的属性liIndex
    index = liIndex;
}

//ol内的第一个li显示高亮色
ol.children[0].className = 'current';

//3.鼠标放上去的时候显示箭头
// onmouseover和onmouseout会触发事件冒泡;onmouseleave和onmouseenter不会触发事件冒泡
box.onmouseenter = function () {
    arr.style.display = 'block';
    clearInterval(timeId);
}

box.onmouseleave = function () {
    arr.style.display = 'none';
    timeId = setInterval(function () {
        arrRight.click();
    }, 2500)
}

// 4.实现上一张,下一张的功能   
var index = 0; //第一张图片的索引

arrRight.onclick = function () {
    //  判断是否是克隆的第一张图片,如果是克隆的第一张图片,此时修改ul的坐标,显示真正的第一张图片
    if (index === count) {
        ul.style.left = '0px';
        index = 0;
    }


    // 如果是最后一张图片,不让index++
    index++;
    // 有5张图片,但是还有一张克隆的图片,克隆图片索引是5
    if (index < count) {
        //获取图片对应的序号,让序号进行点击
        ol.children[index].click();
    } else {
        animate(ul, -index * imgWidth);
        // 取消所有的高亮现实,让第一个序号高亮显示
        for (var i = 0; i < ol.children.length; i++) {
            var li = ol.children[i];
            li.className = '';
        }
        ol.children[0].className = 'current';
    }

    // 
}

arrLeft.onclick = function () {
    if (index === 0) {
        index = count;
        ul.style.left = -index * imgWidth + 'px';
    }
    index--;
    ol.children[index].click();
}

// 无缝滚动
var firstLi = ul.children[0];
// 克隆li    
//cloneNode() 复制节点:参数 true 复制节点中的内容 ;false 只复制当前节点,不复制里面的内容
var cloneLi = firstLi.cloneNode(true);
ul.appendChild(cloneLi)


// 5.自动播放
var timeId = setInterval(function () {
    //  切换到下一张图片
    arrRight.click();
}, 2500)

common.js

function my$(id) {
    return document.getElementById(id);
  }
  
  // 处理浏览器兼容性
  // 获取第一个子元素
  function getFirstElementChild(element) {
      var node, nodes = element.childNodes, i = 0;
      while (node = nodes[i++]) {
          if (node.nodeType === 1) {
              return node;
          }
      }
      return null;
  }
  
  // 处理浏览器兼容性
  // 获取下一个兄弟元素
   function getNextElementSibling(element) {
      var el = element;
      while (el = el.nextSibling) {
        if (el.nodeType === 1) {
            return el;
        }
      }
      return null;
    }
  
  
  // 处理innerText和textContent的兼容性问题
  // 设置标签之间的内容
  function setInnerText(element, content) {
    // 判断当前浏览器是否支持 innerText
    if (typeof element.innerText === 'string') {
      element.innerText = content;
    } else {
      element.textContent = content;
    }
  }
  
  // 处理注册事件的兼容性问题
  // eventName, 不带on,  click  mouseover  mouseout
  function addEventListener(element, eventName, fn) {
    // 判断当前浏览器是否支持addEventListener 方法
    if (element.addEventListener) {
      element.addEventListener(eventName, fn);  // 第三个参数 默认是false
    } else if (element.attachEvent) {
      element.attachEvent('on' + eventName, fn);
    } else {
      // 相当于 element.onclick = fn;
      element['on' + eventName] = fn;
    }
  }
  
  // 处理移除事件的兼容性处理
  function removeEventListener(element, eventName, fn) {
    if (element.removeEventListener) {
      element.removeEventListener(eventName, fn);
    } else if (element.detachEvent) {
      element.detachEvent('on' + eventName, fn);
    } else {
      element['on' + eventName] = null;
    }
  }
  
  // 获取页面滚动距离的浏览器兼容性问题
  // 获取页面滚动出去的距离
  function getScroll() {
    var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    return {
      scrollLeft: scrollLeft,
      scrollTop: scrollTop
    }
  }
  
  // 获取鼠标在页面的位置,处理浏览器兼容性
  function getPage(e) {
    var pageX = e.pageX || e.clientX + getScroll().scrollLeft;
    var pageY = e.pageY || e.clientY + getScroll().scrollTop;
    return {
      pageX: pageX,
      pageY: pageY
    }
  }
  
  
  //格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
  function formatDate(date) {
    // 判断参数date是否是日期对象
    // instanceof  instance 实例(对象)   of 的
    // console.log(date instanceof Date);
    if (!(date instanceof Date)) {
      console.error('date不是日期对象')
      return;
    }
  
    var year = date.getFullYear(),
        month = date.getMonth() + 1,
        day = date.getDate(),
        hour = date.getHours(),
        minute = date.getMinutes(),
        second = date.getSeconds();
  
    month = month < 10 ? '0' + month : month;
    day = day < 10 ? '0' + day : day;
    hour = hour < 10 ? '0' + hour : hour;
    minute = minute < 10 ? '0' + minute : minute;
    second = second < 10 ? '0' + second : second;
  
    return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
  }
  
  // 获取两个日期的时间差
  function getInterval(start, end) {
    // 两个日期对象,相差的毫秒数
    var interval = end - start;
    // 求 相差的天数/小时数/分钟数/秒数
    var day, hour, minute, second;
  
    // 两个日期对象,相差的秒数
    // interval = interval / 1000;
    interval /= 1000;
  
    day = Math.round(interval / 60 / 60 / 24);
    hour = Math.round(interval / 60 / 60 % 24);
    minute = Math.round(interval / 60 % 60);
    second = Math.round(interval % 60);
  
    return {
      day: day,
      hour: hour,
      minute: minute,
      second: second
    }
  }

animate.js

// var timerId = null;
// 封装动画的函数
function animate(element, target) {
    // 通过判断,保证页面上只有一个定时器在执行动画
   if (element.timerId) {
     clearInterval(element.timerId);
     element.timerId = null;
   }
 
   element.timerId = setInterval(function () {
     // 步进  每次移动的距离
     var step = 10;
     // 盒子当前的位置
     var current = element.offsetLeft;
     // 当从400 到 800  执行动画
     // 当从800 到 400  不执行动画
 
     // 判断如果当前位置 > 目标位置 此时的step  要小于0
     if (current > target) {
       step = - Math.abs(step);
     }
 
     // Math.abs(current - target)   <= Math.abs(step)
     if (Math.abs(current - target)   <= Math.abs(step)) {
       // 让定时器停止
       clearInterval(element.timerId);
       // 让盒子到target的位置
       element.style.left = target + 'px';
       return;
     }
     // 移动盒子
     current += step;
     element.style.left = current + 'px';
   }, 5);
 }

FredLiu
182 声望5 粉丝

喜欢画画