一个简单的信封表白程序由前端原生js + 后端nodejs(接收邮件)

程序体验

  • 地址:http://love.hzzy.xyz/ (手机访问效果更加)

前端介绍

如果点击了跳动的爱心,会开始放烟花来庆祝,否则退出程序到信封页面

表白信封下面的两颗心代表同意和拒绝,会发送请求给后端,进行邮件通知。

// 点击爱心发送请求
// type:0 点击了爱心,type:1 点击了心碎
// email: 点击心后将发送通知邮箱告知是否表白成功
agree.onclick = function() {console.log('爱心发送~接受爱意');let type = 0let email = '3067881369@qq.com'request(type, email).then(res=> {// console.log(res)if(res.data.code == 200) {// 开始放烟花fireworks()localStorage.setItem('isok', true)document.querySelector('.love_wrap').remove()}})hint('对方已经收到你的心意~')
}
cancel.onclick = function() {console.log('爱心发送~拒绝爱意');let type = 1let email = '3067881369@qq.com'request(type, email).then(res=> {// console.log(res)hint('来日方长,江湖再见~')localStorage.setItem('isok', false)document.querySelector('.love_wrap').remove()document.querySelector('.wrap_books').classList.add('removesDispaly')close()})
}

// 这里发送请求采用的axios模块,封装一个promise
<script src="./public/axios.min.js"></script>
function request(type, email) {return new Promise((resolve, reject) => {axios({method: 'get',//提交方法url: 'http://124.223.198.104:3123/api/smsemail',//提交地址params: {type,email}}).then(res => {resolve(res)}).catch(err => {reject(err)})})
}

爱心只可点一次,会记录本地存储(机会只有一次),如果再想点的话,就得清空浏览器或者微信缓存

烟花效果的实现

const list = ["red", "yellow", "green", "blue", "orange", "black","LightPink","Magenta","DarkSlateBlue","MediumBlue","DoderBlue","PaleGodenrod","Salmon","IndianRed","Maroon","DimGray","OrangeRed","LightSalmon","Chocolate","DarkGreen","Lime","Gold","Magenta","LawnGreen","MediumBlue","RoyalBlue","PaleGreen","SeaGreen","Turquoise","DarkTurquoise","DeepSkyBlue","Aqua","LightGoldenrodYellow"]; //颜色var Number = 30 //数量  太大会奔溃
var magnitude = 200 //绽放大小范围 PX
const size = [10, 15] //小球大小范围 PX
const velocity = 1;  //停留时间  S
var timeli = 0.5;  //烟花发射速度 S
var sotp = false  //停止烟花
var timeList ; //计时器
function method(x, y,e) {const box = document.createElement("div");box.className = 'div'box.id = 'item'+ebox.style.left = x + "px";box.style.top = y + "px";box.style.width = magnitude + "px"box.style.height = magnitude + "px"document.querySelector('.wrap_books').appendChild(box);const div = document.getElementById(`item${e}`)for (let i = 0; i < Number; i++) {const index = Math.floor(Math.random() * list.length);const a = Math.floor(Math.random() * (size[0] - size[1])) + size[1]const color = list[index];const bondsman = document.createElement("span");bondsman.classList.add("bondsman");bondsman.style.background = color;bondsman.style.left = '50%';bondsman.style.top = '50%';bondsman.style.width = a + 'px';bondsman.style.height = a + 'px';bondsman.style.transition = velocity + 's';bondsman.style.opacity = 0div.appendChild(bondsman);}const time = velocity * 1000const span = div.getElementsByClassName("bondsman");setTimeout(() => {for (let i = 0; i < span.length; i++) {if (Math.round(Math.random())) {span[i].style.left = Math.floor(Math.random() * (100 - 0)) + 0 + '%'span[i].style.top = Math.floor(Math.random() * (100 - 0)) + 0 + '%'span[i].style.opacity = 1} else {span[i].style.left = Math.floor(Math.random() * (100 - 0)) + 0 + '%'span[i].style.top = Math.floor(Math.random() * (100 - 0)) + 0 + '%'span[i].style.opacity = 1}setTimeout(() => {span[i].style.opacity = 0;}, time / 2)}}, 100)setTimeout(() => {document.querySelector('.wrap_books').removeChild(div)}, time + 100)
}
function wire(e) {return new Promise((resolve)=>{const box = document.createElement("div");box.className = 'span'box.id = 'index'+ebox.style.left = Math.floor(Math.random() * (90 - 10)) + 10 + '%'box.style.top = '100%'box.style.transition = velocity + 's'box.opacity = 0;document.querySelector('.wrap_books').appendChild(box);const span = document.getElementById(`index${e}`)setTimeout(() => {span.style.top = Math.floor(Math.random() * (50 - 15)) + 15 + '%'}, 200)setTimeout(() => {span.opacity = 1;}, 300)setTimeout(() => {let data = {span:span,e:e}resolve(data)}, velocity * 1000 + 100)})
}function fireworks(){I = 0timeList = setInterval(() => {wire(I++).then((data)=>{method(data.span.offsetLeft, data.span.offsetTop,data.e)setTimeout(()=>{document.querySelector('.wrap_books').removeChild(data.span)},100)})}, timeli*1000)
}function closefireworks(){clearInterval(timeList)stop = false
}

烟花效果展示

后端介绍

后端使用`express`框架搭建服务,发送邮箱使用 `nodemailer` 模块,跨域采用`cors`模块

const express = require('express')
const nodemailer = require('nodemailer');
const cors = require('cors')
const app = express()
app.use(cors())
var options;
app.get('/api/smsemail', async(req, res) => {console.log(req.query)const email = req.query.emaillet mailTransport = nodemailer.createTransport({// host: 'smtp.qq.email',service: 'qq',secure: true,    //安全方式发送,建议都加上auth: {"user": '2585717148@qq.com',      // 你自己的邮箱的邮箱地址"pass": 'oipsiempoxwveabh'}})if (req.query.type === "0") {options = {from: '2585717148@qq.com', // 发件人地址to: email, // 收件人地址,多个收件人可以使用逗号分隔subject: 'hzzy表白邮箱', // 邮件标题bcc: '密送',html: `<h1>恭喜</h1><p style="font-size: 18px;color:#000;">对方接受了您的爱意</p>`}} else {options = {from: '2585717148@qq.com', // 发件人地址to: email, // 收件人地址,多个收件人可以使用逗号分隔subject: 'hzzy表白邮箱', // 邮件标题bcc: '密送',html: `<h1>别灰心</h1><p style="font-size: 18px;color:#000;">来日方长,江湖再见</p>`}}mailTransport.sendMail(options, function (err, msg) {if (err) {console.log(err);res.send({code: '201',message: "发送失败"});} else {res.send({code: '200',message: '心意已转达~'});}})
})app.listen(3123, () => {console.log('running...');
})

部署

小编在腾讯云买的服务器,前端建了站点挂载静态页面,后端使用pm2管理进程

推荐工具–草料二维码

  • 草料二维码

将部署好的前端项目地址生成二维码,然后发送给爱慕已久的女神,诚意满满~

完整项目地址

  • see github

原生js + 后端nodejs实现邮箱信封表白程序相关推荐

  1. 【前端路由原理--原生JS实现方式】--前后端路由的区别、关于单页面应用与多页面应用、什么是CSR、SSR、SSG、ISP

    前言 本来只是想学习 React-Router v6 ,没有想到,带出了这么多东西.前后端路由有什么区别?SPA与MPA的是什么?在了解到前端路之后又发现单页面于应用与多页面应用的不同之处,以及 .n ...

  2. 用原生 js jquery 实现知乎收起答案功能

    Update 2016.12.7 已封装为插件 原生 js 插件$ npm install foldcontent-zhihu@">=3.0.12" --save Usage ...

  3. js 自动分配金额_(2.4w字,建议收藏)??原生JS灵魂之问(下), 冲刺??进阶最后一公里(附个人成长经验分享)

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...

  4. js提取新浪邮箱的信用卡

    js提取用户新浪邮箱中的信用卡信息,是js非nodejs. 对比py,之前就做不好,出现了复杂点选验证码.js的开发速度只需要py的三分之一,甚至十分之一. js在客户端执行,py在后端执行,py要实 ...

  5. 原生 遍历_细品原生JS从初级到高级知识点汇总(三)

    作者:火狼1 转发链接:https://juejin.im/post/5daeefc8e51d4524f007fb15 目录 细品原生JS从初级到高级知识点汇总(一) 细品原生JS从初级到高级知识点汇 ...

  6. 原生js实现Ajax,JSONP

    Ajax内部的几个执行步骤 创建XMLHttpRequest对象(new XMLHttpRequest()) 设置请求头(setRequestHeader) 连接服务器(open()) 设置回调(on ...

  7. html5支持原生js,HTML5怎么学原生的js?让你对前端有了新的认识

    原标题:HTML5怎么学原生的js?让你对前端有了新的认识 已经学习了HTML5两个月,第一个月主要学习HTML和CSS,第二个月学完了原生的js,学完原生的js后对前端有了新的认识,了解了前端并不是 ...

  8. vue如何使用原生js写动画效果_原生js写一个无缝轮播图插件(支持vue)

    轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...

  9. AJAX请求和跨域请求详解(原生JS、Jquery)

    一.概述 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数 ...

最新文章

  1. php mysql 时间戳查询_mysql中时间查询函数(包括时间戳)
  2. (0027)iOS 开发之调整导航条上BarButtonItem与屏幕边界的间距
  3. sicily 1137 河床 (二分分治)
  4. linux执行加密的shell,Linux下Shell脚本文件的加密
  5. TensorFlow for Hackers - Part I
  6. python怎么对文件行排序_使用Python对文本文件进行排序
  7. 三星发布8nm芯片Exynos 850
  8. mysql盲注ascii中文_[翻译]关于通过对8bit的ascii做右位移提高mysql盲注效率
  9. 领英宣布开源数据挖掘软件WhereHows
  10. Java中this和super的区别
  11. 我的大学四年到毕业工作5年的学习路线资源汇总
  12. 2009年 上海证券交易所新一代交易系统有多牛逼
  13. 【C语言】易错题 and 易混淆知识
  14. AI识别教程 yolov5 (穿越火线,csgo等FPS游戏识别)
  15. gcc连接脚本 ld.info
  16. 小明种苹果(100分)
  17. 基于ARM Cortex-A8和Android 4.x的联动报警系统 (Android 、A8、Linux、驱动、NDK)
  18. 2015-8-29阿里校园招聘研发project师笔试题
  19. 独立站SaaS系统站群模式怎么玩
  20. flex布局之flex-direction

热门文章

  1. 【SIP】Centos7搭建kamailio的SIP服务器实现网络电话
  2. 利用EW代理实现内网穿透
  3. PID/LQR/MPC自行总结使用
  4. 三农数据(1990-2020)六:生产性固定资产原值、耕地面积、可再生资源利用、水利等
  5. 考研小纪2---考研经历分享(华科计算机)
  6. 疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇) -----(四)ESP430G2 低功耗模式
  7. JAVA变量与数据类型
  8. Clark变化和Park变换
  9. tmac v6设置中文_支持ipv6类型的ddos测试工具thc-ipv6
  10. 大一 大数据Python实验报告汇总