JavaScript轮播图(面向对象)

步骤

轮播图1 HTML+CSS

轮播图2 动态生成页面

通过 JavaScript程序 生成 div标签中 所有 轮播图需要的标签

生成 ul ol div 标签节点

根据数组动态生成 原始 ul>li  ol>li

ul > li > img

ol > li

第一个li添加 class,active

将生成的 ul>li ol>li 字符串 写入 ul ol 标签节点

将 ul ol div 标签节点 写入 轮播图div中

获取 原始 ul>li ol>li 标签对象

克隆 第一个ul>li 和 最后一个 ul>li

将 克隆的第一个ul>li 写入 ul末位

将 克隆的最后一个ul>li 写入 ul起始

重新设定ul宽度

是 当前li个数 * li宽度

默认显示 原始轮播图的第一张 也就是 克隆写入之后的 第二个li

ul 默认 向左 定位 一个li宽度

轮播图3 自动轮播

通过 move() 运动函数 以动画效果完成ul标签定位的切换

自动轮播函数

定义一个全局变量 用于 存储 显示li标签的索引下标

初始值 是 1

通过 修改 变量中 的的数值 表示 显示的 li标签

也就是 通过 修改变量中存储的数值 控制 轮播图的执行

定义定时器

变量定义数值累加1

设定 焦点按钮的样式

设定 ul定位的数值

负的 当前显示的li标签 索引下标 * li宽度

通过 move() 运动函数 来 执行 ul标签定位的改变

move( ul标签 , { left : 负的index数值乘以li宽度 } , 运动结束触发的回调函数 )

焦点按钮设定函数

清除 所有的 ol>li 样式

给 显示的ul>li 对应的 ol>li 添加样式

如果 显示 当前ul>li的最后一个 给 第一个ol>li 添加样式

如果 是其他情况

给 显示的ul>li 索引下标 -1 对应的 ol>li 添加样式

ul切换运动终止的回调函数

如果 显示当前ul>li的最后一个

运动结束 给 index 赋值 1

也就是 要显示 当前ul>li的第二个

通过css样式设定 瞬间完成 ul定位的切换

ul标签对象.style.left = -index * li宽度 + 'px'

轮播图4 鼠标移入移出

给 轮播图div标签 添加事件

鼠标移入

终止轮播图的自动运行

也就是 清除  自动轮播 定时器

鼠标移出

再次执行轮播图的自动轮播

也就是 再次调用 autoLoop() 自动轮播函数

轮播图5 点击事件

给 一直存在的轮播图div添加点击事件

通过事件委托的语法形式 给标签添加点击事件

左右切换按钮

左切换按钮

显示上一次张

也就是 显示li标签索引下标 累减 1

根据 新的显示li标签的索引下标 定位ul标签

通过 move运动函数 运动完成 ul标签的定位切换

右切换按钮

显示下一次张

也就是 显示li标签索引下标 累加 1

根据 新的显示li标签的索引下标 定位ul标签

通过 move运动函数 运动完成 ul标签的定位切换

焦点按钮

显示 点击的 ol>li 对应的 ul>li 标签

也就是 ol>li 标签的索引下标 + 1

是 对应的 ul>li 标签的索引下标  

根据 新的显示li标签的索引下标 定位ul标签

通过 move运动函数 运动完成 ul标签的定位切换


 

轮播图6 防止点击过快

定义变量 存储默认值

触发点击事件 执行程序之前 先判断 变量储存的数据

如果是 原始值

变量赋值 其他数值 正常 执行之后的程序

如果是 其他数值

执行 return 终止 执行之后的程序

当 move() 运动函数执行结束 也就是 ul标签定位切换结束

给 变量 赋值 原始值true

可以执行下一次move()运动函数了

轮播图7 轮播图最小化隐藏

当 浏览器 最小化 / 隐藏 / 显示其他程序时

浏览器 会在 window操作系统 的 后台运行

