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

原生 JS 实现轮播图

程序员文章站 2024-03-17 11:10:58
...

先来看最终完成效果图 :

原生 JS 实现轮播图

一、搭建 HTML 静态页面

<!-- 外层父容器 -->
<div id="container">
    <!-- 图片容器 -->
    <div id="list">
        <img src="imgs/slide_bg1.jpg" alt="">
        <img src="imgs/slide_bg2.jpg" alt="">
        <img src="imgs/slide_bg3.jpg" alt="">
        <img src="imgs/slide_bg4.jpg" alt="">
    </div>
    <>
    <!-- 底部圆点导航 -->
    <div id="buttons">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <!-- 箭头按钮 -->
    <a href="javascript:;" class="arrow" id="prev">&lt;</a>
    <a href="javascript:;" class="arrow" id="next">&gt;</a>
</div>

二、设置 CSS 样式

1.设置容器、图片宽高

  • container 容器宽度设置为与图片宽度相同,刚好足够显示一张图片
  • list 容器宽度要设置为 图片宽度*图片数量 ,这样才足够放下所有图片
#container {
    width: 800px;
    height: 600px;
}

#list {
    width: 4800px;
    height: 600px;
}

#list img {
    width: 800px;
    height: 600px;
}

2.设置图片浮动

  • 给图片设置浮动,使所有图片无缝排列
#list img {
    float: left;
}
  • 给 container 容器设置 overflow 属性, 隐藏多余图片
#container {
    overflow: hidden;
}

3.设置圆点按钮样式

  • 设置定位,将按钮容器水平居中
#container {
    position: relative;
}

#buttons {
    positon: absolute;
    left: 50%;
    bottom: 8%;
    transform: translateX(-50%);
}
  • 设置按钮为 inline-block , 并在父容器中水平居中
#buttons span {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    float: left;
    margin-left: 10px;
    cursor: pointer;
}
  • 设置圆点按钮其他样式
#buttons span {
    box-sizing: border-box;
    background-color: transparent;
    border: 1px solid #fff;
}

#buttons span:hover {
    background-color: #fff;
}

4.设置箭头按钮样式

.arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    text-decoration: none;
    font-size: 48px;
    color: #337ab7;
}

#prev {
    left: 20px;
}

#next {
    right: 20px;
}

CSS 完整代码 :

* {
    margin: 0;
    padding: 0;
}

#container {
    width: 800px;
    height: 600px;
    overflow: hidden;
    position: relative;
    margin: 0 auto;
}

#list {
    width: 4800px;
    height: 600px;
    position: absolute;
    margin-left: -800px;
}

#list img {
    width: 800px;
    height: 600px;
    float: left;
}

#buttons {
    width: 100px;
    height: 10px;

    position: absolute;
    left: 50%;
    bottom: 8%;
    transform: translateX(-50%);
}

#buttons span {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: transparent;
    box-sizing: border-box;
    border: 1px solid #fff;
    float: left;
    margin-left: 10px;
    cursor: pointer;
}

#buttons span:hover {
    background-color: #fff;
    opacity: 0.2;
}

#buttons .on {
    background-color: #fff;
}

.arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    text-decoration: none;
    font-size: 48px;
    color: #337ab7;
}

.arrow:hover {
    color: #23527c;
}

#prev {
    left: 20px;
}

#next {
    right: 20px;
}

三、JS 动态交互页面

思路:
(1) 封装 move () 函数 , 设置定时器 , 周期调用 move () , 使图片产生滑动过渡效果
(2) 判定当前图片下标 , 将标识当前图片的圆点导航 class 设置为 “active”
(3)

  • 在开始进行动态页面编写之前,首先获取到页面中所有元素节点
var container = document.getElementById('container');
var list = document.getElementById('list');
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');

1.实现箭头按钮切换图片

思路 :

  • 获取显示区域宽度, 点击左右箭头时, 偏移量 = 显示区域宽度
  • 实现循环切换
// 移动
function move (offset) {
    var oldLeft = parseInt(list.style.left);    // 原始位置
    var newLeft = oldLeft + offset;     //新位置

    if (newLeft > 0) {
        newLeft = - (pics.length - 3) * pic.width;
    } else if (newLeft < - (pics.length - 3) * pic.width) {
        newLeft = 0;
    }

    list.style.left = newLeft + 'px';
}

// 下一张
next.onclick = function () {
    move(-pic.width);
}

//上一张
prev.onclick = function () {
    move(pic.width);
}

2.实现圆点导航按钮切换

1)圆点导航显示

思路:

  • 给出标识位 index , 记录当前图片标号
  • 修改箭头按钮函数
  • 设置 index 位置上的圆点 class = ‘on’
// 圆点导航显示
function showButtons () {
    for(let i = 0 ; i < buttons.length ; i++){
        if (buttons[i].className == 'on') {
            buttons[i].className = '';
            break;
        }
    }
    buttons[index - 1].className = 'on';
}

// 下一张
next.onclick = function () {
    move(-pic.width);
    index++;
    if (index > buttons.length) {
        index = 1;
    }
    showButtons();
}

//上一张
prev.onclick = function () {
    move(pic.width);
    index--;
    if (index < 1) {
        index = buttons.length;
    }
    showButtons();
}

2)圆点导航切换

  • 计算当前位置与目标位置偏移量之差
  • 调用 move () 方法
