IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 浪漫博主使用 Javascript 做了个表白工具,最后升华了 -> 正文阅读

[JavaScript知识库]浪漫博主使用 Javascript 做了个表白工具,最后升华了

在这里插入图片描述

作者:大二计算机学生 王 子
主页:点击关注 😆
关键词:JavaScriptvue浪漫

前言

大家好啊,熟悉我的小伙伴可能都知道,博主是一个浪漫的程序猿,手动狗头,今天突发奇想,使用 js 写了一个表白工具,我们可以浪漫的同时完成 js 的学习,何乐而不为呢?愣着干嘛!快开始吧 🍉

浪漫猿使用 Javascript 做了个表白工具

实现30x30的格子

在这里插入图片描述

html

html结构通过vue快速遍历出 30 x 30 大小的表格

<!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">
    <title>模拟图片</title>
    <!-- 引入bootstrap的css,主要使用了按钮美化 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- 引入自定义css -->
    <link rel="stylesheet" href="./index.css">
</head>

<body>
    <div id="app">
        <!-- 使用表格 -->
        <table>
            <!-- 使用v-for遍历行 -->
            <tr v-for="i in 30" :name="i">
                <!-- 使用v-for遍历列 -->
                <td v-for="i in 30"></td>
            </tr>
        </table>
        <!-- 代码执行完成会有30x30的表格,剩下的就是css美化了 -->
    </div>
    <!-- 引入vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <!-- 引入自定义js -->
    <script src="./re.js"></script>
</body>

</html>

css

使用到的全部css样式,下面就不再说css文件了

#app {
    position: relative;
    min-height: 100vh;
}

table {
    position: absolute;
    top: 50%;
    left: 20%;
    transform: translatey(-50%);
    border-collapse: collapse;
}

tbody,
td,
tfoot,
th,
thead,
tr {
    border-width: 1px;
}

td {
    width: 15px;
    height: 15px;
}

textarea {
    position: absolute;
    top: 130px;
    right: 410px;
    width: 350px;
    height: 453px;
    resize: none;
    outline: none;
    border-radius: 10px;
    color: #ccc;
}

.btn-outline-primary{
    position: absolute;
    top: 530px;
    right: 430px;
}
.btn-outline-success{
    position: absolute;
    top: 140px;
    right: 430px;
}

js

实例vue管理id为app的上下文

// 实例vue对象
new Vue({
    // 让vue管理#app的上下文
    el: '#app'
})

点击变色,并记录坐标信息

效果
在这里插入图片描述

html

<div id="app">
    <!-- 使用表格 -->
    <table>
        <!-- 使用v-for遍历行 -->
        <tr v-for="i in 30" :name="i">
            <!-- 使用v-for遍历列 添加点击事件 -->
            <td v-for="i in 30" @click="changeBg($event)"></td>
        </tr>
    </table>
    <!-- 代码执行完成会有30x30的表格,剩下的就是css美化了 -->
    <!-- 用来展示位点 双向绑定pointStr -->
    <textarea v-show="pointStr != ''" id="point" cols="30" rows="10" v-model="pointStr"></textarea>
</div>

js

js部分是最关键的部分,因为有很多位点,首先想到的存储结构就是数组对象,然后就是遍历所有格,一旦背景颜色为red,就加入到数组对象,进行管理,这里注意每次是需要重置数组对象的,不然就会一直叠加,数据就被污染

