randomthoughts / index.html
carlleonhard's picture
Add 2 files
fb9568f verified
Raw History Blame Contribute Delete
22.4 kB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的想法气泡</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary-color: #4a6fa5;
--secondary-color: #e9f2fa;
--accent-color: #ff7e5f;
--text-color: #333;
--light-text: #777;
--bg-color: #f9f9f9;
--card-bg: #fff;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
header {
text-align: center;
margin-bottom: 30px;
position: relative;
}
h1 {
color: var(--primary-color);
font-size: 2.5rem;
margin-bottom: 10px;
position: relative;
display: inline-block;
}
h1:after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 4px;
background-color: var(--accent-color);
border-radius: 2px;
}
.subtitle {
color: var(--light-text);
font-size: 1.1rem;
margin-bottom: 20px;
}
.input-container {
background-color: var(--card-bg);
padding: 25px;
border-radius: 10px;
box-shadow: var(--shadow);
margin-bottom: 30px;
position: relative;
transition: all 0.3s ease;
}
.input-container:hover {
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}
.input-container h2 {
color: var(--primary-color);
margin-bottom: 15px;
font-size: 1.4rem;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
color: var(--light-text);
font-size: 0.9rem;
}
textarea {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 6px;
resize: vertical;
min-height: 100px;
font-size: 1rem;
transition: border 0.3s;
}
textarea:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(74, 111, 165, 0.2);
}
.buttons {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
}
.filter-group {
display: flex;
align-items: center;
gap: 10px;
}
select {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background-color: white;
cursor: pointer;
}
select:focus {
outline: none;
border-color: var(--primary-color);
}
button {
background-color: var(--primary-color);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 1rem;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 8px;
}
button:hover {
background-color: #3a5a8f;
transform: translateY(-2px);
}
button.secondary {
background-color: #6c757d;
}
button.secondary:hover {
background-color: #5a6268;
}
button.delete {
background-color: #dc3545;
}
button.delete:hover {
background-color: #c82333;
}
.thoughts-container {
display: flex;
flex-direction: column;
gap: 20px;
}
.thought-card {
background-color: var(--card-bg);
border-radius: 10px;
padding: 20px;
box-shadow: var(--shadow);
position: relative;
transition: all 0.3s;
opacity: 0;
animation: fadeIn 0.5s forwards;
animation-delay: calc(0.1s * var(--order));
}
@keyframes fadeIn {
to {
opacity: 1;
}
}
.thought-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.thought-bubble {
position: relative;
background-color: var(--secondary-color);
padding: 15px;
border-radius: 12px;
margin-bottom: 15px;
}
.thought-bubble:after {
content: '';
position: absolute;
bottom: -10px;
left: 30px;
border-width: 10px 10px 0;
border-style: solid;
border-color: var(--secondary-color) transparent;
}
.thought-content {
font-size: 1.1rem;
line-height: 1.6;
}
.thought-meta {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--light-text);
font-size: 0.9rem;
margin-top: 10px;
}
.thought-actions {
display: flex;
gap: 10px;
}
.no-thoughts {
text-align: center;
padding: 40px;
color: var(--light-text);
font-size: 1.1rem;
background-color: var(--card-bg);
border-radius: 10px;
box-shadow: var(--shadow);
}
.floating-btn {
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: var(--accent-color);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
transition: all 0.3s;
z-index: 10;
}
.floating-btn:hover {
transform: scale(1.1);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
}
.tags {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 10px;
}
.tag {
background-color: #e0e7ff;
color: var(--primary-color);
padding: 4px 8px;
border-radius: 4px;
font-size: 0.8rem;
display: flex;
align-items: center;
gap: 4px;
}
.tag-input {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
.tag-input input {
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px 8px;
flex-grow: 1;
min-width: 100px;
}
.tag-input button {
padding: 5px 10px;
font-size: 0.8rem;
}
@media (max-width: 768px) {
.container {
padding: 10px;
}
h1 {
font-size: 2rem;
}
.buttons {
flex-direction: column;
gap: 10px;
align-items: stretch;
}
.filter-group {
flex-direction: column;
align-items: stretch;
}
.thought-meta {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.thought-actions {
align-self: flex-end;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1><i class="fas fa-comment-dots"></i> 我的想法气泡</h1>
<p class="subtitle">记录你闪光的每一个瞬间</p>
</header>
<div class="input-container">
<h2><i class="fas fa-pencil-alt"></i> 新增想法</h2>
<form id="thought-form">
<div class="form-group">
<label for="thought-content"><i class="fas fa-lightbulb"></i> 内容</label>
<textarea id="thought-content" placeholder="写下你的想法或灵感..." required></textarea>
</div>
<div class="form-group" id="tag-section">
<label><i class="fas fa-tags"></i> 标签</label>
<div class="tag-input">
<input type="text" id="tag-input" placeholder="添加标签,按Enter确认">
<button type="button" id="add-tag-btn" class="secondary"><i class="fas fa-plus"></i> 添加</button>
</div>
<div id="tags-preview" class="tags"></div>
</div>
<div class="buttons">
<div class="filter-group">
<label for="filter-date"><i class="far fa-calendar-alt"></i> 筛选:</label>
<select id="filter-date">
<option value="all">全部日期</option>
<option value="today">今天</option>
<option value="week">本周</option>
<option value="month">本月</option>
</select>
</div>
<button type="submit"><i class="fas fa-paper-plane"></i> 保存想法</button>
</div>
</form>
</div>
<div id="thoughts-container" class="thoughts-container">
<div class="no-thoughts" id="empty-message">
<i class="far fa-comment-alt fa-3x" style="margin-bottom: 15px;"></i>
<p>还没有记录任何想法<br>开始写下你的第一个灵感吧!</p>
</div>
</div>
</div>
<div class="floating-btn" id="scroll-top-btn">
<i class="fas fa-arrow-up"></i>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 初始化变量
let thoughts = JSON.parse(localStorage.getItem('thoughts')) || [];
let tags = [];
// DOM元素
const thoughtForm = document.getElementById('thought-form');
const thoughtContent = document.getElementById('thought-content');
const thoughtContainer = document.getElementById('thoughts-container');
const emptyMessage = document.getElementById('empty-message');
const filterDate = document.getElementById('filter-date');
const tagInput = document.getElementById('tag-input');
const addTagBtn = document.getElementById('add-tag-btn');
const tagsPreview = document.getElementById('tags-preview');
const scrollTopBtn = document.getElementById('scroll-top-btn');
// 渲染想法列表
renderThoughts();
// 表单提交事件
thoughtForm.addEventListener('submit', function(e) {
e.preventDefault();
const content = thoughtContent.value.trim();
if (!content) return;
const newThought = {
id: Date.now().toString(),
content: content,
date: new Date().toISOString(),
tags: [...tags]
};
thoughts.unshift(newThought);
saveThoughts();
tags = [];
renderTags();
thoughtForm.reset();
renderThoughts();
// 显示成功提示
showNotification('想法已保存!');
});
// 添加标签事件
addTagBtn.addEventListener('click', addTag);
tagInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
addTag();
}
});
// 筛选事件
filterDate.addEventListener('change', renderThoughts);
// 滚动到顶部按钮
scrollTopBtn.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
// 显示/隐藏滚动按钮
window.addEventListener('scroll', function() {
if (window.pageYOffset > 300) {
scrollTopBtn.style.display = 'flex';
} else {
scrollTopBtn.style.display = 'none';
}
});
// 添加标签函数
function addTag() {
const tagValue = tagInput.value.trim();
if (tagValue && !tags.includes(tagValue)) {
tags.push(tagValue);
renderTags();
tagInput.value = '';
}
}
// 渲染标签预览
function renderTags() {
tagsPreview.innerHTML = '';
tags.forEach(tag => {
const tagEl = document.createElement('div');
tagEl.className = 'tag';
tagEl.innerHTML = `
<span>${tag}</span>
<i class="fas fa-times" data-tag="${tag}"></i>
`;
tagsPreview.appendChild(tagEl);
});
// 添加删除标签事件
document.querySelectorAll('.tag i').forEach(icon => {
icon.addEventListener('click', function() {
const tagToRemove = this.getAttribute('data-tag');
tags = tags.filter(tag => tag !== tagToRemove);
renderTags();
});
});
}
// 保存想法到本地存储
function saveThoughts() {
localStorage.setItem('thoughts', JSON.stringify(thoughts));
}
// 渲染想法列表
function renderThoughts() {
const filterValue = filterDate.value;
let filteredThoughts = [...thoughts];
// 根据选择筛选
if (filterValue !== 'all') {
const now = new Date();
filteredThoughts = thoughts.filter(thought => {
const thoughtDate = new Date(thought.date);
if (filterValue === 'today') {
return thoughtDate.toDateString() === now.toDateString();
} else if (filterValue === 'week') {
const startOfWeek = new Date(now);
startOfWeek.setDate(now.getDate() - now.getDay());
startOfWeek.setHours(0, 0, 0, 0);
return thoughtDate >= startOfWeek;
} else if (filterValue === 'month') {
return thoughtDate.getMonth() === now.getMonth() &&
thoughtDate.getFullYear() === now.getFullYear();
}
return true;
});
}
// 渲染列表
if (filteredThoughts.length === 0) {
emptyMessage.style.display = 'block';
thoughtContainer.innerHTML = '';
thoughtContainer.appendChild(emptyMessage);
} else {
emptyMessage.style.display = 'none';
thoughtContainer.innerHTML = '';
filteredThoughts.forEach((thought, index) => {
const date = new Date(thought.date);
const formattedDate = formatDate(date);
const formattedTime = formatTime(date);
const thoughtCard = document.createElement('div');
thoughtCard.className = 'thought-card';
thoughtCard.style.setProperty('--order', index);
thoughtCard.innerHTML = `
<div class="thought-bubble">
<div class="thought-content">${thought.content}</div>
</div>
${thought.tags.length > 0 ? `
<div class="tags">
${thought.tags.map(tag => `
<div class="tag">
<span>${tag}</span>
</div>
`).join('')}
</div>
` : ''}
<div class="thought-meta">
<div>
<i class="far fa-clock"></i> ${formattedDate} · ${formattedTime}
</div>
<div class="thought-actions">
<button class="delete delete-btn" data-id="${thought.id}">
<i class="fas fa-trash"></i> 删除
</button>
</div>
</div>
`;
thoughtContainer.appendChild(thoughtCard);
});
// 添加删除按钮事件
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function() {
const id = this.getAttribute('data-id');
deleteThought(id);
});
});
}
}
// 删除想法
function deleteThought(id) {
if (confirm('确定要删除这个想法吗?')) {
thoughts = thoughts.filter(thought => thought.id !== id);
saveThoughts();
renderThoughts();
showNotification('想法已删除');
}
}
// 格式化日期
function formatDate(date) {
const options = { year: 'numeric', month: 'short', day: 'numeric' };
return date.toLocaleDateString('zh-CN', options);
}
// 格式化时间
function formatTime(date) {
const options = { hour: '2-digit', minute: '2-digit', hour12: false };
return date.toLocaleTimeString('zh-CN', options);
}
// 显示通知
function showNotification(message) {
const notification = document.createElement('div');
notification.className = 'notification';
notification.textContent = message;
notification.style.position = 'fixed';
notification.style.bottom = '20px';
notification.style.left = '50%';
notification.style.transform = 'translateX(-50%)';
notification.style.backgroundColor = 'var(--primary-color)';
notification.style.color = 'white';
notification.style.padding = '12px 24px';
notification.style.borderRadius = '6px';
notification.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
notification.style.zIndex = '1000';
notification.style.opacity = '0';
notification.style.transition = 'opacity 0.3s';
document.body.appendChild(notification);
setTimeout(() => {
notification.style.opacity = '1';
}, 10);
setTimeout(() => {
notification.style.opacity = '0';
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, 3000);
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
</html>