浪漫博主使用 Javascript 做了个表白工具,最后升华了

浪漫博主使用 Javascript 做了个表白工具,最后升华了_第1张图片

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

前言

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

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

文章目录

  • 实现30x30的格子
  • 点击变色,并记录坐标信息
  • 数据复位与复制功能
  • 全部代码(去注释版)
  • 结束语

实现30x30的格子

浪漫博主使用 Javascript 做了个表白工具,最后升华了_第2张图片

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>
    
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    
    <link rel="stylesheet" href="./index.css">
head>

<body>
    <div id="app">
        
        <table>
            
            <tr v-for="i in 30" :name="i">
                
                <td v-for="i in 30">td>
            tr>
        table>
        
    div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue@2">script>
    
    <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'
})

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

效果
浪漫博主使用 Javascript 做了个表白工具,最后升华了_第3张图片

html

<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>
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>
        
        <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">Copybutton>
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/[email protected]/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">Copybutton>
    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 做了个表白工具,最后升华了_第4张图片

你可能感兴趣的:(创作,javascript,vue.js,前端)