// 实例vue对象
new Vue({
    // 让vue管理#app的上下文
    el: '#app',
    data: {
        // 数组对象,用于存储位点x,y,颜色信息
        xyArr: [],
        // 格式化点位 json
        pointStr: []
    },
    methods: {
        // 记录点位
        changeBg(e) {
            // 使用事件对象e获取当前dom信息
            // 判断背景颜色是否为red如果是就变为白色,否则就是红色
            if (e.target.style.backgroundColor == "red") {
                e.target.style.backgroundColor = "#FFF";
            } else {
                e.target.style.backgroundColor = "red";
            }
            // 重置数据
            this.xyArr.length = 0;
            this.pointStr.length = 0;
            // 获取所有行
            trs = document.querySelectorAll("tr")
            // 遍历所有行
            for (let i = 0; i < trs.length; i++) {
                // 获取当前行下所有类
                tds = trs[i].querySelectorAll("td");
                // 遍历当前行下所有列
                for (let j = 0; j < tds.length; j++) {
                    // 判断,如果当前点背景颜色为red
                    if (tds[j].style.backgroundColor == "red") {
                        // 就把它存入数组,使用json格式
                        this.xyArr.push({
                            "x": (j + 1),
                            // 这里使用父节点,并获取属性,使用getAttribute("属性名")
                            "y": tds[j].parentNode.getAttribute("name"),
                            "bg": tds[j].style.backgroundColor
                        })
                    }
                }
            }
            // 遍历所有的有效点位,再进行格式化,存入pointStr,进行展示
            this.xyArr.forEach(xyObj => {
                this.pointStr.push(JSON.stringify(xyObj));
            });
        }
    }
})

数据复位与复制功能

html

html部分就是简单的新增一个导入按钮和复制按钮,并添加相应事件

<div id="app">
    <!-- 使用表格 -->
    <table>
        <!-- 使用v-for遍历行 -->
        <tr v-for="i in 30" :name="i">
            <!-- 使用v-for遍历列 添加点击事件 -->
            <td v-for="i in 30" @click="changeBg($event)"></td>
        </tr>
    </table>
    <!-- 代码执行完成会有30x30的表格,剩下的就是css美化了 -->
    <!-- 用来展示位点 双向绑定pointStr -->
    <textarea v-show="pointStr != ''" id="point" cols="30" rows="10" v-model="pointStr"></textarea>
    <!-- 导入按钮 -->
    <button v-show="pointStr != ''" type="button" class="btn btn-outline-primary" @click="readPoint">导入位点</button>
    <!-- 复制按钮 -->
    <button v-show="pointStr != ''" type="button" class="btn-sm btn btn-outline-success" @click="copyPoint">Copy</button>
</div>

js

这里先把数组拼接成json格式字符串,然后转成JavaScript对象,方便获取信息进行操作,之后就是获取坐标,使用dom api进行查找,找到后改变颜色,就完成了,是不是很棒呢 😆

// 实例vue对象
new Vue({
    // 让vue管理#app的上下文
    el: '#app',
    data: {
        // 数组对象,用于存储位点x,y,颜色信息
        xyArr: [],
        // 格式化点位 json
        pointStr: []
    },
    methods: {
        // 记录点位
        changeBg(e) {
            // 使用事件对象e获取当前dom信息
            // 判断背景颜色是否为red如果是就变为白色,否则就是红色
            if (e.target.style.backgroundColor == "red") {
                e.target.style.backgroundColor = "#FFF";
            } else {
                e.target.style.backgroundColor = "red";
            }
            // 重置数据
            this.xyArr.length = 0;
            this.pointStr.length = 0;
            // 获取所有行
            trs = document.querySelectorAll("tr")
            // 遍历所有行
            for (let i = 0; i < trs.length; i++) {
                // 获取当前行下所有类
                tds = trs[i].querySelectorAll("td");
                // 遍历当前行下所有列
                for (let j = 0; j < tds.length; j++) {
                    // 判断,如果当前点背景颜色为red
                    if (tds[j].style.backgroundColor == "red") {
                        // 就把它存入数组,使用json格式
                        this.xyArr.push({
                            "x": (j + 1),
                            // 这里使用父节点,并获取属性,使用getAttribute("属性名")
                            "y": tds[j].parentNode.getAttribute("name"),
                            "bg": tds[j].style.backgroundColor
                        })
                    }
                }
            }
            // 遍历所有的有效点位,再进行格式化,存入pointStr,进行展示
            this.xyArr.forEach(xyObj => {
                this.pointStr.push(JSON.stringify(xyObj));
            });
        },
        // 读取点位
        readPoint() {
            // 先使用拼接字符串把数据包装成json对象数组的字符串
            let jsonstr = '[' + this.pointStr + ']';
            // 把json字符串转换位JavaScript对象
            let obj = JSON.parse(jsonstr);
            // 获取所有行
            let trs = document.querySelectorAll("tr");
            // 遍历对象
            obj.forEach(df => {
                // 获取对象的y坐标
                let tds = trs[df.y - 1].querySelectorAll("td");
                // 同时y对应的x坐标的背景颜色变为红色,即实现了数据的复位
                tds[df.x - 1].style.backgroundColor = "red";
            })
        },
        // 复制点位
        copyPoint() {
            // 获取textarea
            point = document.querySelector("#point");
            // 选择textarea
            point.select();
            // 使用api进行复制
            document.execCommand("copy");
        }
    }
})

