作者:大二计算机学生 王 子
主页:点击关注
关键词:JavaScript
,vue
,浪漫
前言
大家好啊,熟悉我的小伙伴可能都知道,博主是一个浪漫的程序猿,手动狗头,今天突发奇想,使用 js 写了一个表白工具,我们可以浪漫的同时完成 js 的学习,何乐而不为呢?愣着干嘛!快开始吧
浪漫猿使用 Javascript 做了个表白工具
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'
})
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>
这个案例,当时自己想着玩的,感觉有意思,就写了,中途还遇到了很多问题,发现了自己的不足,如果你也能独立的写出来,恭喜你,真的很棒,其实我们发现,我们这个案例通过数据来记录视图,你发现了,只要我们都是用这个工具,我有信息要传递时,发给你一些数据就可以了,那你再思考,图片的信息存储原理不也是这样吗?只不过它使用了二进制数据,仔细想,其实数据可以通过规定渲染出任何能想到的效果,你说对吗?啥?跑题了,