欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

轮播图的多种实现及原理

程序员文章站 2022-06-24 17:45:35
【写在前面】最近,在自己的项目中遇到了很多轮播图。这里的很多,并非数量多,指的是种类很多,即多种实现。本篇主要内容:1、轮播图的多种实现。2、效果对比和更好的建议。【正文开始】方法一:相当常见简单的实现方法:1、将所有的图片并排。2、依次平移即可。HMTL 和 CSS部分: ...

【写在前面】

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

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

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

本篇主要内容:

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,也可不用 )

效果如下:

轮播图的多种实现及原理


【结语】

呼~偷了个懒,实现一和实现二的代码在:https://github.com/mengps/Web-jx

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

最后来总结一下:

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

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

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

本文地址:https://blog.csdn.net/u011283226/article/details/111873683