全部代码(去注释版)

<!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">
    <title>模拟图片</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        #app {
            position: relative;
            min-height: 100vh;
        }

        table {
            position: absolute;
            top: 50%;
            left: 20%;
            transform: translatey(-50%);
            border-collapse: collapse;
        }

        tbody,
        td,
        tfoot,
        th,
        thead,
        tr {
            border-width: 1px;
        }

        td {
            width: 15px;
            height: 15px;
        }

        textarea {
            position: absolute;
            top: 130px;
            right: 410px;
            width: 350px;
            height: 453px;
            resize: none;
            outline: none;
            border-radius: 10px;
            color: #ccc;
        }

        .btn-outline-primary {
            position: absolute;
            top: 530px;
            right: 430px;
        }

        .btn-outline-success {
            position: absolute;
            top: 140px;
            right: 430px;
        }
    </style>
</head>

<body>
    <div id="app">
        <table>
            <tr v-for="i in 30" :name="i">
                <td v-for="i in 30" @click="changeBg($event)"></td>
            </tr>
        </table>
        <textarea v-show="pointStr != ''" id="point" cols="30" rows="10" v-model="pointStr"></textarea>
        <button v-show="pointStr != ''" type="button" class="btn btn-outline-primary" @click="readPoint">导入位点</button>
        <button v-show="pointStr != ''" type="button" class="btn-sm btn btn-outline-success"
            @click="copyPoint">Copy</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                xyArr: [],
                pointStr: []
            },
            methods: {
                changeBg(e) {
                    if (e.target.style.backgroundColor == "red") {
                        e.target.style.backgroundColor = "#FFF";
                    } else {
                        e.target.style.backgroundColor = "red";
                    }
                    this.xyArr.length = 0;
                    this.pointStr.length = 0;
                    trs = document.querySelectorAll("tr")
                    for (let i = 0; i < trs.length; i++) {
                        tds = trs[i].querySelectorAll("td");
                        for (let j = 0; j < tds.length; j++) {
                            if (tds[j].style.backgroundColor == "red") {
                                this.xyArr.push({
                                    "x": (j + 1),
                                    "y": tds[j].parentNode.getAttribute("name"),
                                    "bg": tds[j].style.backgroundColor
                                })
                            }
                        }
                    }
                    this.xyArr.forEach(xyObj => {
                        this.pointStr.push(JSON.stringify(xyObj));
                    });
                },
                readPoint() {
                    let jsonstr = '[' + this.pointStr + ']';
                    let obj = JSON.parse(jsonstr);
                    let trs = document.querySelectorAll("tr");
                    obj.forEach(df => {
                        let tds = trs[df.y - 1].querySelectorAll("td");
                        tds[df.x - 1].style.backgroundColor = "red";
                    })
                },
                copyPoint() {
                    point = document.querySelector("#point");
                    point.select();
                    document.execCommand("copy");
                }
            }
        })
    </script>
</body>

</html>

结束语

这个案例,当时自己想着玩的,感觉有意思,就写了,中途还遇到了很多问题,发现了自己的不足,如果你也能独立的写出来,恭喜你,真的很棒,其实我们发现,我们这个案例通过数据来记录视图,你发现了,只要我们都是用这个工具,我有信息要传递时,发给你一些数据就可以了,那你再思考,图片的信息存储原理不也是这样吗?只不过它使用了二进制数据,仔细想,其实数据可以通过规定渲染出任何能想到的效果,你说对吗?啥?跑题了,

哈哈,对了,快给对象发送一条爱心的数据吧,生活不止代码,还有诗和远方👋🏼👋🏼👋🏼
在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 18:57:17  更:2022-06-08 18:57:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:32:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码