作者:大二计算机学生 王 子 主页:点击关注 😆 关键词:JavaScript ,vue ,浪漫
前言
大家好啊,熟悉我的小伙伴可能都知道,博主是一个浪漫的程序猿,手动狗头,今天突发奇想,使用 js 写了一个表白工具,我们可以浪漫的同时完成 js 的学习,何乐而不为呢?愣着干嘛!快开始吧 🍉
实现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>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/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的上下文
new Vue({
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,就加入到数组对象,进行管理 ,这里注意每次是需要重置 数组对象的,不然就会一直叠加,数据就被污染 了
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));
});
}
}
})
数据复位与复制功能
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">Copy</button>
</div>
js
这里先把数组拼接成json格式 的字符串 ,然后转成JavaScript对象 ,方便获取信息进行操作,之后就是获取坐标 ,使用dom api 进行查找,找到后改变颜色,就完成了,是不是很棒呢 😆
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");
}
}
})
全部代码(去注释版)
<!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>
结束语
这个案例,当时自己想着玩的,感觉有意思,就写了,中途还遇到了很多问题,发现了自己的不足,如果你也能独立的写出来,恭喜你,真的很棒,其实我们发现,我们这个案例通过数据来记录视图,你发现了,只要我们都是用这个工具,我有信息要传递时,发给你一些数据就可以了,那你再思考,图片的信息存储原理不也是这样吗?只不过它使用了二进制数据,仔细想,其实数据可以通过规定渲染出任何能想到的效果,你说对吗?啥?跑题了,
哈哈,对了,快给对象发送一条爱心的数据吧,生活不止代码,还有诗和远方👋🏼👋🏼👋🏼
|