JavaScript学习笔记(二十六)——面向对象编程小案例

面型对象编程——放大镜

HTML文件

<!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;
        }

        .container {
            width: 980px;
            margin: 0 auto;
        }

        ul {
            list-style: none;
        }

        .fdj {
            width: 400px;
            position: relative;
        }

        .fdj1 {
            width: 200px;
            position: relative;
        }
    </style>
</head>

<body>
    <div class="content">
        <div class="container">
            <div class="fdj"></div>
        </div>
        <div class="container">
            <div class="fdj1"></div>
        </div>
    </div>
    <script src="../js/glass.js"></script>
    <script>

        // 获取元素
        let fdj = document.querySelector(".fdj");
        let fdj1 = document.querySelector(".fdj1");

        // 图片地址数组
        let imgArr = [
            {
                iconPath: "../images/icon01.jpg",
                smallImgPath: "../images/small01.jpg",
                bigImgPath: "../images/big01.jpg"
            },
            {
                iconPath: "../images/icon02.jpg",
                smallImgPath: "../images/small02.jpg",
                bigImgPath: "../images/big02.jpg"
            },
            {
                iconPath: "../images/icon03.jpg",
                smallImgPath: "../images/small03.jpg",
                bigImgPath: "../images/big03.jpg"
            },
        ]
        // 创建实例对象
        let z = new Zoom(fdj, imgArr);
        z.render();
        z.addStyle();
        z.addEvevt();
        let z1 = new Zoom(fdj1, imgArr);
        z1.render();
        z1.addStyle();
        z1.addEvevt();
    </script>
</body>

</html>

glass.js文件

let Zoom = (function(){
    function offset(dom){
            // 定义两个变量
            var left = 0;
            var top = 0;
            // 计算自身元素左边框外到定位父元素的左边框内
            var left = dom.offsetLeft;
            var top = dom.offsetTop;
            // 判断浏览器是否是IE8
            var isIE8 = false;
            if(window.navigator.userAgent.indexOf("MSIE 8") != -1){
                isIE8 = true;
            }
            // 让自己指向上一层
            dom = dom.offsetParent;
            // 因为dom没有直接获取到页面的属性所以只能一层一层的往上找
            while(dom != document.body){
                // 如果是浏览器IE8,不需要加上clientLeft、clientTop
                if(isIE8){
                    // 累加每一层的offsetLeft
                    left += dom.offsetLeft;
                    // 累加每一层的offsetTop
                    top += dom.offsetTop;
                }else{
                    // 累加每一层的offsetLeft、clientLeft
                    left += dom.offsetLeft + dom.clientLeft;
                    // 累加每一层的offsetTop、clientTop
                    top += dom.offsetTop + dom.clientTop;
                }
                // 让dom指向上一层
                dom = dom.offsetParent;
            }
            // 返回left、top
            return{
                left: left,
                top: top
            }
        }

    // 参数一表示外层大容器,参数二表示图片的地址
    function Zoom(container, imgArr) {
        // 容器属性
        this.container = container;
        // 图片地址数组属性
        this.imgArr = imgArr;
        // 创建小图图片
        this.smallImage = document.createElement("img");
        // 创建大图图片
        this.bigImage = document.createElement("img");
        // 创建图片列表
        this.ul = document.createElement("ul");
        // 创建镜片
        this.glass = document.createElement("div");
        // 定义图片容器列表
        this.lis = [];
        // 定义一个缩放比例
        this.r = 0.5;
    }

    // 在原型里面添加属性,要保证原型里面原来的constructor还存在原型里面
    Zoom.prototype = {
        construtor: Zoom,
        // 渲染结构
        render(){
            // 创建小图容器
            let smallContainer = document.createElement("div");
            // 设置小图图片
            this.smallImage.src = this.imgArr[0].smallImgPath;
            // 创建大图容器
            let bigContainer = document.createElement("div");
            // 设置大图图片
            this.bigImage.src = this.imgArr[0].bigImgPath;
            // 追加小图片、大图片
            smallContainer.appendChild(this.smallImage);
            bigContainer.appendChild(this.bigImage);
            // 将小图容器、大图容器、图片列表容器追加到主容器中
            this.container.appendChild(smallContainer);
            this.container.appendChild(bigContainer);
            this.container.appendChild(this.ul);
            // 追加放大镜
            smallContainer.appendChild(this.glass);
            // 根据传递的图片地址数组,创建ul的li元素
            this.imgArr.forEach((value) => {
                // 创建li元素
                let li = document.createElement("li");
                // 创建img元素
                let img = document.createElement("img");
                // 设置img的src
                img.src = value.iconPath;
                // 将img追加到li
                li.appendChild(img);
                this.lis.push(li);
                // 将li追加到ul
                this.ul.appendChild(li);
            });
        },

        // 添加样式
        addStyle(){
            // 获取小图容器元素
            let smallContainer = this.smallImage.parentNode;
            // 准备小图容器样式
            let smallStyle = {
                width: "100%",
                height: smallContainer.clientWidth + "px"
            }
            // 设置小图容器样式
            for (let i in smallStyle){
                smallContainer.style[i] = smallStyle[i];
            }
            // 准备小图图片样式
            let smallImgStyle = {
                width: "100%",
                height: "100%"
            }
            // 设置小图图片样式
            for (let i in smallImgStyle){
                this.smallImage.style[i] = smallImgStyle[i]; 
            }
            // 获取大图容器元素
            let bigContainer = this.bigImage.parentNode;
            // 准备大图容器样式
            let bigStyle = {
                width: smallContainer.clientWidth * 1.50 + "px",
                height: smallContainer.clientWidth * 1.50 + "px",
                position: "absolute",
                overflow: "hidden",
                left: "110%",
                top: 0,
                display: "none"
            }
            // 设置大图容器样式
            for (let i in bigStyle){
                bigContainer.style[i] = bigStyle[i];
            }
            // 准备大图图片样式
            let bigImgStyle = {
                position: "absolute",
                top: "0",
                left: "0",
                width: smallContainer.clientWidth * 1.50 / this.r + "px",
                height: smallContainer.clientWidth * 1.50 / this.r + "px"
            }
            // 设置大图图片样式
            for (let i in bigImgStyle){
                this.bigImage.style[i] = bigImgStyle[i];
            }
            // 准备放大镜样式
            let glassStyle = {
                position: "absolute",
                top: 0,
                left: 0,
                backgroundColor: "rgba(0, 0, 0, 0.4)",
                width: smallContainer.clientWidth * this.r + "px",
                height: smallContainer.clientWidth * this.r + "px",
                display: "none",
                cursor: "pointer"
            }
            // 设置放大镜样式
            for (let i in glassStyle){
                this.glass.style[i] = glassStyle[i];
            }
            // 准备图片列表样式
            let ulStyle = {
                display: "flex",
                justifyContent: "space-around",
                padding: '10px 0',
                cursor: "pointer"
            }
            // 设置图片列表样式
            for (let i in ulStyle){
                this.ul.style[i] = ulStyle[i];
            }
            // 设置ul中li被选中状态样式
            this.lis.forEach((value) => {
                value.style.border = "2px solid transparent";
            })
        },

        // 添加事件
        addEvevt() {
            // 遍历图片列表
            this.lis.forEach((value, index) => {
                // 添加鼠标进入图片列表每个li的事件
                value.addEventListener("mouseenter", () => {
                    // 改变小图图片
                    this.smallImage.src = this.imgArr[index].smallImgPath;
                    // 改变大图图片
                    this.bigImage.src = this.imgArr[index].bigImgPath;
                    // 节流,清除图片列表里面每一个li的边框样式
                    this.lis.forEach((value) => {
                        value.style.borderColor = "transparent";
                    })
                    // 设置选中的li边框颜色
                    value.style.borderColor = "red";
                })
            })
            // 获取小图容器元素
            let smallContainer = this.smallImage.parentNode;
            // 鼠标进入事件,显示放大镜和大图容器
            smallContainer.addEventListener("mouseenter", () => {
                this.glass.style.display = "block";
                this.bigImage.parentNode.style.display = "block";
            })
            // 鼠标离开事件,隐藏放大镜和大图容器
            smallContainer.addEventListener("mouseleave", () => {
                this.glass.style.display = "none";
                this.bigImage.parentNode.style.display = "none";
            })
            // 添加拖拽事件(鼠标移动事件)
            smallContainer.addEventListener("mousemove", (e) => {
                // 浏览器兼容处理
                let event = e || window.event;
                // 获取鼠标到页面的距离
                let pageX = event.pageX;
                let pageY = event.pageY;
                // 获取元素到页面的距离
                let obj = offset(this.container);
                let x = obj.left;
                let y = obj.top;
                // 计算放大镜glass的一半宽高
                let halfX = this.glass.clientWidth / 2;
                let halfY = this.glass.clientHeight / 2;
                // 计算放大镜移动后的位置
                let glassLeft = pageX - x - halfX;
                let glassTop = pageY - y - halfY;
                // 边界值判定
                if (glassLeft < 0){
                    glassLeft = 0;
                } else if(glassLeft > this.smallImage.clientWidth - this.glass.clientWidth){
                    glassLeft = this.smallImage.clientWidth - this.glass.clientWidth;
                }
                if (glassTop < 0){
                    glassTop = 0;
                } else if(glassTop > this.smallImage.clientHeight - this.glass.clientHeight){
                    glassTop = this.smallImage.clientHeight - this.glass.clientHeight;
                }
                // 设置放大镜glass位置
                this.glass.style.left = glassLeft + "px";
                this.glass.style.top = glassTop + "px";
                // 设置大图图像随着放大镜移动
                let r = (this.smallImage.clientWidth * this.r / (this.bigImage.width - this.bigImage.parentNode.clientWidth));
                this.bigImage.style.left = -glassLeft / r + "px";
                this.bigImage.style.top = -glassTop / r + "px";
            })
        }
    }
    return Zoom;
})();

