ux: Toast 提示替代 alert,自动消失无需手动点击

This commit is contained in:
2026-04-16 13:41:46 +08:00
parent 974ccc6b24
commit 49b6f7aafe
2 changed files with 57 additions and 10 deletions

View File

@@ -10,6 +10,22 @@ document.addEventListener('DOMContentLoaded', function() {
refreshAll(); refreshAll();
}); });
// Toast 提示(自动消失)
function showToast(message, duration) {
duration = duration || 2000;
var toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(function() {
toast.classList.add('fade-out');
setTimeout(function() {
toast.remove();
}, 300);
}, duration);
}
// 点击模态框背景关闭 // 点击模态框背景关闭
function closeModalOnBackground(event, modalId) { function closeModalOnBackground(event, modalId) {
if (event.target.id === modalId) { if (event.target.id === modalId) {
@@ -92,13 +108,13 @@ function startScheduler() {
.then(function(res) { return res.json(); }) .then(function(res) { return res.json(); })
.then(function(data) { .then(function(data) {
if (data.success) { if (data.success) {
alert('Started!'); showToast('Started!', 1500);
refreshAll(); refreshAll();
} else { } else {
alert('Failed: ' + data.error); showToast('Failed: ' + data.error, 3000);
} }
}) })
.catch(function(e) { alert('Error: ' + e.message); }); .catch(function(e) { showToast('Error: ' + e.message, 3000); });
} }
function stopScheduler() { function stopScheduler() {
@@ -106,11 +122,11 @@ function stopScheduler() {
.then(function(res) { return res.json(); }) .then(function(res) { return res.json(); })
.then(function(data) { .then(function(data) {
if (data.success) { if (data.success) {
alert('Stopped!'); showToast('Stopped!', 1500);
refreshAll(); refreshAll();
} }
}) })
.catch(function(e) { alert('Error: ' + e.message); }); .catch(function(e) { showToast('Error: ' + e.message, 3000); });
} }
function captureNow() { function captureNow() {
@@ -118,23 +134,23 @@ function captureNow() {
.then(function(res) { return res.json(); }) .then(function(res) { return res.json(); })
.then(function(data) { .then(function(data) {
if (data.success) { if (data.success) {
alert('Capture success! Image ID: ' + data.image_id); showToast('Captured! ID: ' + data.image_id, 1500);
refreshAll(); refreshAll();
} else { } else {
alert('Capture failed: ' + data.error); showToast('Failed: ' + data.error, 3000);
} }
}) })
.catch(function(e) { alert('Error: ' + e.message); }); .catch(function(e) { showToast('Error: ' + e.message, 3000); });
} }
function analyzeUnanalyzed() { function analyzeUnanalyzed() {
fetch(API_BASE + '/api/analyze/unanalyzed', {method: 'POST'}) fetch(API_BASE + '/api/analyze/unanalyzed', {method: 'POST'})
.then(function(res) { return res.json(); }) .then(function(res) { return res.json(); })
.then(function(data) { .then(function(data) {
alert('Analyzed ' + data.results.length + ' images'); showToast('Analyzed ' + data.results.length + ' images', 1500);
refreshAll(); refreshAll();
}) })
.catch(function(e) { alert('Error: ' + e.message); }); .catch(function(e) { showToast('Error: ' + e.message, 3000); });
} }
// Images // Images

View File

@@ -453,6 +453,37 @@ button {
justify-content: center; justify-content: center;
} }
/* Toast 提示 */
.toast {
position: fixed;
top: 80px;
left: 50%;
transform: translateX(-50%);
background: #333;
color: white;
padding: 12px 24px;
border-radius: 8px;
z-index: 2000;
font-size: 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
animation: fadeIn 0.3s;
}
.toast.fade-out {
animation: fadeOut 0.3s;
opacity: 0;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
to { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
/* 响应式 */ /* 响应式 */
@media (max-width: 768px) { @media (max-width: 768px) {
.control-panel { .control-panel {