卡片项目管理(Web)(项目卡位)
ztj100 2025-07-09 18:38 4 浏览 0 评论
简洁的HTML文档卡片管理,简单框架个人本地离线使用。
将个人工具类的文档整理使用。
优化方向:添加图片、瀑布式布局、颜色修改、毛玻璃效果等。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>卡片项目管理</title>
<style>
/* CSS变量定义 */
:root {
/* 浅色主题变量 */
--system-blue: #007AFF;
--system-gray-1: #F6F6F6;
--system-gray-2: #E5E5EA;
--system-gray-3: #D1D1D6;
--system-gray-4: #8E8E93;
--system-gray-5: #333333;
--system-red: #FF3B30;
--system-white: #FFFFFF;
--system-background: #FFFFFF;
--system-card-bg: rgba(255, 255, 255, 0.85);
--system-text-primary: #000000;
--system-text-secondary: #8E8E93;
--system-shadow: rgba(0, 0, 0, 0.1);
--system-border: rgba(0, 0, 0, 0.1);
--system-glass: rgba(255, 255, 255, 0.8);
--system-tint: rgba(0, 122, 255, 0.1);
--running-border: #007AFF;
}
/* 深色主题变量 */
.dark-theme {
--system-blue: #0A84FF;
--system-gray-1: #1C1C1E;
--system-gray-2: #2C2C2E;
--system-gray-3: #3A3A3C;
--system-gray-4: #8E8E93;
--system-gray-5: #F2F2F7;
--system-white: #000000;
--system-background: #000000;
--system-card-bg: rgba(28, 28, 30, 0.85);
--system-text-primary: #F2F2F7;
--system-text-secondary: #8E8E93;
--system-shadow: rgba(0, 0, 0, 0.3);
--system-border: rgba(255, 255, 255, 0.1);
--system-glass: rgba(28, 28, 30, 0.8);
--system-tint: rgba(10, 132, 255, 0.2);
--running-border: #0A84FF;
}
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
transition: background-color 0.3s, color 0.3s, transform 0.2s, border 0.3s;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: var(--system-background);
color: var(--system-text-primary);
line-height: 1.5;
min-height: 100vh;
padding-top: 44px; /* 导航栏44px */
}
/* iOS导航栏样式 */
.nav-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 44px;
padding: 0 16px;
display: flex;
justify-content: space-between;
align-items: center;
background: var(--system-glass);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
z-index: 1000;
border-bottom: 0.5px solid var(--system-border);
}
.nav-title {
font-size: 17px;
font-weight: 600;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.nav-btn {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
color: var(--system-blue);
font-size: 16px;
cursor: pointer;
z-index: 1;
}
.nav-btn.add-btn {
font-weight: bold;
font-size: 24px;
margin-right: -8px;
}
/* 内容区域样式 */
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.section-title {
font-size: 34px;
font-weight: 700;
line-height: 1.2;
margin-bottom: 20px;
}
/* 卡片网格布局 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
margin-top: 20px;
}
/* iOS卡片样式 */
.card {
background: var(--system-card-bg);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px var(--system-shadow);
transition: transform 0.3s ease, box-shadow 0.3s ease;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 0.5px solid var(--system-border);
}
.card.running {
border: 2px solid var(--running-border);
box-shadow: 0 0 0 2px var(--system-tint), 0 4px 12px var(--system-shadow);
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 6px 20px var(--system-shadow);
}
.card-header {
padding: 16px;
border-bottom: 0.5px solid var(--system-border);
display: flex;
align-items: center;
gap: 12px;
}
.card-icon {
width: 40px;
height: 40px;
background: linear-gradient(135deg, var(--system-blue), #5e5ce6);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 18px;
}
.card-title {
font-size: 17px;
font-weight: 600;
color: var(--system-text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-content {
padding: 16px;
height: 120px;
overflow: hidden;
position: relative;
}
.card-content::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 30px;
background: linear-gradient(to top, var(--system-card-bg), transparent);
}
.card-content pre {
font-family: 'SF Mono', Menlo, monospace;
font-size: 13px;
margin: 0;
white-space: pre-wrap;
word-break: break-word;
color: var(--system-text-secondary);
opacity: 0.9;
max-height: 100%;
overflow: hidden;
}
.card-footer {
padding: 12px 16px;
display: flex;
justify-content: space-between;
border-top: 0.5px solid var(--system-border);
}
.card-date {
font-size: 13px;
color: var(--system-text-secondary);
}
.card-actions {
display: flex;
gap: 8px;
}
.card-btn {
padding: 6px 12px;
font-size: 14px;
border-radius: 8px;
background: var(--system-tint);
color: var(--system-blue);
border: none;
cursor: pointer;
font-weight: 500;
}
.card-btn:hover {
background: var(--system-blue);
color: white;
}
.delete-btn {
background: rgba(255, 59, 48, 0.1);
color: var(--system-red);
}
.delete-btn:hover {
background: var(--system-red);
color: white;
}
/* 空状态样式 */
.empty-state {
text-align: center;
padding: 60px 20px;
opacity: 0.6;
grid-column: 1 / -1;
}
.empty-state i {
font-size: 48px;
margin-bottom: 16px;
opacity: 0.5;
color: var(--system-text-secondary);
}
.empty-state p {
font-size: 17px;
max-width: 500px;
margin: 0 auto;
color: var(--system-text-secondary);
}
/* Safari浏览器模拟窗口 */
.safari-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.95);
z-index: 2000;
display: flex;
flex-direction: column;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
}
.safari-modal.active {
opacity: 1;
visibility: visible;
}
.safari-header {
height: 44px;
background: rgba(30, 30, 30, 0.9);
padding: 16px;
display: flex;
flex-direction: column;
gap: 12px;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
}
.safari-controls {
display: flex;
gap: 10px;
align-items: center;
}
.control-btn {
width: 14px;
height: 14px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: rgba(0, 0, 0, 0.7);
font-weight: bold;
}
.close-btn {
background: #ff5f57;
}
.minimize-btn {
background: #ffbd2e;
}
.edit-code-btn {
background: #28c940;
}
.safari-url-bar {
background: rgba(40, 40, 40, 0.6);
padding: 8px 15px;
border-radius: 8px;
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
display: flex;
align-items: center;
gap: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.safari-url-bar::before {
content: '';
font-size: 16px;
}
.safari-content {
flex: 1;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.safari-iframe {
width: 100%;
height: 100%;
border: none;
border-radius: 12px;
background: white;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
/* 编辑模态框 */
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
backdrop-filter: blur(5px);
}
.modal.active {
opacity: 1;
visibility: visible;
}
.modal-content {
background: var(--system-card-bg);
border-radius: 14px;
width: 90%;
max-width: 500px;
max-height: 90vh;
overflow: hidden;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
transform: translateY(20px);
transition: transform 0.4s;
border: 0.5px solid var(--system-border);
}
.modal.active .modal-content {
transform: translateY(0);
}
.modal-header {
padding: 16px;
border-bottom: 0.5px solid var(--system-border);
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-title {
font-size: 17px;
font-weight: 600;
}
.modal-close {
background: none;
border: none;
font-size: 20px;
cursor: pointer;
color: var(--system-blue);
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.modal-close:hover {
background: var(--system-tint);
}
.modal-body {
padding: 16px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
font-size: 14px;
color: var(--system-text-secondary);
}
input, textarea {
width: 100%;
padding: 12px 15px;
border-radius: 10px;
border: 0.5px solid var(--system-border);
background: var(--system-card-bg);
color: var(--system-text-primary);
font-family: inherit;
font-size: 17px;
}
textarea {
min-height: 200px;
resize: vertical;
font-family: 'SF Mono', Menlo, monospace;
background: rgba(0, 0, 0, 0.05);
padding: 15px;
}
.dark-theme textarea {
background: rgba(255, 255, 255, 0.05);
}
.modal-footer {
padding: 16px;
display: flex;
justify-content: flex-end;
gap: 10px;
border-top: 0.5px solid var(--system-border);
}
.primary-btn {
padding: 10px 24px;
background: var(--system-blue);
color: white;
border: none;
border-radius: 10px;
font-size: 17px;
font-weight: 500;
cursor: pointer;
}
.secondary-btn {
padding: 10px 24px;
background: var(--system-gray-2);
color: var(--system-text-primary);
border: none;
border-radius: 10px;
font-size: 17px;
font-weight: 500;
cursor: pointer;
}
.import-btn {
width: 100%;
padding: 12px;
background: var(--system-tint);
color: var(--system-blue);
border: none;
border-radius: 10px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
text-align: center;
margin-bottom: 15px;
}
.import-btn:hover {
background: var(--system-blue);
color: white;
}
/* 最小化窗口 */
.minimized-window {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
background: #ffbd2e;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: black;
font-weight: bold;
cursor: pointer;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
z-index: 999;
opacity: 0;
transform: translateY(20px);
transition: opacity 0.3s, transform 0.3s;
}
.minimized-window.active {
opacity: 1;
transform: translateY(0);
}
/* 响应式调整 */
@media (max-width: 768px) {
.card-grid {
grid-template-columns: 1fr;
}
.section-title {
font-size: 28px;
}
.container {
padding: 16px;
}
}
@media (max-width: 480px) {
.nav-bar {
padding: 0 8px;
}
.section-title {
font-size: 24px;
}
}
</style>
</head>
<body>
<!-- iOS导航栏 -->
<div class="nav-bar">
<button class="nav-btn theme-toggle-btn">←</button>
<div class="nav-title">我的项目</div>
<button class="nav-btn add-btn">+</button>
</div>
<!-- 内容区域 -->
<div class="container">
<h1 class="section-title">项目卡片库</h1>
<div class="card-grid" id="projects-container">
<!-- 项目卡片将通过JS动态生成 -->
<div class="empty-state">
<div></div>
<p>暂无项目,点击右上角"+"按钮添加新项目</p>
</div>
</div>
</div>
<!-- 添加/编辑项目模态框 -->
<div class="modal" id="edit-modal">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title">添加新项目</h2>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="project-title">项目名称</label>
<input type="text" id="project-title" placeholder="输入项目名称">
</div>
<div class="form-group">
<label for="project-code">HTML代码</label>
<textarea id="project-code" placeholder="粘贴您的HTML代码..."></textarea>
</div>
<button class="import-btn" id="import-file">
<span> 导入本地HTML文件</span>
<input type="file" id="file-input" accept=".html,.htm" style="display:none">
</button>
</div>
<div class="modal-footer">
<button class="secondary-btn" id="cancel-edit">取消</button>
<button class="primary-btn" id="save-project">保存</button>
</div>
</div>
</div>
<!-- Safari浏览器模拟窗口 -->
<div class="safari-modal" id="safari-modal">
<div class="safari-header">
<div class="safari-controls">
<div class="control-btn close-btn" id="safari-close">×</div>
<div class="control-btn minimize-btn" id="safari-minimize">-</div>
<div class="control-btn edit-code-btn" id="safari-edit">+</div>
</div>
<div class="safari-url-bar" id="safari-url">localhost/project.html</div>
</div>
<div class="safari-content">
<iframe class="safari-iframe" id="safari-iframe"></iframe>
</div>
</div>
<!-- 最小化窗口 -->
<div class="minimized-window" id="minimized-window">↗</div>
<script>
// DOM元素
const projectsContainer = document.getElementById('projects-container');
const editModal = document.getElementById('edit-modal');
const safariModal = document.getElementById('safari-modal');
const themeToggleBtn = document.querySelector('.theme-toggle-btn');
const addBtn = document.querySelector('.add-btn');
const minimizedWindow = document.getElementById('minimized-window');
const fileInput = document.getElementById('file-input');
const importBtn = document.getElementById('import-file');
// 状态变量
let currentEditIndex = -1;
let currentRunningProject = null;
let minimizedProject = null;
let cards = []; // 存储卡片DOM元素
// 初始化
document.addEventListener('DOMContentLoaded', () => {
// 加载主题设置
loadTheme();
// 加载存储的项目
loadProjects();
// 事件监听
addBtn.addEventListener('click', () => {
currentEditIndex = -1;
document.getElementById('project-title').value = '';
document.getElementById('project-code').value = '';
document.querySelector('#edit-modal .modal-title').textContent = '添加新项目';
openModal(editModal);
});
themeToggleBtn.addEventListener('click', toggleTheme);
document.querySelector('.modal-close').addEventListener('click', () => {
closeModal(editModal);
});
document.getElementById('cancel-edit').addEventListener('click', () => {
closeModal(editModal);
});
document.getElementById('save-project').addEventListener('click', saveProject);
// 文件导入处理
importBtn.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', handleFileImport);
// Safari 控制按钮
document.getElementById('safari-close').addEventListener('click', () => {
safariModal.classList.remove('active');
document.getElementById('safari-iframe').src = '';
removeRunningHighlight();
currentRunningProject = null;
});
document.getElementById('safari-minimize').addEventListener('click', () => {
safariModal.classList.remove('active');
minimizedWindow.classList.add('active');
minimizedProject = currentRunningProject;
});
document.getElementById('safari-edit').addEventListener('click', () => {
if (currentRunningProject !== null) {
editProject(currentRunningProject.index);
}
});
minimizedWindow.addEventListener('click', () => {
minimizedWindow.classList.remove('active');
safariModal.classList.add('active');
minimizedProject = null;
});
});
// 主题功能
function toggleTheme() {
document.body.classList.toggle('dark-theme');
const isDarkMode = document.body.classList.contains('dark-theme');
localStorage.setItem('theme', isDarkMode ? 'dark' : 'light');
// 更新运行边框颜色
if (currentRunningProject) {
highlightRunningCard(currentRunningProject.index);
}
}
function loadTheme() {
const savedTheme = localStorage.getItem('theme') || 'light';
if (savedTheme === 'dark') {
document.body.classList.add('dark-theme');
}
}
// 项目管理功能
function loadProjects() {
const projects = JSON.parse(localStorage.getItem('projects') || '[]');
if (projects.length === 0) {
projectsContainer.innerHTML = `
<div class="empty-state">
<div></div>
<p>暂无项目,点击右上角"+"按钮添加新项目</p>
</div>
`;
return;
}
projectsContainer.innerHTML = '';
cards = [];
projects.forEach((project, index) => {
const card = createProjectCard(project, index);
projectsContainer.appendChild(card);
cards.push(card);
});
}
function createProjectCard(project, index) {
const card = document.createElement('div');
card.className = 'card';
card.dataset.index = index;
card.innerHTML = `
<div class="card-header">
<div class="card-icon">${project.title.charAt(0).toUpperCase()}</div>
<h3 class="card-title">${project.title}</h3>
</div>
<div class="card-content">
<pre>${escapeHtml(project.code.substring(0, 500))}${project.code.length > 500 ? '...' : ''}</pre>
</div>
<div class="card-footer">
<div class="card-date">${formatDate(project.date)}</div>
<div class="card-actions">
<button class="card-btn run-btn">运行</button>
<button class="card-btn edit-btn">编辑</button>
<button class="card-btn delete-btn">删除</button>
</div>
</div>
`;
card.querySelector('.run-btn').addEventListener('click', () => {
runProject(project.code, project.title, index);
});
card.querySelector('.edit-btn').addEventListener('click', () => {
editProject(index);
});
card.querySelector('.delete-btn').addEventListener('click', () => {
deleteProject(index);
});
return card;
}
function runProject(code, title, index) {
// 移除之前的高亮
removeRunningHighlight();
// 设置当前运行项目
currentRunningProject = { code, title, index };
// 高亮显示当前卡片
highlightRunningCard(index);
// 更新运行窗口
const blob = new Blob([code], {type: 'text/html'});
const iframe = document.getElementById('safari-iframe');
iframe.src = URL.createObjectURL(blob);
document.getElementById('safari-url').textContent = `localhost/${title.replace(/\s+/g, '-').toLowerCase()}.html`;
safariModal.classList.add('active');
minimizedWindow.classList.remove('active');
}
function highlightRunningCard(index) {
if (cards[index]) {
cards[index].classList.add('running');
}
}
function removeRunningHighlight() {
if (currentRunningProject && cards[currentRunningProject.index]) {
cards[currentRunningProject.index].classList.remove('running');
}
}
function editProject(index) {
const projects = JSON.parse(localStorage.getItem('projects') || '[]');
const project = projects[index];
if (!project) return;
currentEditIndex = index;
document.getElementById('project-title').value = project.title;
document.getElementById('project-code').value = project.code;
document.querySelector('#edit-modal .modal-title').textContent = '编辑项目';
openModal(editModal);
closeModal(safariModal);
}
function saveProject() {
const title = document.getElementById('project-title').value.trim();
const code = document.getElementById('project-code').value.trim();
if (!title || !code) {
alert('请填写项目名称和代码');
return;
}
const projects = JSON.parse(localStorage.getItem('projects') || '[]');
if (currentEditIndex >= 0) {
// 编辑现有项目
projects[currentEditIndex] = {
title,
code,
date: new Date().toISOString()
};
// 如果当前正在运行的是编辑的项目,更新运行内容
if (currentRunningProject && currentRunningProject.index === currentEditIndex) {
currentRunningProject.code = code;
const iframe = document.getElementById('safari-iframe');
const blob = new Blob([code], {type: 'text/html'});
iframe.src = URL.createObjectURL(blob);
}
} else {
// 添加新项目
projects.push({
title,
code,
date: new Date().toISOString()
});
}
localStorage.setItem('projects', JSON.stringify(projects));
closeModal(editModal);
loadProjects();
}
function deleteProject(index) {
if (!confirm('确定要删除这个项目吗?')) return;
const projects = JSON.parse(localStorage.getItem('projects') || '[]');
// 如果删除的是当前正在运行的项目,关闭运行窗口
if (currentRunningProject && currentRunningProject.index === index) {
safariModal.classList.remove('active');
document.getElementById('safari-iframe').src = '';
currentRunningProject = null;
}
projects.splice(index, 1);
localStorage.setItem('projects', JSON.stringify(projects));
loadProjects();
}
function handleFileImport(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(event) {
document.getElementById('project-code').value = event.target.result;
// 自动设置项目名为文件名(不含扩展名)
const fileName = file.name.replace(/\.[^/.]+$/, "");
document.getElementById('project-title').value = fileName;
};
reader.readAsText(file);
// 重置input,允许再次选择相同文件
e.target.value = '';
}
// 工具函数
function openModal(modal) {
modal.classList.add('active');
document.body.style.overflow = 'hidden';
}
function closeModal(modal) {
modal.classList.remove('active');
document.body.style.overflow = '';
}
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function formatDate(isoString) {
const date = new Date(isoString);
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
}
</script>
</body>
</html>
相关推荐
- 前端案例·程序员的浪漫:流星雨背景
-
如果文章对你有收获,还请不要吝啬【点赞收藏评论】三连哦,你的鼓励将是我成长助力之一!谢谢!(1)方式1:简单版本【1】先看实现效果...
- UI样式iPod classic的HTML本地音乐播放器框架
-
PS:音量可以鼠标点击按住在音量图标边的轮盘上下拖拽滑动音量大小中心按钮可以更改播放器为白色...
- JavaScript 强制回流问题及优化方案
-
JavaScript代码在运行过程中可能会强制触发浏览器的回流(Reflow)...
- Ai 编辑器 Cursor 零基础教程:推箱子小游戏实战演练
-
最近Ai火的同时,Ai编辑器Cursor同样火了一把。今天我们就白漂一下Cursor,使用免费版本搞一个零基础教程...
- 19年前司机被沉尸水库!凶手落网,竟已是身家千万的大老板
-
]|\[sS])*"|'(?:[^\']|\[sS])*'|[^)}]+)s*)/g,l=window.testenv_reshost||window.__moon_host||"res.wx.qq...
- 全民健身网络热度调查“居家健身”成为第一网络热词
-
]|\[sS])*"|'(?:[^\']|\[sS])*'|[^)}]+)s*)/g,l=window.testenv_reshost||window.__moon_host||"res.wx.qq...
- 取代JavaScript库的10个现代Web API及详细实施代码
-
为什么浏览器内置的API你还在用某个臃肿的Javascript库呢?用内置的API有什么好处呢?Web平台经历了巨大演进,引入了强大的原生API,不再需要臃肿的JavaScript库。现代浏览器现已支...
- 前端文件下载的N种姿势:从简单到高级
-
文件下载是web开发里一个非常常见的功能,无论是下载用户生成的数据、图片、文档还是应用程序包。前端开发者有多种方式来实现这一需求,每种方式都有其适用场景和优缺点。介绍下几种比较常用的文件下载方法。...
- JavaScript 性能优化方法(js前端性能优化)
-
JavaScript性能优化方法减少DOM操作频繁的DOM操作会导致浏览器重绘和回流,影响性能。使用文档片段(DocumentFragment)或虚拟DOM技术减少直接操作。...
- DOM节点的创建、插入、删除、查找、替换
-
在前端开发中,js与html联系最紧密的莫过于对DOM的操作了,本文为大家分享一些DOM节点的基本操作。一、创建DOM节点使用的命令是varoDiv=document.createElement...
- 前端里的拖拖拽拽(拖拽式前端框架)
-
最近在项目中使用了react-dnd,一个基于HTML5的拖拽库,“拖拽能力”丰富了前端的交互方式,基于拖拽能力,会扩展各种各样的拖拽反馈效果,因此有必要学习了解,最好的学习方式就是实操!...
- 大模型实战:Flask+H5三件套实现大模型基础聊天界面
-
本文使用Flask和H5三件套(HTML+JS+CSS)实现大模型聊天应用的基本方式话不多说,先贴上实现效果:流式输出:思考输出:聊天界面模型设置:模型设置会话切换:前言大模型的聊天应用从功能...
- SSE前端(sse前端数据)
-
<!DOCTYPEhtml><htmllang="zh-CN"><head>...
- 课堂点名总尴尬?试试 DeepSeek,或能实现点名自由!(附教程)
-
2025年2月26日"你有没有经历过这样的场景?老师拿着花名册扫视全班:'今天我们来点名...'那一刻心跳加速,默念:'别点我!'但现在,我要...
- 我会在每个项目中复制这10个JS代码片段
-
你是否也有这种感觉:在搭建新项目时,你会想:"这个函数我是不是已经写过了...在某个地方?"是的——我也是。所以在开发了数十个React、Node和全栈应用后,我不再重复造轮子。我创建...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)