在这里插入图片描述


面向对象编程——轮播图

HTML文件

<!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;
        }

        .carousel {
            width: 600px;
            height: 400px;
            margin: 0 auto;
            overflow: hidden;
            position: relative;
            border: 1px solid #ccc;
        }
    </style>
</head>

<body>
    <div class="carousel"></div>
    <script src="../js/Banner.js"></script>
    <script>
        let carousel = document.querySelector(".carousel");
        let b = new Banner(carousel, [
            "../images/1.jpeg",
            "../images/2.jpeg",
            "../images/3.jpeg",
            "../images/4.jpeg",
            "../images/5.jpeg",
            "../images/6.jpeg"]);

    </script>
</body>

</html>

Banner.js文件

let Banner = (function(){
    // 封装运动函数,参数一表示元素,参数二表示一个对象(对象里面可以设置多个属性),参数三表示运动时间,参数四表示回调函数
    function animate(ele, endObj, duration, callback) {
        // 规定运动频率
        let interval = 20;
        // 运动次数 = 运动时间 / 运动频率
        let stepCount = duration / interval;
        // 获取元素起点位置
        let startObj = {};
        // 通过循环参数二对象里面的属性,获取元素开始时与参数二对象里面的属性的初始值
        for (let i in endObj) {
            // 将获取到的初始值放到一个startObj对象
            // 因为使用getComputedStyle获取到的计算后样式,返回值是一个带有px的字符串,所以需要将其转为一个数值型
            startObj[i] = parseInt(getComputedStyle(ele)[i]);
        }
        // 定义一个变量,用于计算运动了几次
        let count = 0;
        // 开启定时器
        let timer = setInterval(() => {
            // 每运动一次,count加1
            count++;
            // 通过循环改变元素的属性
            for (let i in endObj) {
                // 开始位置(或者说是开始属性) + (最终位置(或者说是最终属性) - 开始位置(或者说是开始属性)) / 运动总次数 * 当前运动的第几次
                let result = startObj[i] + (endObj[i] - startObj[i]) / stepCount * count;
                // 假设参数endObj里面函数有一个透明的属性opacity,需要进行判断,因为opacity没有单位px
                ele.style[i] = (i.toLowerCase() === "opacity") ? result : (result + "px");
            }
            // 判断何时运动结束
            if (count >= stepCount) {
                clearInterval(timer);
                // 回调函数
                callback && callback();
                // 上行代码等价于
                // if(callback){callback()}
            }
        }, interval);
    }

    function Banner(container, imageArr, interval = 1000, waitInterval = interval * 2) {
        this.container = container;
        this.imageArr = imageArr;
        this.interval = interval;
        this.waitInterval = waitInterval;
        // 图片容器ul属性
        this.imgUL = document.createElement("ul");
        // 左右按钮容器属性
        this.btnContainer = document.createElement("div");
        // 左按钮属性
        this.leftBtn = document.createElement("span");
        // 右按钮属性
        this.rightBtn = document.createElement("span");
        // 小圆点按钮容器ul属性
        this.cirUL = document.createElement("ul");
        // 定义数组,用于承载图片的li
        this.liArr = [];
        // 定义数组。用于承载图片
        this.imgArr = [];
        // 定义数组,用于承载小圆点按钮的li
        this.cirArr = [];
        // 定义定时器
        this.timer = null;
        // 定义锁
        this.lock = true;
        // 定义信号量
        this.idx = 0;
        this.init();
    }


    Banner.prototype = {
        constructor: Banner,
        // 初始化
        init() {
            this.create();
            this.addStyle();
            this.upTree();
            this.bindEvent();
        },

        // 创建元素
        create() {
            this.createImageList();
            this.createLeftBtn();
            this.createRightBtn();
            this.createCirList();
        },

        // 创建图片列表
        createImageList() {
            // 根据图片地址数组,循环创建每一个li元素
            this.imageArr.forEach((value) => {
                // 创建li
                let li = document.createElement("li");
                // 创建完li,载入数组
                this.liArr.push(li);
                // 创建图片
                let img = new Image();
                // 创建完图片,载入数组
                this.imgArr.push(img);
                // 设置路径
                img.src = value;
                // 让img成为li的子元素
                li.appendChild(img);
                // 让li成为ul的子元素
                this.imgUL.appendChild(li);
            })
            // 创建猫腻图
            let li = this.liArr[0].cloneNode(true);
            // 将猫腻图加入liArr数组
            this.liArr.push(li);
            // 将猫腻图加入imgArr数组
            this.imgArr.push(li.childNodes[0]);
            // 将猫腻图追加到ul最后
            this.imgUL.appendChild(li);
        },

        // 创建左按钮
        createLeftBtn() {
            this.btnContainer.appendChild(this.leftBtn);
        },

        // 创建右按钮
        createRightBtn() {
            this.btnContainer.appendChild(this.rightBtn);
        },

        // 创建小圆点
        createCirList() {
            this.imageArr.forEach(function () {
                // 创建li
                let li = document.createElement("li");
                // 创建完li,载入数组
                this.cirArr.push(li);
                // 让li成为cirUL的子元素
                this.cirUL.appendChild(li);
            }.bind(this));
        },

        // 渲染方法
        addStyle() {
            this.addImageListStyle();
            this.addBtnStyle();
            this.addCirStyle();
        },

        // 添加图片列表样式
        addImageListStyle() {
            // 设置ul样式
            this.imgUL.style.width = this.container.clientWidth * this.liArr.length + "px";
            this.imgUL.style.height = this.container.clientHeight + "px";
            this.imgUL.style.listStyle = "none";
            this.imgUL.style.position = "absolute";
            // 获取li,添加样式
            this.liArr.forEach((value) => {
                value.style.width = this.container.clientWidth + "px";
                value.style.height = this.container.clientHeight + "px";
                value.style.float = "left";
            })
            // 设置img样式
            this.imgArr.forEach((value) => {
                value.style.width = "100%";
                value.style.height = "100%";
            })
        },

        // 添加左右按钮容器样式
        addBtnStyle() {
            let conStyle = {
                width: "100%",
                height: this.container.clientHeight * 0.3 + "px",
                position: "absolute",
                top: "35%",
                display: "flex",
                justifyContent: "space-between"
            }
            for (let i in conStyle) {
                this.btnContainer.style[i] = conStyle[i];
            }
            let btnStyle = {
                display: 'block',
                width: this.container.clientWidth * 0.15 + "px",
                height: "100%",
                textAlign: "center",
                color: "white",
                lineHeight: this.container.clientHeight * 0.3 + "px",
                cursor: "pointer",
                fontSize: this.container.clientHeight * 0.1 + "px",
                backgroundColor: "rgba(0, 0, 0, 0.3)"
            }
            // 添加左右按钮样式 
            for (var i in btnStyle) {
                this.leftBtn.style[i] = btnStyle[i];
                this.rightBtn.style[i] = btnStyle[i];
            }
            this.leftBtn.innerHTML = "&lt;";
            this.rightBtn.innerHTML = "&gt;";
        },

        // 添加小圆点按钮容器样式
        addCirStyle() {
            let conStyle = {
                position: "absolute",
                height: this.container.clientHeight * 0.15 + "px",
                width: this.container.clientWidth * 0.5 + "px",
                right: 0,
                bottom: 0,
                listStyle: "none",
                display: "flex",
                justifyContent: "space-around",
                alignItems: "center"
            }
            for (let i in conStyle) {
                this.cirUL.style[i] = conStyle[i];
            }
            // 添加小圆点按钮样式
            let cirStyle = {
                width: this.container.clientWidth * 0.04 + "px",
                height: this.container.clientWidth * 0.04 + "px",
                backgroundColor: "white",
                borderRadius: "50%",
                cursor: "pointer"
            }
            this.cirArr.forEach((value) => {
                for (let i in cirStyle) {
                    value.style[i] = cirStyle[i];
                }
            })
            // 默认为第一个小圆点添加样式
            this.cirArr[0].style.backgroundColor = "red";
        },

        // 上树
        upTree() {
            this.container.appendChild(this.imgUL);
            this.container.appendChild(this.btnContainer);
            this.container.appendChild(this.cirUL);
        },

        // 绑定事件
        bindEvent() {
            this.bindLeftBtn();
            this.bindRightBtn();
            this.bindCirBtn();
            this.bindAutoLoop();
            this.bindMouseEnter();
            this.bindMouseLeave();
        },

        // 绑定左按钮事件
        bindLeftBtn() {
            this.leftBtn.addEventListener("click", () => {
                // 判断锁状态
                if (!this.lock) {
                    return;
                }
                // 如果处于开锁状态,下面的代码将会被执行,动画结束前多次点击无效
                this.lock = false;
                // 点击一次信号量减1
                this.idx--;
                // 判断是否是第一张图片
                if (this.idx < 0) {
                    // 因为小圆点的个数比图片的数量少1
                    this.idx = this.liArr.length - 1;
                    this.imgUL.style.left = -this.idx * this.container.clientWidth + "px";
                    this.idx--;
                }
                animate(this.imgUL, { left: -this.idx * this.container.clientWidth }, this.interval, () => {
                    // 开锁
                    this.lock = true;
                });
                // 添加小圆点样式
                this.changeCirBtnStyle();
            })
        },
        // 绑定右按钮事件
        bindRightBtn() {
            this.rightBtn.onclick = () => {
                // 判断锁状态
                if (!this.lock) {
                    return;
                }
                // 如果处于开锁状态,下面的代码将会被执行,动画结束前多次点击无效
                this.lock = false;
                // 点击一次信号量加1
                this.idx++;
                animate(this.imgUL, {left: -this.idx * this.container.clientWidth}, this.interval, () => {
                    // 判断是否是最后一张图
                    if(this.idx >= this.liArr.length - 1){
                        // 将图片列表位置归零
                        this.imgUL.style.left = 0;
                        // 将信号量归零
                        this.idx = 0;
                    }
                    // 开锁
                    this.lock = true;
                });
                // 添加小圆点样式
                this.changeCirBtnStyle();
            }
        },
        // 绑定小圆点按钮事件
        bindCirBtn() {
            this.cirArr.forEach((value, index) => {
                // 为每一个小圆点添加点击事件
                value.addEventListener("click", () => {
                    // 判断锁状态
                    if (!this.lock) {
                        return;
                    }
                    // 如果处于开锁状态,下面的代码将会被执行,动画结束前多次点击无效
                    this.lock = false;
                    // 切换图片
                    this.idx = index;
                    animate(this.imgUL, {left: -this.idx * this.container.clientWidth}, this.interval, () => {
                        // 开锁
                        this.lock = true;
                    })
                    // 添加小圆点样式
                    this.changeCirBtnStyle();
                })
            })

        },
        // 设置小圆点样式
        changeCirBtnStyle(){
            this.cirArr.forEach((value, index) => {
                value.style.backgroundColor = index === this.idx ? "red" : "white";
            })
            if (this.idx >= this.liArr.length - 1) {
                this.cirArr[0].style.backgroundColor = "red";
            }
        },
        // 绑定自动轮播事件
        bindAutoLoop() {
            this.timer = setInterval(() => {
                this.rightBtn.onclick();
            }, this.waitInterval)
        },
        // 绑定鼠标进入事件
        bindMouseEnter() {
            this.container.addEventListener("mouseenter", () => {
                clearInterval(this.timer);
            })
        },
        // 绑定鼠标移出事件
        bindMouseLeave() {
            this.container.addEventListener("mouseleave", () => {
                this.bindAutoLoop();
            })
        }
    }
    return Banner;
})();

