乐趣区

关于javascript:如何使用JavaScript实现无缝滚动-自动播放轮播图效果

在一些我的项目开发中,咱们常常须要应用到轮播图,然而没有深刻学习的状况下做轮播图是十分艰难的。

思路

分成小问题来解决

1. 动静生成序号 12345


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

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

2.1 给序号注册 onclick 事件
2.2 勾销其余序号高亮显示,让以后点击的序号高亮显示
2.3 点击序号,动画的形式切换到以后点击的图片地位(设置自定义属性,记录以后索引,有了索引就可用动画进行挪动)

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

onmouseenteronmouseleave

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

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);
 }
退出移动版