作者:大二计算机学生 王 子
主页:点击关注 😆
关键词:JavaScript
,
vue
,
浪漫
前言
大家好啊,熟悉我的小伙伴可能都知道,博主是一个浪漫的程序猿,手动狗头,今天突发奇想,使用 js 写了一个表白工具,我们可以浪漫的同时完成 js 的学习,何乐而不为呢?愣着干嘛!快开始吧 🍉
浪漫猿使用 Javascript 做了个表白工具
文章目录
实现30x30的格子
html
html结构通过vue快速遍历出
30 x 30
大小的表格
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>模拟图片</title><!-- 引入bootstrap的css,主要使用了按钮美化 --><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"rel="stylesheet"><!-- 引入自定义css --><linkrel="stylesheet"href="./index.css"></head><body><divid="app"><!-- 使用表格 --><table><!-- 使用v-for遍历行 --><trv-for="i in 30":name="i"><!-- 使用v-for遍历列 --><tdv-for="i in 30"></td></tr></table><!-- 代码执行完成会有30x30的表格,剩下的就是css美化了 --></div><!-- 引入vue --><scriptsrc="https://cdn.jsdelivr.net/npm/vue@2"></script><!-- 引入自定义js --><scriptsrc="./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对象newVue({// 让vue管理#app的上下文el:'#app'})
点击变色,并记录坐标信息
效果
html
<divid="app"><!-- 使用表格 --><table><!-- 使用v-for遍历行 --><trv-for="i in 30":name="i"><!-- 使用v-for遍历列 添加点击事件 --><tdv-for="i in 30"@click="changeBg($event)"></td></tr></table><!-- 代码执行完成会有30x30的表格,剩下的就是css美化了 --><!-- 用来展示位点 双向绑定pointStr --><textareav-show="pointStr != ''"id="point"cols="30"rows="10"v-model="pointStr"></textarea></div>
js
js部分是最关键的部分,因为有很多位点,首先想到的
存储结构
就是
数组对象
,然后就是遍历所有格,一旦背景颜色为red,就加入到数组对象,进行
管理
,这里注意每次是需要
重置
数组对象的,不然就会一直叠加,数据就被
污染
了
// 实例vue对象newVue({// 让vue管理#app的上下文el:'#app',data:{// 数组对象,用于存储位点x,y,颜色信息xyArr:[],// 格式化点位 jsonpointStr:[]},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++){// 判断,如果当前点背景颜色为redif(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部分就是简单的新增一个导入按钮和复制按钮,并添加相应事件
<divid="app"><!-- 使用表格 --><table><!-- 使用v-for遍历行 --><trv-for="i in 30":name="i"><!-- 使用v-for遍历列 添加点击事件 --><tdv-for="i in 30"@click="changeBg($event)"></td></tr></table><!-- 代码执行完成会有30x30的表格,剩下的就是css美化了 --><!-- 用来展示位点 双向绑定pointStr --><textareav-show="pointStr != ''"id="point"cols="30"rows="10"v-model="pointStr"></textarea><!-- 导入按钮 --><buttonv-show="pointStr != ''"type="button"class="btn btn-outline-primary"@click="readPoint">导入位点</button><!-- 复制按钮 --><buttonv-show="pointStr != ''"type="button"class="btn-sm btn btn-outline-success"@click="copyPoint">Copy</button></div>
js
这里先把数组拼接成
json格式
的
字符串
,然后转成
JavaScript对象
,方便获取信息进行操作,之后就是
获取坐标
,使用
dom api
进行查找,找到后改变颜色,就完成了,是不是很棒呢 😆
// 实例vue对象newVue({// 让vue管理#app的上下文el:'#app',data:{// 数组对象,用于存储位点x,y,颜色信息xyArr:[],// 格式化点位 jsonpointStr:[]},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++){// 判断,如果当前点背景颜色为redif(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");}}})
全部代码(去注释版)
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>模拟图片</title><linkhref="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><divid="app"><table><trv-for="i in 30":name="i"><tdv-for="i in 30"@click="changeBg($event)"></td></tr></table><textareav-show="pointStr != ''"id="point"cols="30"rows="10"v-model="pointStr"></textarea><buttonv-show="pointStr != ''"type="button"class="btn btn-outline-primary"@click="readPoint">导入位点</button><buttonv-show="pointStr != ''"type="button"class="btn-sm btn btn-outline-success"@click="copyPoint">Copy</button></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue@2"></script><script>newVue({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>
结束语
这个案例,当时自己想着玩的,感觉有意思,就写了,中途还遇到了很多问题,发现了自己的不足,如果你也能独立的写出来,恭喜你,真的很棒,其实我们发现,我们这个案例通过数据来记录视图,你发现了,只要我们都是用这个工具,我有信息要传递时,发给你一些数据就可以了,那你再思考,图片的信息存储原理不也是这样吗?只不过它使用了二进制数据,仔细想,其实数据可以通过规定渲染出任何能想到的效果,你说对吗?啥?跑题了,
哈哈,对了,快给对象发送一条爱心的数据吧,生活不止代码,还有诗和远方👋🏼👋🏼👋🏼
版权归原作者 王 子 所有, 如有侵权,请联系我们删除。