在这里插入图片描述


面向对象编程——弹幕

<!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;
        }
        .container{
            width: 800px;
            height: 600px;
            margin: 0 auto;
        }
        .videoArea{
            width: 100%;
            height: 550px;
            position: relative;
            background: #000;
            overflow: hidden;
        }
        .inputArea{
            width: 100%;
            height: 50px;
            display: flex;
        }
        .inp{
            flex: 8;
            outline: none;
        }
        .sendMsg{
            flex: 2;
            cursor: pointer;
            outline: none;
        }
    </style>
</head>
<body>
    <div class="container" id="container">
        <div class="videoArea" id="videoArea">
        </div>
        <div class="inputArea" id="inputArea">
            <input type="text" name="inp" id="inp" class="inp" placeholder="请文注意文明用语">
            <button class="sendMsg" id="sendMsg">发送</button>
        </div>
    </div>
    <script>
        // 获取元素
        let videoArea = document.getElementById("videoArea");
        let inp = document.getElementById("inp");
        let sendMsg = document.getElementById("sendMsg");

        // 定义一个数组用于存放弹幕
        let arr = [];

        // 点击发送按钮事件
        sendMsg.addEventListener("click", () => {
            // 获取弹幕内容
            let val = inp.value;
            // 判断获取到的弹幕内容是否为空
            if(val === ""){
                alert("弹幕内容不能为空!");
                return;
            }
            // 屏蔽敏感词
            let reg = /(色)|(杀)|(打)|(毒)|(赌)|(抢)|(操)/g;
            // 提示用户注意言语
            if(reg.test(val)){
                alert("请注意您的言语!");
            }   
            // 将敏感词替换
            val = val.replace(reg, "*");
            // 生成一个弹幕对象
            arr.push(new Message(videoArea, val));
            // 清空输入框内容
            inp.value = "";
        })

        // 定义Message类
        function Message(container, text){
            this.container = container;
            this.text = text;
            // 创建元素
            this.ele = document.createElement("div");
            // 设置随机速度
            this.speed = parseInt(Math.random() * 5) + 2;
            // 备份速度,用于在弹幕被鼠标移入停止,鼠标离开后能够保持原来的速度移动
            this.copySpeed = this.speed;
            this.init();
        }

        Message.prototype = {
            consturctor: Message,
            init(){
                this.create();
                this.upTree();
                this.addStyle();
                this.bindEvent();
            },

            // 创建元素
            create(){
                // 创建弹幕元素
                this.message = document.createElement("span");
                // 添加弹幕内容
                this.message.innerText = this.text;
                // 追加
                this.ele.appendChild(this.message);
            },

            // 上树
            upTree(){
                this.container.appendChild(this.ele);
            },

            // 添加样式
            addStyle(){
                // 准备弹幕容器样式
                let eleStyle = {
                    position: "absolute",
                    left: "100%",
                    top: Math.random()*this.container.clientHeight + "px",
                    width: this.container.clientWidth + "px"
                }
                // 设置容器样式
                for (let i in eleStyle){
                    this.ele.style[i] = eleStyle[i];
                }
                // 准备弹幕内容样式
                let msgStyle = {
                    display: 'inline-block',
                    left: "100%",
                    height: "16px",
                    lineHeight: "16px",
                    fontSize: "14px",
                    color: `rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`
                }
                // 设置弹幕内容样式
                for (var i in msgStyle) {
                    this.message.style[i] = msgStyle[i]
                }
            },
            // 运动
            move() {
                this.ele.style.left = this.ele.offsetLeft - this.speed + "px";
            },
            // 将元素删除
            unload() {
                this.ele.remove();
            },
            // 当鼠标进入元素时 要让当前这个停下  1 停止定时器 我们操作到了类之外的内容 而且一旦定时器停止 所有的弹幕都停了 
            // 2 仅仅把当前弹幕停止 把速度变为0即可
            bindEvent() {
                // 鼠标进入事件
                this.ele.onmouseenter = () => {
                    // 鼠标移到哪条弹幕上面,就将哪条弹幕停止运动,为了防止鼠标进入某一条弹幕上后,后面的某一条弹幕经过鼠标箭头时,导致原来暂停的弹幕继续运动,后来的弹幕停止的现象,所以需要将弹幕的层级提升
                    this.ele.style.zIndex = 100;
                    // 将弹幕的速度设为0
                    this.speed = 0;
                }
                // 鼠标离开事件
                this.ele.onmouseleave = () => {
                    // 鼠标离开后,将层级设为原来的1
                    this.ele.style.zIndex = 1;
                    // 恢复原来的移动速度
                    this.speed = this.copySpeed;
                }
            }
        }

        // 设置定时器
        setInterval(function() {
            // 遍历数组
            arr.forEach((value, index) => {
                // 让数组里面的每一条弹幕运动
                value.move();
                // 当弹幕全部离开后,将其删除
                if (value.ele.offsetLeft < -value.ele.offsetWidth) {
                    value.unload();
                    arr.splice(index, 1);
                }
            })
        }, 30)
    </script>
