面向对象的轮播图写法

        // 1,面向对象编程意思,大部分内容与面向过程基本相似
        //   只是将程序封装在一个对象内
        //   将程序执行需要的数据,定义为对象的属性和属性值
        //   将程序执行需要的代码,定义为对象的函数方法
        // 优点:对象是使用{}来定义的,如果使用let 等语法定义数据等,只能在对象中使用调用,与对象外的数据不会产生冲突,不会造成全局变量污染
        //      对象的数据,可以通过属性的方法获取属性值,便于调用使用
        //      封装一次面向对象程序,也可以反复调用使用,不用重复定义程序代码
        //      高内聚,低耦合,可反复调用
下面是代码部分
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        ul,
        ol,
        li {
            list-style: none;
        }

        a,
        a:hover,
        a:active {
            text-decoration: none;
            color: #333;
        }

        .clear::after {
            content: "";
            display: block;
            clear: both;
        }

        .banner {
            width: 600px;
            height: 400px;
            border: 3px solid #000;
            margin: 40px auto;
            position: relative;
            overflow: hidden;
        }

        .banner ul {
            width: 500%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
        }

        .banner ul li {
            width: 600px;
            height: 100%;
            float: left;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            font-size: 100px;
        }

        .banner ol {
            height: 50px;
            background: rgba(0, 0, 0, .4);
            position: absolute;
            bottom: 50px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            justify-content: space-evenly;
            align-items: center;
            border-radius: 10px;
        }

        .banner ol li {
            width: 25px;
            height: 25px;
            border-radius: 50%;
            background: #fff;
            margin: 0 25px;
            cursor: pointer;
        }

        .banner ol li.active {
            background: red;
        }

        .banner div {
            width: 100%;
            height: 50px;
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .banner div a {
            width: 40px;
            line-height: 40px;
            font-size: 40px;
            font-weight: 900;
            color: #fff;
            background: rgba(0, 0, 0, .4);
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="banner">
        <!-- 需要轮序播放的图片,没有多的5和1 
             多出来的5和1是动态生成的
        -->
        <ul class="clear">
            <li style="background:pink ;">img1</li>
            <li style="background:gray ;">img2</li>
            <li style="background:blue ;">img3</li>
            <li style="background:skyblue;">img4</li>
            <li style="background:orange ;">img5</li>
        </ul>
        <!-- 与轮播图,对应的焦点按钮 
             是根据轮播图的图片数量,动态生成的
        -->
        <ol></ol>
        <div>
            <a href="JavaScript:;" name="left"> &lt; </a>
            <a href="JavaScript:;" name="right"> &gt; </a>
        </div>
    </div>



    <script src="./04_banner.js"></script>
    <script>



        // 面向对象
        
        // 只需要获取总的父级的标签对象,oDiv
        // 其他的参数,都是在class类中来定义封装
        const oDiv = document.querySelector('div');

        // 创建实例化对象
        const setLoop = new SetLoop(oDiv);
        // 调用生成焦点方法
        setLoop.setLi();
        // 调用复制标签方法
        setLoop.copyLi();
        // 调用自动轮播方法
        setLoop.autoLoop();
        // 调用鼠标移入移出方法
        setLoop.overOut();
        // 调用焦点切换方法
        setLoop.focus();
        // 调用左右切换方法
        setLoop.leftRight();
        //调用解决页面隐藏的方法
        setLoop.hidden();
------------------------------------------------------------------------------------------------
这里面是banne。js里面封包的一些函数。
// 面向对象,封装class类

class SetLoop{
    // 定义数据参数
    // 参数是 父级标签div
    constructor(ele){
        // 存储参数,也就是div标签对象
        this.ele = ele;
        // 获取设定需要的数据参数

        // 获取的标签对象
        this.oUl = ele.querySelector('ul');
        this.oOl = ele.querySelector('ol');
        this.oD = ele.querySelector('div');
        this.oUllis = ele.querySelectorAll('ul li');

        // 定义参数
        this.index = 1;
        // 存储自动轮播定时器变量
        this.loopTime = 0;
        // li的默认宽度
        this.oLiwidth = parseInt(window.getComputedStyle(this.oUllis[0]).width );
        // 定义开关变量,防止点击过快
        this.bool = '原始数值';
    }

    // 定义方法1 , 运动函数 在其他的方法中调用
    move(ele, obj, callback) {
        // 1,循环
        for (let type in obj) {
            // 获取原始定位数据
            let oldVal = parseInt(window.getComputedStyle(ele)[type]);
            // 定义定时器
            let time = setInterval(function () {
                // 计算步长
                let val = (obj[type] - oldVal) / 5;
                // 判断正负,取整
                val = val > 0 ? Math.ceil(val) : Math.floor(val);
                // 执行步长
                oldVal += val;
                // 执行定位
                ele.style[type] = oldVal + 'px';
                // 到达目标位置,终止定时器
                if (oldVal == obj[type]) {
                    // 终止定时器
                    clearInterval(time);
                    // 调用函数
                    callback()
                }
            }, 100)
        }
    }


    // 定义方法2 , 设定焦点
    setLi() {
        // 定义变量,存储生成的li标签
        let str = '';
        // 根据原始轮播图,生成焦点按钮
        this.oUllis.forEach(function (item, key) {
            if (key == 0) {
                str += `<li index="${key + 1}" class="active"></li>`;
            } else {
                str += `<li index="${key + 1}" ></li>`;
            }
        });
        // 写入标签
        this.oOl.innerHTML = str;
    }

    // 定义方法3 , 复制标签
    copyLi() {
        // 1,获取需要复制的标签对象
        let liF = this.oUllis[0];
        let liL = this.oUllis[this.oUllis.length - 1];
    
        // 2,复制标签
        let first = liF.cloneNode(true);
        let last = liL.cloneNode(true);
    
        // 3,写入标签
        this.oUl.appendChild(first);
        this.oUl.insertBefore(last, liF);
    
        // 4,定义ul宽度
        this.oUl.style.width = ((this.oUllis.length + 2) * this.oLiwidth) + 'px';
    
        // 5,定义ul位移
        this.oUl.style.left = -this.oLiwidth + 'px';
    }


    // 定义方法4,自动轮播
    // 此时,所有的this,指向的都是构造函数中的参数所表示的this
    // 也就是实例化对象,都要改成箭头函数
    autoLoop() {
        // 改成箭头函数
        this.loopTime = setInterval( ()=> {
            // 记录轮播次数变量++
            this.index++;

            // 执行运动函数,改成箭头函数
            this.move(this.oUl, { left: -this.index * this.oLiwidth },  ()=>{
                // 虽然写在class中的方法,可以省略function关键词
                // 但是定义的还是一个函数,class语法,会自动添加 function关键词
                // 有了 function关键词 就可以提前调用函数方法
                // 调用时,通过 this.函数方法名称() 来调用
                this.stopLoop();
            })
        }, 3000);
    }

    // 定义方法5 , 运动终止时,执行的函数
    stopLoop() {
        // 1,给开关变量,赋值初始值
        this.bool = '原始数值';
    
        // 2,判断idnex数值,并且给ul做定位
        // 如果是最后一个img1
        if (this.index == this.oUllis.length + 1) {
            // 改变index数值
            this.index = 1;
            // 瞬间切换图片
            this.oUl.style.left = (-this.index * this.oLiwidth) + 'px';
        // 如果是第一个img5
        } else if (this.index == 0) {
            // 改变index数值
            this.index = this.oUllis.length;
            // 瞬间切换图片
            this.oUl.style.left = (-this.index * this.oLiwidth) + 'px';
        }
    
        // 3,设定焦点按钮样式,后动
        // 获取ol中的li,在生成焦点之后生成
        // 在 this.ele 也就是 oDiv中 获取 ol中的li
        let oOllis = this.ele.querySelectorAll('ol li');
        // 循环遍历
        // 使用 this.index 必须改成箭头函数
        oOllis.forEach( (item) => {
            // 清除所有的样式
            item.className = '';
            // 给点击的li,添加样式
            if (item.getAttribute('index') == this.index) {
                item.className = 'active';
            }
        })
    }

    // 定义方法6 , 鼠标移入移出
    overOut () {
        // 给父级div添加事件 oDiv改成 this.ele
    
        // 移入清除定时器,终止函数
        this.ele.addEventListener('mouseover',  () =>{
            clearInterval(this.loopTime)
        });
        // 移出,再次执行函数
        this.ele.addEventListener('mouseout',  () =>{
            this.autoLoop();
        });
    }

    // 定义方法7,焦点按钮切换
    focus(){
        // 给ol添加事件
        this.oOl.addEventListener('click' , (e)=>{
            // 如果点击的是li标签
            if(e.target.tagName == 'LI'){
                // 防止点击过快
                if(this.bool !== '原始数值'){
                    return;
                }
                this.bool = '非原始数值';
                // 获取点击标签,index的属性,赋值给变量
                this.index = e.target.getAttribute('index')-0;
                // 一定要用move()运动函数,这样才可以再次点击
                this.move(this.oUl, { left: -this.index * this.oLiwidth },  ()=> {
                    this.stopLoop();
                })
            }
        })
    }

    // 定义方法8 , 左右切换
    
    leftRight() {
        this.oD.addEventListener('click',  (e)=> {
            // 如果点击的是左切换
            if (e.target.getAttribute('name') == 'left') {
                // 防止过快
                if(this.bool !== '原始数值'){
                    return;
                }
                this.bool = '非原始数值';
                // index数值--
                this.index--;
                // 一定要用move()运动函数,这样才可以再次点击
                this.move(this.oUl, { left: -this.index * this.oLiwidth },  ()=> {
                    this.stopLoop();
                })
            }else if(e.target.getAttribute('name') == 'right'){
                // 防止过快
                if(this.bool !== '原始数值'){
                    return;
                }
                this.bool = '非原始数值';
                // index数值++
                this.index++;
                // 一定要用move()运动函数,这样才可以再次点击
                this.move(this.oUl, { left: -this.index * this.oLiwidth },  ()=> {
                    this.stopLoop();
                })
            }
        })
    }

    // 定义方法9 , 页面隐藏
    hidden(){
        // 当 页面显示变化时
        // 此处是特殊的页面显示状态事件,必须是document,不能改的
        document.addEventListener('visibilitychange' , ()=>{
            // 如果隐藏,清除定时器,不执行自动轮播
            if(document.visibilityState === 'hidden'){
                clearInterval(this.loopTime);
            // 如果显示,继续执行自动轮播
            }else if(document.visibilityState === 'visible'){
                this.autoLoop();
            }
        })
    }
}
posted @ 2021-04-19 09:56  小白797  阅读(354)  评论(0)    收藏  举报