记事本
开篇(请大家看完):此网站写给挚爱,后续页面还会慢慢更新,大家敬请期待~ ~ ~
此前端框架,主要侧重于前端页面的视觉效果和交互体验。通过运用各种前端技术和创意,精心打造了一系列引人入胜的页面特效,会为大家带来全新的浏览体验。
同时,我非常支持和鼓励大家对这个框架进行二次创作或修改。您可以根据自己的需求和喜好,对框架进行个性化的定制和扩展,以打造出更符合自己品味的页面效果。
但请注意,如果您打算将这个框架转发给其他人或用于其他场合,请务必注明原创来源。让我们一起维护一个良好的创作环境。
最后,轻舟会继续更新和完善这个前端页面特效框架,为大家带来更多有趣、实用的功能和效果。感谢您的支持和关注!
页面效果:多种颜色搭配的动态粒子背景特效(粒子会随着鼠标的移动进行吸附,好看又好玩),左右摆动的文字特效,并且使用
localStorage
进行数据的持久化存储,使记事本的内容可以长期的保存在浏览器中,功能包括添加留言、显示留言和删除留言。
一:留言板.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> <!-- 设置文档字符编码为UTF-8 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 设置视口宽度等于设备宽度,初始缩放比例为1.0 -->
<title>私人留言板</title> <!-- 设置网页标题 -->
<link rel="stylesheet" href="CSS/留言板.css"> <!-- 链接外部CSS文件 -->
</head>
<body>
<h1>专属记事薄</h1> <!-- 显示标题 -->
<div class="container"> <!-- 容器 -->
<form id="messageForm"> <!-- 表单 -->
<textarea id="messageInput" placeholder="请输入你的留言..." style="color: #dc6515"></textarea> <!-- 输入框,用于输入留言 -->
<button type="submit">提交留言</button> <!-- 提交按钮 -->
<button id="submitButton">显示留言</button> <!-- 显示留言按钮 -->
</form>
<div id="messages"> <!-- 留言显示区域 -->
<!-- 留言 -->
</div>
</div>
<script src="JS/留言板.js"></script> <!-- 链接JavaScript文件 -->
<script>
!(function () {
// 使用立即执行函数,避免污染全局命名空间
function n(n, e, t) {
// 获取元素属性的函数
return n.getAttribute(e) || t;
}
function e(n) {
// 获取标签名的函数
return document.getElementsByTagName(n);
}
function t() {
// 获取配置信息的函数
var t = e("script"), // 获取所有script标签
o = t.length, // script标签的数量
i = t[o - 1]; // 获取最后一个script标签
return {
// 返回配置对象
l: o, // script标签的数量
z: n(i, "zIndex", -1), // z-index值
o: n(i, "opacity", 0.6), // 透明度
c: n(i, "color", "0,255,0"), // 粒子颜色
n: n(i, "count", 400), // 粒子数量
};
}
function o() {
// 初始化画布大小的函数
(a = m.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth),
(c = m.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight);
}
function i() {
// 绘制函数
r.clearRect(0, 0, a, c); // 清除画布
var n, e, t, o, m, l;
s.forEach(function (particle, index) {
// 遍历粒子数组
for (
particle.x += particle.xa, // 更新粒子x坐标
particle.y += particle.ya, // 更新粒子y坐标
particle.xa *= particle.x > a || particle.x < 0 ? -1 : 1, // 根据边界条件更新x轴速度
particle.ya *= particle.y > c || particle.y < 0 ? -1 : 1, // 根据边界条件更新y轴速度
r.fillStyle = particle.color, // 设置粒子颜色
r.fillRect(particle.x - 0.5, particle.y - 0.5, 1, 1), // 绘制粒子
e = index + 1;
e < u.length;
e++
) {
(n = u[e]), // 获取当前粒子后面的粒子
null !== n.x && null !== n.y && ((o = particle.x - n.x), (m = particle.y - n.y), (l = o * o + m * m), // 计算粒子间距离
l < n.max && // 如果距离小于最大距离
(n === y && l >= n.max / 2 && ((particle.x -= 0.03 * o), (particle.y -= 0.03 * m)), // 鼠标吸附效果
(t = (n.max - l) / n.max), // 计算连线宽度
r.beginPath(), // 开始绘制路径
(r.lineWidth = t / 2), // 设置连线宽度
r.strokeStyle = particle.color, // 设置连线颜色
r.moveTo(particle.x, particle.y), // 移动到起始点
r.lineTo(n.x, n.y), // 绘制到终点
r.stroke())); // 执行绘制
}
}),
x(i); // 使用requestAnimationFrame递归调用i函数
}
var fixedColors = [ // 定义固定颜色数组
"rgba(255, 0, 0, 1.0)", // 红色
"rgba(0, 255, 0, 1.0)", // 绿色
"rgba(0, 0, 255, 1.0)", // 蓝色
"rgba(255, 255, 0, 1.0)", // 黄色
"rgba(0, 255, 255, 0.8)", // 青色
"rgba(255, 0, 255, 0.8)", // 紫色
"rgba(255, 165, 0, 0.8)", // 橙色
"rgba(127, 255, 212, 1.0)",
"rgba(0, 255, 127, 1.0)"
];
var a, c, u, m = document.createElement("canvas"), // 创建canvas元素
d = t(), // 获取配置信息
l = "c_n" + d.l, // 设置canvas的id
r = m.getContext("2d"), // 获取canvas的2D绘图上下文
x = window.requestAnimationFrame || // 兼容性处理,获取requestAnimationFrame函数
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (n) {
window.setTimeout(n, 1e3 / 45); },
w = Math.random, // 获取随机数函数
y = {
x: null, y: null, max: 2e4 }; // 定义鼠标对象
(m.id = l), // 设置canvas的id
(m.style.cssText = "position:fixed;top:0;left:0;z-index:" + d.z + ";opacity:" + d.o), // 设置canvas的样式
e("body")[0].appendChild(m), // 将canvas添加到body中
o(), // 初始化画布大小
(window.onresize = o), // 绑定窗口大小改变事件
(window.onmousemove = function (n) {
// 绑定鼠标移动事件
(n = n || window.event), (y.x = n.clientX), (y.y = n.clientY); // 更新鼠标位置
}),
(window.onmouseout = function () {
// 绑定鼠标移出事件
(y.x = null), (y.y = null); // 清除鼠标位置
});
// 创建粒子数组,固定颜色
for (var s = [], f = 0; d.n > f; f++) {
var h = w() * a, // 粒子x坐标
g = w() * c, // 粒子y坐标
v = 2 * w() - 1, // 粒子x轴速度
p = 2 * w() - 1, // 粒子y轴速度
color = fixedColors[Math.floor(Math.random() * fixedColors.length)]; // 从固定颜色数组中随机选择一个颜色
s.push({
x: h, y: g, xa: v, ya: p, max: 6e3, color: color }); // 将粒子添加到数组中
}
(u = s.concat([y])), // 将鼠标对象添加到粒子数组中
setTimeout(function () {
// 使用setTimeout延迟执行绘制函数
i();
}, 100);
})();
</script>
</body>
</html>
二:留言板.css
/* 设置body的字体为Arial,sans-serif,文本居中,使用flex布局,方向为垂直,内容垂直居中,无外边距,顶部内边距50px */
body {
font-family: Arial, sans-serif;
text-align: center; /* 使body内的内容水平居中 */
display: flex;
flex-direction: column; /* 垂直布局 */
align-items: center; /* 垂直居中(对于单行内容) */
margin: 0;
padding-top: 50px; /* 根据需要调整h1与顶部的距离 */
}
/* 设置留言板容器的最大宽度为600px,宽度为100%,文本对齐方式为左对齐 */
.container {
max-width: 600px; /* 限制留言板容器的最大宽度 */
width: 100%; /* 响应式宽度 */
text-align: left; /* 重置文本对齐方式,如果需要的话 */
}
/* 设置textarea的宽度为100%,高度为100px,下边距为10px,字体加粗 */
textarea {
width: 100%;
height: 100px;
margin-bottom: 10px;
font-weight: bold;
}
/* 设置#messages的上边距为60px */
#messages {
margin-top: 60px;
}
/* 特定于#messageForm内的textarea样式,与全局textarea样式相同 */
#messageForm textarea {
width: 100%; /* 边框宽度 */
height: 100px; /* 边框高度 */
margin-bottom: 10px; /* 按钮与边框的垂直距离 */
}
/* 设置每条留言的背景色为#f4f4f4,内边距为10px,下边距为10px,边框圆角为5px */
.message {
background-color: #f4f4f4; /* 背景色 */
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
}
/* 设置删除按钮的样式:右浮动,鼠标悬停样式为指针,字体颜色为红色,背景色为#f0adad,无边框,内边距为5px 10px,圆角为5px,左边距为10px */
.delete-button {
float: right;
cursor: pointer;
color: red;
background-color: #f0adad; /* 添加背景色 */
border: none; /* 移除边框 */
padding: 5px 10px; /* 添加内边距 */
border-radius: 5px; /* 圆角 */
margin-left: 10px; /* 与文本内容间隔 */
}
/* 设置删除按钮鼠标悬停时的背景色为#e09dad */
.delete-button:hover {
/* 鼠标悬停效果 */
background-color: #e09dad;
}
/* 设置h1的字体大小为48px,字体加粗为600,添加无限循环的旋转动画,宽度适应内容,下边距为20px */
h1 {
font-size: 48px;
font-weight: 600;
animation: rotate 0.3s ease infinite;
width: fit-content; /* 确保h1的宽度适应其内容 */
margin-bottom: 20px; /* 增加h1与留言板内容之间的垂直间距 */
}
/* 定义rotate动画,使元素在0%时旋转0度,20%时旋转-2度,60%时旋转0度,80%时旋转2度,100%时旋转0度 */
@keyframes rotate {
0% {
transform: rotate(0);
}
20% {
transform: rotate(-2deg);
}
60% {
transform: rotate(0);
}
80% {
transform: rotate(2deg);
}
100% {
transform: rotate(0);
}
}
三:留言板.js
document.addEventListener('DOMContentLoaded', function() {
// 获取表单元素
const form = document.getElementById('messageForm');
// 获取输入框元素
const messageInput = document.getElementById('messageInput');
// 获取留言容器元素
const messagesContainer = document.getElementById('messages');
// 获取提交按钮元素
const submitButton = document.getElementById('submitButton');
// 为提交按钮添加点击事件监听器,点击时重新加载并显示留言
submitButton.addEventListener('click', function() {
loadMessages(); // 直接调用loadMessages来重新加载并显示留言
});
// 从localStorage加载留言
loadMessages();
// 为表单添加提交事件监听器
form.addEventListener('submit', function(e) {
e.preventDefault(); // 阻止表单默认提交行为
// 获取输入框的值并去除首尾空格
const messageText = messageInput.value.trim();
// 如果输入框不为空
if (messageText) {
// 将留言保存到localStorage并显示在页面上
saveMessage(messageText);
messageInput.value = ''; // 清空输入框
}
// 如果输入框为空,可以选择弹出提示,这里注释掉了
// else {
// alert('请输入留言内容!');
// }
});
// 将留言保存到localStorage并显示在页面上
function saveMessage(messageText) {
// 从localStorage获取留言数组,如果不存在则初始化为空数组
const messages = JSON.parse(localStorage.getItem('messages')) || [];
// 创建新的留言对象
const newMessage = {
text: messageText, timestamp: Date.now() };
// 将新留言添加到数组中
messages.push(newMessage);
// 将更新后的留言数组保存回localStorage
localStorage.setItem('messages', JSON.stringify(messages));
// 显示留言
displayMessages();
}
// 从localStorage加载留言并显示
function loadMessages() {
// 从localStorage获取留言数组
const savedMessages = JSON.parse(localStorage.getItem('messages'));
// 如果存在留言数组,则显示留言
if (savedMessages) {
displayMessages(savedMessages);
}
}
// 显示留言
function displayMessages(loadedMessages = []) {
// 清空留言容器
messagesContainer.innerHTML = '';
// 遍历留言数组
loadedMessages.forEach(function(message) {
// 创建留言元素
const messageElem = document.createElement('div');
messageElem.classList.add('message');
// 创建文本元素并设置内容为留言时间和内容
const textElem = document.createElement('span');
textElem.textContent = new Date(message.timestamp).toLocaleString() + ': ' + message.text;
messageElem.appendChild(textElem);
// 创建删除按钮
const deleteButton = document.createElement('button');
deleteButton.textContent = '删除';
deleteButton.classList.add('delete-button');
// 为删除按钮添加点击事件监听器,点击时删除对应留言
deleteButton.addEventListener('click', function() {
removeMessage(message.timestamp);
});
// 将删除按钮添加到留言元素中
messageElem.appendChild(deleteButton);
// 将留言元素添加到留言容器中
messagesContainer.appendChild(messageElem);
});
}
// 删除指定时间戳的留言
function removeMessage(timestamp) {
// 从localStorage获取留言数组
const messages = JSON.parse(localStorage.getItem('messages')) || [];
// 过滤掉指定时间戳的留言
const filteredMessages = messages.filter(msg => msg.timestamp !== timestamp);
// 将过滤后的留言数组保存回localStorage
localStorage.setItem('messages', JSON.stringify(filteredMessages));
// 重新渲染留言列表
displayMessages(filteredMessages);
}
});
本页面就到这里啦~ ~ ~源码复制粘贴直接可用,每一行都有详细的注释,大家可以根据自己的喜欢进行二创,大家期待一下下一个页面功能叭!!!