轮播图的多种实现及原理

2 篇文章 1 订阅
2 篇文章 2 订阅

【写在前面】

        最近,在自己的项目中遇到了很多轮播图。

        当然,这里的很多,并非数量多,指的是种类很多,即多种实现。

        然后我觉得有不少小技巧,就决定写一篇文章讲解一下。

        本篇主要内容:

        1、轮播图的多种实现( 含动态图 )。

        2、效果对比和更好的建议。


【正文开始】

  • 实现一

        相当常见且简单的实现方法:

        1、将所有的图片并排。

        2、依次平移即可。

        HMTL 和 CSS部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图</title>
    <style>
        ul,
        ol {
            list-style: none;
            padding: 0px;
            margin: 0px;
        }

        #main {
            width: 600px;
            height: 350px;
            margin: 30px auto;
            position: relative;
        }

        #display {
            width: 600px;
            height: 350px;
            overflow: hidden;
            position: relative;
            -webkit-user-select: none;
        }

        #display ul {
            position: relative;
            left: 0;
            top: 0px;
            width: 3600px;
            height: 350px;
            transition: left 500ms linear;
        }

        #list li {
            float: left;
            width: 600px;
            height: 350px;
        }

        #arrow {
            display: none;
        }

        #arrow span {
            position: absolute;
            width: 40px;
            height: 40px;
            line-height: 40px;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            cursor: pointer;
            text-align: center;
            font-weight: bold;
            font-family: 黑体, SimHei;
            font-size: 30px;
            color: #fff;
            opacity: 0.4;
            border: 1px solid #fff;
            -webkit-user-select: none;
        }

        #arrow span:hover {
            opacity: 0.7;
        }

        #arrow #right {
            right: 5px;
            left: auto;
        }

        #index_container {
            position: absolute;
            width: 210px;
            height: 30px;
            right: 20px;
            bottom: 20px;
        }

        #index_container .index {
            float: left;
            width: 30px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            opacity: 0.8;
            background: #fff;
            border: 1px solid #ccc;
            margin-left: 10px;
            cursor: pointer;
            -webkit-user-select: none;
        }

        #index_container .current {
            background: #ec3d3d;
        }
    </style>
    <script>
    </script>
</head>
<body>
    <div id="main">
        <div id="display">
            <ul id="list">
                <li><img src="images/0.jpg" width="600" height="350"/></li>
                <li><img src="images/1.jpg" width="600" height="350"/></li>
                <li><img src="images/2.jpg" width="600" height="350"/></li>
                <li><img src="images/3.jpg" width="600" height="350"/></li>
                <li><img src="images/4.jpg" width="600" height="350"/></li>
            </ul>
            <ol id="index_container"></ol>
            <div id="arrow">
                <span id="left" title="前一张"><</span>
                <span id="right" title="后一张">></span>
            </div>
        </div>
    </div>
</body>
</html>

        其中 <script> 部分: 

window.onload = () => {
    let list = document.getElementById('list');
    let ol = document.getElementsByTagName('ol')[0];
    let display = document.getElementById('display');
    let currentIndex = 0;
    let autoPlay = () => {
        window.autoPlay = true;
        window.autoPlayTimer = setInterval(() => move((currentIndex + 1) % 5), 2000);
    }
    let stopPlay = () => {
        if (window.autoPlay) {
            window.autoPlay = false;
            clearInterval(window.autoPlayTimer);
        }
    }
    //创建索引按钮
    for (let i = 0; i < 5; i++) {
        let li = document.createElement('li');
        li.textContent = String(i + 1);
        li.className = 'index';
        if (i == 0) li.className += ' current';
        li.index = i;
        ol.appendChild(li);
        li.addEventListener('mouseover', function() {
            move(this.index);
            stopPlay();
        });
    }
    let arrow = document.getElementById('arrow');
    let showArrow = () => arrow.style.display = 'block';
    let hideArrow = () => arrow.style.display = 'none';
    //核心move函数
    let move = (index) => {
        let width = display.offsetWidth;
        for (let i = 0; i < 5; i++) {
            //改变当前索引按钮
            if ((index % 5) === i) {
                ol.children[i].className = 'index current';
            } else ol.children[i].className = 'index';
        }
        //移动lists
        list.style.left = (-index) * width + 'px';
        currentIndex = index;
    }
    display.addEventListener('mouseover', showArrow)
    display.addEventListener('mouseleave', () => {
        hideArrow();
        if (!window.autoPlay) {
            //重新开始自动播放
            autoPlay();
        }
    })
    
    let left = document.getElementById('left');
    let right = document.getElementById('right');
    left.addEventListener('click', () => {
        move((currentIndex - 1) === -1 ? 4 : currentIndex - 1);
        stopPlay();
    });
    right.addEventListener('click', () => {
        move((currentIndex + 1) % 5);
        stopPlay();
    });

    //启动自动播放
    move(0);
    autoPlay();
}

        关键部分为 move() 函数,即平移整个轮播图像列表( 根据跳转索引 index )。

        效果如下:

  • 实现二( 代码见结语 ):

        1、将所有图片叠在一起。

        2、如果为当前图片则设置 ( z-index ),使其在最顶层。

        3、使用 opacity 过渡代替方法一中的平移过渡( left ):

        效果如下:

  •  实现三:

        先来看看去掉 overflow: hidden 后的效果:

        1、将所有图像复制一轮后并排。

        2、同方法一,依次平移。

        3、重要:平移一轮到复制的图像的第一张[ 结束后 ] ,立即将 left 设置为 0px ( 我这里用了 jquery,也可不用 )

        效果如下:


【结语】

        呼~偷了个懒,实现一和实现二的代码在:GitHub - mengps/Web-jx: 模仿京东首页,纯css3+h5+js+jq

        话说这个项目有相当多的小技巧( css3 和 js ),请多多 star 呀..⭐_⭐

        最后来总结一下:

        实现一:优点是简单缺点是不够连贯,且首尾没有无缝滚动

        实现二:优点是过渡平滑,相隔几个切换也相当丝滑缺点是不够好看,视觉效果差了点

        实现三:优点是无缝滚动,也相当丝滑基本没有什么缺点

  • 62
    点赞
  • 297
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦起丶

您的鼓励和支持是我创作最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值