// 圆点导航切换
for(let i = 0; i < buttons.length ; i++){
    buttons[i].id = i+1;
    buttons[i].onclick = function () {
        // 偏移量 = 点击位置 - 当前位置
        var offLen = this.id - index;
        // 如果未发生偏移, 返回
        if (!offLen) {
            return;
        }
        console.log(offLen);
        // 这里偏移量为 '-'
        move(- offLen * pic.width);
        // 将当前图片标号 index 更新为点击按钮标号
        index = this.id;
        showButtons();
    }
}

3. 动画过渡

  • 设定位移总时间
  • 设定位移间隔时间
  • 计算 每次所需偏移量 = 总宽度 / (偏移时间);
  • 偏移函数 go () : 在未到达目标位置时,进行移动
  • 设置定时器,在位移间隔内调用偏移函数 go ()

根据以上 修改 move () 方法

// 移动
function move (offset) {
    var oldLeft = parseInt(list.style.left);    // 原始位置
    var newLeft = oldLeft + offset;     //新位置
    var time = 300;     //位移总时间
    var interval = 10;  //位移间隔时间
    var speed = offset / (time/interval);

    var timer = setInterval(go,interval);
    function go () {
        var currentLeft = parseInt(list.style.left);
        if ((speed<0 && currentLeft>newLeft) || (speed>0 && currentLeft<newLeft)) {
            list.style.left = parseInt(list.style.left) + speed + 'px';
        }else {
            clearInterval(timer);
            if (newLeft > 0) {
                newLeft = - (pics.length - 3) * pic.width;
            } else if (newLeft < - (pics.length - 3) * pic.width) {
                newLeft = 0;
            }
            list.style.left = newLeft + 'px';
        }
    }
}

4. 自动播放

  • 设置定时器, 在鼠标无动作时调用 move ()
  • 鼠标划过时, 清除定时器
var timer;
// 自动播放
function autoPlay () {
    move(-pic.width);
    index++;
    if (index>buttons.length) {
        index = 1;
    }
    showButtons();
}
list.onmouseover = function () {
    clearInterval(timer);
}
list.onmouseout = function () {
    timer = setInterval(autoPlay,3000);
}
timer = setInterval(autoPlay,3000);

JS 完整代码 :

/*

思路:
(1) 实现箭头按钮切换
    1) 获取显示区域宽度, 点击左右箭头时, 偏移量 = 显示区域宽度
    2) 实现循环切换
(2) 实现圆点导航显示
    1) 给出标识位 index = 1, 点击左右箭头时, 对 index 进行加减
    2) 设置 index 位置上的圆点 class = 'on'
(3) 实现圆点导航切换
    1) 计算当前位置与目标位置偏移量之差
    2) 调用 move () 方法
(4) 动画过渡, 修改 move () 方法
    1) 设定位移总时间
    2) 设定位移间隔时间
    3) 计算 每次所需偏移量 = 总宽度 / (偏移时间);
(5) 自动播放
    1) 设置定时器, 在鼠标无动作时调用 move ()
    2) 鼠标划过时, 清除定时器

*/

window.onload = function () {

    var container = document.getElementById('container');
    var list = document.getElementById('list');
    var pics = list.getElementsByTagName('img');
    var pic = pics[0];
    var buttons = document.getElementById('buttons').getElementsByTagName('span');
    var prev = document.getElementById('prev');
    var next = document.getElementById('next');
    var index = 1;

    // 移动
    function move (offset) {
        var oldLeft = parseInt(list.style.left);    // 原始位置
        var newLeft = oldLeft + offset;     //新位置
        var time = 300;     //位移总时间
        var interval = 10;  //位移间隔时间

        var speed = offset / (time/interval);

        var timer = setInterval(go,interval);
        function go () {
            var currentLeft = parseInt(list.style.left);
            if ((speed<0 && currentLeft>newLeft) || (speed>0 && currentLeft<newLeft)) {
                list.style.left = parseInt(list.style.left) + speed + 'px';
            }else {
                clearInterval(timer);
                if (newLeft > 0) {
                    newLeft = - (pics.length - 3) * pic.width;
                } else if (newLeft < - (pics.length - 3) * pic.width) {
                    newLeft = 0;
                }
                list.style.left = newLeft + 'px';
            }
        }
    }

    // 圆点导航显示
    function showButtons () {
        for(let i = 0 ; i < buttons.length ; i++){
            if (buttons[i].className == 'on') {
                buttons[i].className = '';
                break;
            }
        }
        buttons[index - 1].className = 'on';
    }

    // 下一张
    next.onclick = function () {
        move(-pic.width);
        index++;
        if (index > buttons.length) {
            index = 1;
        }
        showButtons();
    }

    //上一张
    prev.onclick = function () {
        move(pic.width);
        index--;
        if (index < 1) {
            index = buttons.length;
        }
        showButtons();
    }

    // 圆点导航切换
    for(let i = 0; i < buttons.length ; i++){
        buttons[i].id = i+1;
        buttons[i].onclick = function () {
            // 偏移量 = 点击位置 - 当前位置
            var offLen = this.id - index;
            if (!offLen) {
                return;
            }
            move(-offLen * pic.width);
            index = this.id;
            showButtons();
        }
    }

    var timer;
    // 自动播放
    function autoPlay () {
        move(-pic.width);
        index++;
        if (index>buttons.length) {
            index = 1;
        }
        showButtons();
    }
    list.onmouseover = function () {
        clearInterval(timer);
    }
    list.onmouseout = function () {
        timer = setInterval(autoPlay,3000);
    }
    timer = setInterval(autoPlay,3000);
}