</body>
</html>

在这里插入图片描述


面向对象编程——随机点名系统

HTML文件

<!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;
            background-color: #444;
        }
        h1{
            text-align: center;
            margin: 50px auto;
        }
        .box{
            width: 1000px;
            height: auto;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <h1>随机点名系统</h1>
    <div class="box" id="box"></div>

    <script src="../js/Roll.js"></script>
    <script>
        let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
        let box = document.getElementById("box");
        let roll = new Roll(box, arr, 200, 20);
    </script>
</body>
</html>

Roll.js文件

let Roll = (function(){
    // 参数一表示主容器,参数二表示数组,参数三表示定时器间隔时间(默认是100毫秒),参数四是多选次数(默认是10),多选指的是随机选择多次后停止
    function Roll(container, arr, duration = 100, count = 10){
        // 容器
        this.container = container;
        // 数组
        this.arr = arr;
        // 定时器间隔时间
        this.duration = duration;
        // 多选次数
        this.count = count;
        // 被选中名字容器
        this.box1 = document.createElement("div");
        // 所有名字容器
        this.box2 = document.createElement("div");
        // 按钮容器
        this.box3 = document.createElement("div");
        // h2
        this.clickedH2 = document.createElement("h2");
        // 显示选中名字span
        this.clickedSpan = document.createElement("span");
        // 单选按钮
        this.btn1 = document.createElement("button");
        // 多选按钮
        this.btn2 = document.createElement("button");
        // 所有数组成员
        this.nameArr = [];
        this.init();
    }
    Roll.prototype = {
        constructor: Roll,
        init(){
            this.upTree();
            this.addStyle();
            this.bindEvent();
        },
        // 元素上树
        upTree(){
            this.upClickName();
            this.upAllName();
            this.upBtnBox();
        },
        upClickName(){
            this.clickedH2.innerText = "恭喜选中:"
            // clickedSpan追加到clickedH2中
            this.clickedH2.appendChild(this.clickedSpan);
            // clickedH2追加到box1中
            this.box1.appendChild(this.clickedH2);
            // box1追加到container中
            this.container.appendChild(this.box1);
        },
        upAllName(){
            // 遍历数组
            this.arr.forEach((value) => {
                let nameSpan = document.createElement("span");
                nameSpan.innerText = value;
                this.nameArr.push(nameSpan);
                // nameSpan追加到box2中
                this.box2.appendChild(nameSpan);
                // box2追加到container中
                this.container.appendChild(this.box2);
            })            
        },
        upBtnBox(){
            this.btn1.innerText = "单选";
            this.btn2.innerText = "多选";
            // btn1、btn2追加到box3中
            this.box3.appendChild(this.btn1);
            this.box3.appendChild(this.btn2);
            // box3追加到container中
            this.container.appendChild(this.box3);
        },

        // 添加样式
        addStyle(){
            this.addBoxStyle1();
            this.addBoxStyle2();
            this.addBoxStyle3();
        },
        // box1样式
        addBoxStyle1(){
            // 准备box1样式
            let box1Style = {
                width: this.container.clientWidth + "px",
                height: "auto",
                margin: "10px 0",
                padding: "10px 0",
                borderWidth: "2px",
                borderStyle: "solid",
                borderColor: "#CCC",
                display: "flex",
                justifyContent: "center",
                alignItems: "center"
            }
            // 设置box1样式
            for (let i in box1Style){
                this.box1.style[i] = box1Style[i];
            }
            // 准备clickedSpan样式
            let spanStyle = {
                color: "red"
            }
            // 设置clickedSpan样式
            for (let i in spanStyle){
                this.clickedSpan.style[i] = spanStyle[i];
            }
        },
        // box2样式
        addBoxStyle2(){
            // 准备box2样式
            let box2Style = {
                width: this.container.clientWidth + "px",
                height: "auto",
                margin: "10px 0",
                borderWidth: "2px",
                borderStyle: "solid",
                borderColor: "#CCC",
                display: "flex",
                justifyContent: "center",
                flexWrap: "wrap"
            }
            // 设置box2样式
            for (let i in box2Style){
                this.box2.style[i] = box2Style[i];
            }
            // 准备box2子元素样式
            let nameStyle = {
                display: "inline-block",
                justifyContent: "space-between",
                width: (this.container.clientWidth / 10) + "px",
                margin: "10px",
                height: "auto",
                padding: "5px 0",
                backgroundColor: "yellow",
                textAlign: "center"
            }
            // 设置box2子元素样式
            this.nameArr.forEach((value) => {
                for (let i in nameStyle){
                    value.style[i] = nameStyle[i];
                }
            })
        },
        // box3样式
        addBoxStyle3(){
            // 准备box3样式
            let box3Style = {
                width: this.container.clientWidth + "px",
                height: "auto",
                margin: "10px 0",
                padding: "10px 0",
                borderWidth: "2px",
                borderStyle: "solid",
                borderColor: "#CCC",
                display: "flex",
                justifyContent: "center",
                alignItems: "center"
            }
            // 设置box1样式
            for (let i in box3Style){
                this.box3.style[i] = box3Style[i];
            }
            // 准备btn1、btn2样式
            let btnStyle = {
                width: (this.container.clientWidth / 10) + "px",
                height: "auto",
                margin: "0 10px",
                padding: "10px 0",
                textAlign: "center",
                backgroundColor: "green",
                color: "#fff",
                border: "none",
                outline: "none",
                cursor: "pointer"
            }
            // 设置btn1样式
            for (let i in btnStyle){
                this.btn1.style[i] = btnStyle[i];
            }
            // 设置btn2样式
            for (let i in btnStyle){
                this.btn2.style[i] = btnStyle[i];
            }
        },

        // 绑定事件
        bindEvent(){
            this.bindBtnEvent1();
            this.bindBtnEvent2();
        },
        // 单选事件
        bindBtnEvent1(){
            // 绑定单选按钮点击事件
            this.btn1.addEventListener("click", () => {
                // 首先样式重置
                this.nameArr.forEach((value, index) => {
                    this.nameArr[index].style.backgroundColor = "yellow";
                    this.nameArr[index].style.color = "";
                })
                // 随机选择一个成员
                let randomName = parseInt(Math.random() * this.nameArr.length);
                // 将随机选中的成员添加样式
                this.nameArr[randomName].style.backgroundColor = "red";
                this.nameArr[randomName].style.color = "#fff";
                // 将随机选中的成员渲染到页面
                this.clickedSpan.innerText = this.nameArr[randomName].innerText;
            })
        },
        // 多选事件
        bindBtnEvent2(){
            // 绑定多选按钮点击事件
            this.btn2.addEventListener("click", () => {
                // 定义一个计数器
                let num = 0;
                // 定义一个定时器
                let timer = setInterval(() => {
                    // 首先样式重置
                    this.nameArr.forEach((value, index) => {
                        this.nameArr[index].style.backgroundColor = "yellow";
                        this.nameArr[index].style.color = "";
                    })
                    // 随机选择一个成员
                    let randomName = parseInt(Math.random() * this.nameArr.length);
                    // 计数器加1
                    num++;
                    // 将随机选中的成员添加样式
                    this.nameArr[randomName].style.backgroundColor = "red";
                    this.nameArr[randomName].style.color = "#fff";
                    // 定时器执行多次后停止
                    if(num >= this.count){
                        clearInterval(timer);
                    }
                    // 将随机选中的成员渲染到页面
                    this.clickedSpan.innerText = this.nameArr[randomName].innerText;
                }, this.duration)
            })
        },
    }
    return Roll;
})()

在这里插入图片描述


面向对象编程——进度条

HTML文件

<!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;
        }
        .box{
            position: relative;
            width: 1000px;
            height: 50px;
            border: 1px solid #ccc;
            margin: 100px auto;
        }
        .box1{
            position: relative;
            width: 500px;
            height: 50px;
            border: 1px solid #ccc;
            margin: 100px auto;
        }
    </style>