浏览器 本身 不会触发执行任何程序

但是 浏览器中 JavaScript程序 会继续执行

也就是 autoLoop() 中的定时器 会自动继续执行

也就是 ul标签的定位 会被改变

解决方案:

浏览器最小化隐藏时

清除 定时器

浏览器显示时

再次 启动自动轮播函数

visibilitychange事件

添加个 document 的事件

浏览器显示状态监听事件

当浏览器显示状态改变时触发设定的函数程序

document.visibilityState

浏览器显示状态描述

hidden  

隐藏最小化状态

清除定时器

visible

显示状态

再次调用 自动轮播函数

代码(面向对象编程)

HTML部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./iconfont.ttf">
    <link rel="stylesheet" href="./iconfont.css">

    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        li{
            list-style: none;
        }
        a{
            text-decoration: none;
        }
        .banner{
            margin: auto;
            width: 1920px;
            height: 1030px;
            border: 2px solid red;
            position: relative;
            background-color: black;
            overflow: hidden;
        }
        .banner ul{
            width: 600%;
            height: 1030px;
            position: absolute;
            left: 0;
            top: 0;
        }
        .banner ul li{
            width: 1920px;
            height: 1030px;
            float: left;
        }
        .banner ol{
            width: 400px;
            height: 80px;
            position: absolute;
            bottom: 50px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgb(0, 0, 0,0.4);
            border-radius: 30px;
            display: flex;
            justify-content: space-around;
            align-items: center;
            cursor: pointer;
        }
        .banner ol li{
            width: 30px;
            height: 30px;
            margin: 20px;
            border-radius: 50%;
            background-color: white;
        }
        .banner div {
            padding: 0 30px;
            box-sizing: border-box;
            width: 100%;
            height: 80px;
            position: absolute;
            left: 0;
            top: 50%;
            transform: translateY(-100%);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .banner div a{
            font-size: 60px;
            color: white;
        }
        .banner ol .active{
            width: 45px;
            height: 45px;
            transition: 1s;
            background-color: red;
        }
        .banner div span{
            background-color: rgb(14, 13, 13,0.6);
            border-radius: 30%;
            box-sizing: border-box;
            display: block;
            padding: 20px 20px;
            transition: all 0.5s;
        }
        .banner div span:hover{
            background-color: red;
            font-size: 70px;
        }
    </style>
</head>
<body>
    <div class="banner"></div>
    <script src="./move.js"></script>
    <script src="./ind.js"></script>
    <script>
        //定义数组模拟后端传参
        const arr = [{url:'./image/1.png'},
                        {url:'./image/2.png'},
                        {url:'./image/6.png'},
                        {url:'./image/4.png'},
                        {url:'./image/5.png'}];
        const oBanner = document.querySelector(".banner");
        const obj = new CreateTabObj( oBanner , arr );
        // 入口函数调用
        obj.init();
    </script>
</body>
</html>

JavaScript部分

class CreateTabObj {
    constructor(elment, msgArr) {
        // 获取标签对象
        this.ele = elment;
        // 数组模拟数据库
        this.arr = msgArr;
        //创建ul ol div节点
        this.oUl;
        this.oOl;
        this.oDiv;
        this.liWidth;
        this.ulLis;
        this.olLis;
        this.time;
        this.index = 1;
        this.res = true;
    }

    // 入口函数
    // 在一个函数中调用所有需要执行的函数程序
    // 也就是 只要 调用一个函数 就调用了所有需要调用的函数
    // 入口函数 必须定义名称是 init
    init() {
        this.theTag();
        this.slideshow();
        this.theMouseMoves();
        this.theMouseClick();
        this.hide();
    }
    // 动态生成标签内容函数
    theTag() {
        //创建ul ol div节点
        this.oUl = document.createElement('ul');
        this.oOl = document.createElement('ol');
        this.oDiv = document.createElement('div');
        // 设定节点内容
        this.oDiv.innerHTML = '<a href="JavaScript:;"><span name="left" class="iconfont icon-zuofanye"></span></a><a href="JavaScript:;"><span name="right" class="iconfont icon-youfanye"></span></a>'
        //循环遍历数组动态写入内容
        let oUlstr = '';
        let oOlstr = '';
        this.arr.forEach(function (item, key) {
            // item 是 数组单元的数据数值 也就是 存储图片数据的对象

            // 动态生成 ul>li
            oUlstr += `<li><img src="${item.url}"></li>`;
            // 动态生生 ol>li
            // 给 第一个li标签 添加class,active 也就是 背景颜色是红色
            // 给 每个li标签 添加 num属性属性值是索引下标
            oOlstr += key === 0 ? `<li name = "ollis" class = "active" num = ${key}></li>` : `<li name = "ollis" num = ${key}></li>`
        })
        // 将 生成的字符串 写入 标签节点中
        this.oUl.innerHTML = oUlstr;
        this.oOl.innerHTML = oOlstr;
        // 添加节点,添加到div中
        this.ele.appendChild(this.oUl);
        this.ele.appendChild(this.oOl);
        this.ele.appendChild(this.oDiv);
        //获取生成的 原始 ul>li ol>li标签对象
        this.ulLis = this.oUl.querySelectorAll('li');
        this.olLis = this.oOl.querySelectorAll('li');

        //获取标签宽度
        this.liWidth = this.ulLis[0].offsetWidth;

        // 克隆标签
        let ulLisFirst = this.ulLis[0].cloneNode(true);
        let ulLisLast = this.ulLis[this.ulLis.length - 1].cloneNode(true);
        // 将 克隆的第一个 写入 ul的最后 
        this.oUl.appendChild(ulLisFirst)
        // 将 克隆的最后一个 写入 ul的起始 
        this.oUl.insertBefore(ulLisLast, this.ulLis[0]);
        // 重新设定ul宽度 
        // 克隆之后li标签个数 * li标签宽度
        // 克隆之后li标签个数是数组单元个数+2
        this.oUl.style.width = (this.arr.length + 2) * this.liWidth + 'px';
        // 将ul向左定位一个li的宽度
        this.oUl.style.left = -this.liWidth + 'px';
    }
    //自动轮播函数
    slideshow() {
        // 设定定时器
        this.time = setInterval(() => {
            if (this.res) {
                this.res = false;
            } else {
                return;
            }
            // 变量累加1
            this.index++;
            // index变量累加后 设定 对应的焦点样式
            this.point();
            // 通过 move() 运动函数 完成 ul标签 定位的切换

            // 回调函数使用 bind() 方法 修改this指向 
            // 当前 this 指向实例化对象 修改回调函数的this指向是当前this也就是实例化对象
            move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this))

        }, 2000)
    }

    //move运动函数执行结束触发的回调函数
    circulation() {
        //  如果是 当前ul的最后一个li 运动结束 立即切换到 当前ul的第二个li
        //  也就是 index 是 最后一个li的索引下标 也就是 arr.length+2-1 
        //  切换到 当前ul的第二个li 也就是 index 赋值 1 
        if (this.index === this.arr.length + 2 - 1) {
            this.index = 1;
            //  如果是 当前ul的第一个li 运动结束 立即切换到 当前ul的倒数二个li
            //  也就是 index 是 第一个li的索引下标 也就是 0
            //  切换到 当前ul的倒数第二个li 也就是 index 赋值 arr.length+2-1-1
        } else if (this.index === 0) {
            // 给 变量 赋值 当前ul的倒数第二个li的索引下标
            this.index = this.arr.length + 2 - 2
        }
        //  给 ul 执行定位 瞬间切换
        // 根据新的index数值 给 ul标签 做瞬间定位切换
        this.oUl.style.left = -this.index * this.liWidth + 'px';

        // 运动结束 也就是 一次ul切换完成
        // 给变量赋值原始值 可以 执行下一次运动
        this.res = true;
    }

    //焦点图函数
    point() {
        // 清除所有的ol>li焦点样式
        this.olLis.forEach((item) => {
            item.classList.remove('active');
        })
        // 如果 显示 当前ul中最后一个li 给 ol>li 中的 第一个添加样式
        if (this.index === this.arr.length + 2 - 1) {
            // 给 索引是0 的 第一个 ol>li 添加 css样式
            this.olLis[0].classList.add('active');
            // 如果 显示 点券ul中第一个li 给 ol>li 中的 最后一个添加样式
        } else if (this.index === 0) {
            // 给 ol>li 的最后一个 添加 css样式
            this.olLis[this.olLis.length - 1].classList.add('active');
            // 其他情况 给 当期ul>li索引下标 -1 对应的 ol>li 添加样式
        } else {
            // 当前 显示的ul>li的索引下标 也就是 index
            // 数值 -1 是 对应的 ol>li 的 索引下标 
            this.olLis[this.index - 1].classList.add("active");
        }
    }
    //鼠标移入移出函数
    theMouseMoves() {
        // 鼠标移入
        this.ele.addEventListener('mouseenter', () => {
            // 清除定时器
            clearInterval(this.time);
        })
        // 鼠标移出
        this.ele.addEventListener('mouseleave', () => {
            // 再次调用自动轮播
            this.slideshow();
        })
    }
    //点击事件函数
    theMouseClick() {
        // 给 轮播图div添加点击事件
        this.ele.addEventListener('click', (e) => {
            // 判断 如果 事件对象 e.target 的name属性值是 left 点击的是左切换按钮
            if (e.target.getAttribute('name') === "left") {
                // 防止点击过快
                if (this.res) {
                    this.res = false;
                } else {
                    return;
                }
                // 切换显示上一个li 
                // 也就是 索引下标 累减 1 
                this.index--;
                // 调用函数 重新设定 焦点按钮css样式
                this.point();
                // 根据新的索引下标 通过move()运动函数 
                // 动画效果 完成ul标签的重新定位
                move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));
            } else if (e.target.getAttribute('name') === "right") {
                // 判断 如果 事件对象 e.target 的name属性值是 right 点击的是左切换按钮
                if (this.res) {
                    this.res = false;
                } else {
                    return;
                }
                this.index++;
                this.point();
                move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));
            } else if (e.target.getAttribute('name') === "ollis") {
                // 判断 如果 事件对象 e.target 的name属性值是 olLi 点击的是焦点按钮
                if (this.res) {
                    this.res = false;
                } else {
                    return;
                }
                // 获取当前 点击的ol>li标签 num属性的属性值 
                // 也就是 点击的ol>li标签的 索引下标 
                // num属性值+1 是 对应的 ul>li 的索引下标
                // num属性值 是 字符串类型 必须要转化为数值类型 再 执行+1 运算
                this.index = Number(e.target.getAttribute('num')) + 1;
                this.point();
                move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));
            }
        })
    }
    // 浏览器最小化隐藏
    hide() {
        // 给 document 添加 浏览器显示状态监听
        document.addEventListener('visibilitychange', () => {
            // 如果 浏览器显示状态描述 是 hidden 
            if (document.visibilityState === 'hidden') {
                // 证明当前浏览器隐藏最小化
                // 清除定时器
                clearInterval(this.time);

                // 如果 浏览器显示状态描述 是 visible 
            } else if (document.visibilityState === 'visible') {
                // 证明当前浏览器 显示
                // 再次调用 自动轮播函数
                this.autoLoop();
            }
        })

    }
}

运行结果 

 

总结

控制轮播图的核心

就是 控制 变量中的存储的数值

也就是 控制 显示 li标签的索引下标

通过 设定 ul标签的定位 是 变量 * li宽度

也就是 设定 ul标签的定位 显示 变量对应索引下标对应的li标签

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大聪明码农徐

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值