</head>
<body>
    <div id="box" class="box"></div>
    <div id="box1" class="box1"></div>
    <script src="../js/Progress.js"></script>
    <script>
        let box = document.getElementById("box");
        let pro = new Progress(box, 0.4, "red", "blue");

        let box1 = document.getElementById("box1");
        let pro1 = new Progress(box1, 0.1, "yellow");
    </script>
</body>
</html>

Progress.js文件

let Progress = (function(){
    // 参数1表示进度条容器,参数二表示初始进度(默认值为0),参数三表示进度颜色(默认值为红色),参数四表示进度按钮颜色(默认值为橙色)
    function Progress(container, start = 0, barColor = "red", btnColor = "orange"){
        this.container = container;
        this.start = start;
        this.barColor = barColor;
        this.btnColor = btnColor;
        // 进度
        this.bar = document.createElement("div");
        // 按钮
        this.btn = document.createElement("div");
        // 进度值
        this.proVal = document.createElement("div");
        // 初始进度值
        this.width = this.start * (this.container.clientWidth - this.container.clientWidth * 0.05);
        this.init();
    }
    Progress.prototype = {
        constructor: Progress,
        init(){
            this.upTree();
            this.addStyle();
            this.bindEvent();
        },
        // 元素上树
        upTree(){
            this.container.appendChild(this.bar);
            this.container.appendChild(this.btn);
            this.container.appendChild(this.proVal);
        },
        // 渲染方法
        addStyle(){
            this.addBtnStyle();
            this.addBarStyle();
            this.addProValStyle();
        },
        // 按钮样式
        addBtnStyle(){
            // 准备按钮样式
            let btnStyle = {
                position: "absolute",
                height: this.container.clientHeight + "px",
                width: this.container.clientWidth * 0.05 + "px",
                left: this.width + "px",
                backgroundColor: this.btnColor,
                cursor: "pointer"
            }
            // 设置按钮样式
            for (let i in btnStyle){
                this.btn.style[i] = btnStyle[i];
            }
        },
        // 进度样式
        addBarStyle(){
            // 准备进度样式
            let barStyle = {
                position: "absolute",
                height: this.container.clientHeight + "px",
                width: this.width + "px",
                backgroundColor: this.barColor
            }
            // 设置进度样式
            for (let i in barStyle){
                this.bar.style[i] = barStyle[i];
            }
        },
        // 进度值样式
        addProValStyle(){
            // 准备进度值样式
            let proValStyle = {
                position: "absolute",
                height: this.container.clientHeight + "px",
                width: "auto",
                left: "100%",
                textAlign: "center",
                lineHeight: this.container.clientHeight + "px",
                color: this.btn.style.backgroundColor,
                fontSize: this.container.clientHeight * 0.7 + "px"
            }
            // 设置进度值样式
            for (let i in proValStyle){
                this.proVal.style[i] = proValStyle[i];
            }
            // 显示初始进度值
            this.proVal.innerText = (this.width / (this.container.clientWidth - this.btn.offsetWidth) * 100).toFixed(2) + "%"
        },
        // 绑定事件
        bindEvent(){
            this.btnEvent();
        },
        // 按钮拖拽事件
        btnEvent(){
            // 绑定按钮点击事件
            this.btn.addEventListener("mousedown", (e) => {
                // 浏览器兼容处理
                let event = e || window.event;
                // 记录鼠标开始时点击的位置
                let startX = event.clientX;
                // 记录此时按钮的位置
                let left = this.btn.offsetLeft;
                // 绑定按钮移动事件
                document.onmousemove =  (e) => {
                    // 浏览器兼容处理
                    let event = e || window.event;
                    // 记录鼠标移动后的位置
                    let endX = event.clientX;
                    // 计算此时按钮距离左边的距离
                    let resultX = endX - startX + left;
                    // 边界值限定
                    if(resultX < 0){
                        // 限定不超出左边
                        resultX = 0;
                    }else if(resultX > this.container.clientWidth - this.btn.clientWidth){
                        // 限定不超出右边
                        resultX = this.container.clientWidth - this.btn.clientWidth;
                    }
                    // 设置鼠标移动后按钮的位置
                    this.btn.style.left = resultX + "px";
                    // 设置进度样式随着改变
                    this.bar.style.width = resultX + "px";
                    // 渲染进度值
                    this.proVal.innerText = (resultX / (this.container.clientWidth - this.btn.offsetWidth) * 100).toFixed(2) + "%";
                    console.log((resultX / (this.container.clientWidth - this.btn.offsetWidth) * 100).toFixed(2) + "%");
                }
            })
            // 绑定鼠标弹起事件
            document.addEventListener("mouseup", function() {
                // 移除按钮移动事件
                document.onmousemove = null;
            })
        }
    }
    return Progress;
})()

在这里插入图片描述


面向对象编程——简易版贪吃蛇小游戏

HTML文件

<!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;
        }
        html, body{
            width: 100%;
            height: 100%;
        }
        .container{
            margin: 0 auto;
            width: 600px;
            height: 600px;
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <div id="container" class="container"></div>
    <script src="../js/Game.js"></script>
    <script src="../js/Map.js"></script>
    <script src="../js/Snake.js"></script>
    <script src="../js/Food.js"></script>
    <script>
        let container = document.getElementById("container");
        let map = new Map(container.clientWidth, container.clientHeight, 20, 20, "#4d4d4d");
        let snake = new Snake("red");
        let food = new Food(5, 5, "yellow");
        let game = new Game(container, map, snake, food, "hard");
    </script>
</body>
</html>

Game.js文件

function Game(container, map, snake, food, level){
    // 容器
    this.container = container;
    // 地图
    this.map = map;
    // 蛇
    this.snake = snake;
    // 食物
    this.food = food;
    // 等级(定时器时间间隔)
    this.interval = level === "hard" ? 100 : level === "easy" ? 500 : 250; 
    // 定时器
    this.timer = null;
    this.flag = false;
    // 初始化
    this.init();
}

// 渲染地图
Game.prototype = {
    constructor: Game,
    init(){
        this.renderMap();
        this.renderSnake();
        this.bindEvent();
        this.start();
    },
    renderMap(){
        this.container.appendChild(this.map.dom);
        // this.container.appendChild(this.map.controls);
    },
    renderSnake(){
        // 根据蛇的坐标,更改地图样式
        this.snake.arr.forEach(({x, y}) => {
            this.map.arr[x][y].style.backgroundColor = this.snake.snakeColor;
        })
    },
    renderFood(){
        let {x, y} = this.food;
        this.map.arr[x][y].style.backgroundColor = this.food.foodColor;
    },

    bindEvent() {
        document.addEventListener("keydown", (e) => {
            // 只有按下 ↑ ↓ ← →这几个键的时候 或者 w s a d这几个键时 改变蛇的方向
            switch (e.keyCode) {
                case 65:
                case 87:
                case 83:
                case 68:
                case 37:
                case 38:
                case 39:
                case 40:
                    this.snake.switchDirection(e.keyCode);
                break;
            }
        })
    },
    
    // 检测
    check(){
        // 地图边界检测
        this.checkMap();
        // 吃到食物检测
        this.checkFood();
        // 撞到自己检测
        this.checkSnake();
    },
    // 地图边界检测
    checkMap(){
        // 获取蛇头的坐标
        let x = this.snake.arr.slice(-1)[0].x;
        let y = this.snake.arr.slice(-1)[0].y;
        // 检测是否达到地图边界
        if(x < 0 || x >= this.map.row || y < 0 || y >= this.map.col){
            // 游戏结束
            this.gameover();
        }
    },
    // 吃到食物检测
    checkFood(){
        // 获取蛇头部坐标
        let snakeHeadX = this.snake.arr.slice(-1)[0].x;
        let snakeHeadY = this.snake.arr.slice(-1)[0].y;
        // 获取食物坐标
        let foodX = this.food.x;
        let foodY = this.food.y;
        if(snakeHeadX === foodX && snakeHeadY === foodY){
            // 吃到食物,变长
            this.snake.growUp();
            // 重置食物
            this.resetFood();
        }
    },
    // 撞到自己检测
    checkSnake(){
        // 把蛇分为头部和身体两部分
        // 蛇头坐标
        let x = this.snake.arr.slice(-1)[0].x;
        let y = this.snake.arr.slice(-1)[0].y;
        // 蛇身体
        let bodyArr = this.snake.arr.slice(0, -1);
        let isExist = bodyArr.some((value) => {
            return value.x === x && value.y === y;
        })
        // 判断是否撞到自己
        if(isExist){
            // 游戏结束
            this.gameover();
        }
    },

    // 添加事件
    start(){
        this.flag = true;
        this.timer = setInterval(() => {
            // 蛇移动
            this.snake.move();
            // 检测
            this.check();
            if(!this.flag){
                clearInterval(this.timer);
                return;
            }
            // 清除屏幕
            this.map.clear();
            // 重新渲染蛇
            this.renderSnake();
            // 重新渲染食物
            this.renderFood();
        }, this.interval)
    },

    // 游戏结束
    gameover(){
        this.flag = false;
    },

    // 重置食物
    resetFood(){
        // 重新获取一个食物坐标
        let x = parseInt(Math.random() * this.map.col);
        let y = parseInt(Math.random() * this.map.row);
        // 判定食物是否落在蛇身上
        let isExist = this.snake.arr.some((value) => {
            return value.x === x && value.y === y;
        })
        if(isExist){
            // 重新重置食物
            this.resetFood();
            return;
        }
        this.food.x = x;
        this.food.y = y;
    }
}

Map.js文件

// 参数一表示容器宽度。参数二表示容器高度,参数三表示地图行数,参数四表示地图列数,参数五表示地图颜色
function Map(width, height, row, col, mapColor = "#444"){
    this.width = width;
    this.height = height;
    this.row = row;
    this.col = col;
    this.mapColor = mapColor;
    // 创建地图容器
    this.dom = document.createElement("div");
    // 定义数组,方便获取每一列元素,是一个二维数组
    this.arr = [];
    // 定义数组,用于存放行元素
    this.rowArr = [];
    // 初始化
    this.init();
}
Map.prototype = {
    constructor: Map,
    init(){
        this.create();
        // this.createControls();
        this.addStyle();
    },
    // 创建地图
    create(){
        // 循环创建行
        for (let i = 0; i < this.row; i++){
            // 定义行元素
            let rowElement = document.createElement("div");
            // 将rowElement追加到rowArr数组中
            this.rowArr.push(rowElement);
            // 定义数组,用于存放列元素
            let colArr = [];
            // 循环创建列
            for (let j = 0; j < this.col; j++){
                // 定义列元素
                let colElement = document.createElement("div");
                // 将corElement追加到rowElement中
                rowElement.appendChild(colElement);
                // 将corElement追加到colArr数组中
                colArr.push(colElement);
            }
            // 内层循环结束,将colArr追加到arr数组中
            this.arr.push(colArr);
            // 将rowElement追加到map中
            this.dom.appendChild(rowElement);
        }
    },

    // 添加样式
    addStyle(){
        this.addMapStyle();
        this.addRowStyle();
        this.addColStyle();
    },
    // 添加map样式
    addMapStyle(){
        // 准备Map样式
        let mapStyle = {
            width: "100%",
            height: "100%",
            backgroundColor: this.mapColor
        }
        // 设置Map样式
        for (let i in mapStyle){
            this.dom.style[i] = mapStyle[i];
        }
    },
    // 添加行样式
    addRowStyle(){
        // 准备行样式
        let rowStyle = {
            width: "100%",
            height: 100 / this.row + "%",
            borderBottom: "1px solid #CCC",
            boxSizing: "border-box"
        }
        // 设置行样式
        for (let i in rowStyle){
            for (let j = 0; j < this.rowArr.length; j++){
                this.rowArr[j].style[i] = rowStyle[i];
            }
        }
        // 设置最后一行没有下边框
        this.rowArr.slice(-1)[0].style.borderBottom = "none";
    },
    // 添加列样式
    addColStyle(){
        // 准备列样式
        let colStyle = {
            float: "left",
            width: 100 / this.col + "%",
            height: "100%",
            borderRight: "1px solid #ccc",
            boxSizing: "border-box"
        }
        // 设置列样式
        this.arr.forEach((value) => {
            value.forEach((value) => {
                for (let i in colStyle){
                    value.style[i] = colStyle[i];
                }
            })
            // 设置最后一列没有右边框
            value.slice(-1)[0].style.borderRight = "none";
        })
    },
    // 添加控制面板样式
    addControlsStyle(){
        // 准备控制面板样式
        let controlsStyle = {
            width: "100%",
            height: "10%",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            backgroundColor: "#CCC"
        }
        // 设置控制面板样式
        for (let i in controlsStyle){
            this.controls.style[i] = controlsStyle[i];
        }
    },

    // 蛇移动后,清除屏幕(重置地图样式)
    clear(){
        this.arr.forEach((value) => {
            value.forEach((value) => {
                value.style.backgroundColor = this.mapColor;
            })
        })
    },
}

Snake.js文件

function Snake(snakeColor = "red"){
    // 蛇的颜色
    this.snakeColor = snakeColor;
    // 设置蛇的起始长度和位置
    this.arr = [{x: 0, y: 0}, {x: 0, y: 1}];
    // 设置蛇默认的运动方向,上下左右分别是U\D\L\R
    this.direction = "R";
    // 设置锁
    this.lock = true;
    this.init();
}
Snake.prototype = {
    constructor: Snake,
    init(){
        this.move();
        this.switchDirection();
    },

    // 判断键盘事件,确定运动方向
    switchDirection(code){
        // 判断锁状态,在蛇的上一步运动结束后,才能改变蛇的下一步运动方向
        if(!this.lock){
            return;
        }
        // 键盘事件
        // 如果传递的是W或者↑,表示向上运动,并且向上运动时不能直接180度掉头向下运动
        // 如果传递的是S或者↓,表示向下运动,并且向下运动时不能直接180度掉头向上运动
        // 如果传递的是A或者←,表示向左运动,并且向左运动时不能直接180度掉头向右运动
        // 如果传递的是D或者→,表示向右运动,并且向右运动时不能直接180度掉头向左运动
        if((code === 87 || code === 38) && this.direction != "D"){
            this.direction = "U";
        } else if ((code === 83 || code === 40) && this.direction != "U"){
            this.direction = "D";
        } else if ((code === 65 || code === 37) && this.direction != "R"){
            this.direction = "L";
        } else if ((code === 68 || code === 39) && this.direction != "L"){
            this.direction = "R";
        }
        this.lock = false;
    },

    // 蛇运动
    // 蛇的头部是数组的最后一个成员,蛇的尾部是数组的第一个成员
    // 蛇默认向右运动,蛇运动的时候,可以看做是将蛇的尾巴去掉,添加新的蛇头
    move(){
        // 去掉蛇尾
        this.arr.shift();
        // 定义新蛇头
        let newHead = {
            x: this.arr[this.arr.length - 1].x,
            y: this.arr[this.arr.length - 1].y
        }
        // 根据运动方向确定新蛇头的位置
        // 如果向右 y + 1
        // 如果向左 y - 1
        // 如果向上 x - 1
        // 如果向下 x + 1
        if (this.direction === "R"){
            newHead.y++;
        } else if(this.direction === "L"){
            newHead.y--;
        } else if(this.direction === "U"){
            newHead.x--;
        } else if(this.direction === "D"){
            newHead.x++;
        }
        // 将新位置追加到数组
        this.arr.push(newHead);
        // 开锁
        this.lock = true;
    },

    // 蛇吃到食物,身体边长
    growUp(){
        // 在蛇尾添加一个成员
        let newTail = {
            x: this.arr[0].x,
            y: this.arr[0].y
        }
        this.arr.unshift(newTail);
        // console.log(this.arr.length)
    }
}

Food.js文件

// 参数一表示第一次食物在x上的位置,参数二表示第一次食物在y上的位置,参数三表示食物颜色
function Food(x = 0, y = 3, foodColor = "green"){
    this.x = x;
    this.y = y;
    this.foodColor = foodColor;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值