卡片增加右键菜单

This commit is contained in:
wzj 2025-07-11 16:54:33 +08:00
parent 40dce39e94
commit 1517509776

View File

@ -874,6 +874,49 @@ body.dark-theme .secondary-filters-container::after {
box-sizing: border-box;
}
</style>
<style>
/* 右键菜单样式 */
.context-menu {
position: absolute;
z-index: 1000;
background-color: white;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
display: none;
}
.context-menu.dark {
background-color: #333;
border-color: #555;
}
.context-menu-item {
padding: 8px 16px;
cursor: pointer;
white-space: nowrap;
}
.context-menu-item:hover {
background-color: #f0f0f0;
}
.context-menu-item.dark:hover {
background-color: #444;
}
.context-menu-divider {
height: 1px;
background-color: #eee;
margin: 4px 0;
}
.context-menu-divider.dark {
background-color: #555;
}
</style>
</head>
<body>
<!-- 背景图片容器 -->
@ -927,6 +970,15 @@ body.dark-theme .secondary-filters-container::after {
<a href="/login?next=/" class="floating-btn" id="loginBtn" title="登录/退出"><i class="fas fa-sign-in-alt" style="color: #007bff;"></i></a>
</div>
<!-- 右键菜单 -->
<div id="contextMenu" class="context-menu">
<div class="context-menu-item" data-action="open">打开</div>
<div class="context-menu-item" data-action="copy">复制地址</div>
<div class="context-menu-divider"></div>
<div class="context-menu-item" data-action="edit" style="display: none;">编辑</div>
<div class="context-menu-item" data-action="delete" style="display: none;">删除</div>
</div>
<footer class="footer">
{% include 'footer.html' %}
</footer>
@ -1842,25 +1894,175 @@ body.dark-theme .secondary-filters-container::after {
});
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
loadData();
loadSettings();
setupSearch();
setupThemeSwitcher();
setupCompactToggle();
setupAdminButton();
setupBackToTop(); // 初始化返回顶部功能
// 右键菜单功能
function setupContextMenu() {
const contextMenu = document.getElementById('contextMenu');
let currentApp = null;
let currentAppIndex = -1;
// 为静态的一级筛选容器添加滚轮事件
primaryFilters.addEventListener('wheel', (e) => {
if (e.deltaY !== 0) {
e.preventDefault();
primaryFilters.scrollLeft += e.deltaY;
// 显示右键菜单
document.addEventListener('contextmenu', (e) => {
// 检查是否点击的是应用卡片
const appItem = e.target.closest('.app-item');
if (appItem) {
e.preventDefault();
// 找到对应的应用数据
const appTitle = appItem.querySelector('.app-title').textContent;
currentApp = apps.find(app => app.title === appTitle);
currentAppIndex = apps.findIndex(app => app.title === appTitle);
// 更新菜单位置
contextMenu.style.left = `${e.pageX}px`;
contextMenu.style.top = `${e.pageY}px`;
contextMenu.style.display = 'block';
// 根据主题设置菜单样式
if (document.body.classList.contains('dark-theme')) {
contextMenu.classList.add('dark');
contextMenu.querySelectorAll('.context-menu-item').forEach(item => item.classList.add('dark'));
contextMenu.querySelectorAll('.context-menu-divider').forEach(divider => divider.classList.add('dark'));
} else {
contextMenu.classList.remove('dark');
contextMenu.querySelectorAll('.context-menu-item').forEach(item => item.classList.remove('dark'));
contextMenu.querySelectorAll('.context-menu-divider').forEach(divider => divider.classList.remove('dark'));
}
});
// 显示/隐藏编辑和删除按钮(仅管理员可见)
const editItem = contextMenu.querySelector('[data-action="edit"]');
const deleteItem = contextMenu.querySelector('[data-action="delete"]');
if (isLoggedIn) {
editItem.style.display = 'block';
deleteItem.style.display = 'block';
} else {
editItem.style.display = 'none';
deleteItem.style.display = 'none';
}
}
});
// 隐藏右键菜单
document.addEventListener('click', (e) => {
if (!contextMenu.contains(e.target)) {
contextMenu.style.display = 'none';
}
});
// 菜单项点击处理
contextMenu.addEventListener('click', (e) => {
const menuItem = e.target.closest('.context-menu-item');
if (!menuItem || !currentApp) return;
const action = menuItem.dataset.action;
switch (action) {
case 'open':
window.open(currentApp.url, '_blank');
break;
case 'copy':
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(currentApp.url)
.then(() => {
showCopyNotification('已复制到剪贴板');
})
.catch(err => {
console.error('复制失败:', err);
fallbackCopyText(currentApp.url);
});
} else {
fallbackCopyText(currentApp.url);
}
break;
case 'edit':
if (isLoggedIn) {
window.location.href = `/app/edit/${currentAppIndex}`;
}
break;
case 'delete':
if (isLoggedIn) {
if (confirm(`确定要删除 "${currentApp.title}" 吗?`)) {
fetch(`/app/delete/${currentAppIndex}`, {
method: 'GET'
})
.then(response => {
if (response.ok) {
// 重新加载数据
loadData();
} else {
alert('删除失败');
}
})
.catch(error => {
console.error('删除失败:', error);
alert('删除失败');
});
}
}
break;
}
contextMenu.style.display = 'none';
});
}
// 在DOMContentLoaded事件中添加setupContextMenu调用
document.addEventListener('DOMContentLoaded', () => {
loadData();
loadSettings();
setupSearch();
setupThemeSwitcher();
setupCompactToggle();
setupAdminButton();
setupBackToTop();
setupContextMenu(); // 添加右键菜单功能
// 为静态的一级筛选容器添加滚轮事件
primaryFilters.addEventListener('wheel', (e) => {
if (e.deltaY !== 0) {
e.preventDefault();
primaryFilters.scrollLeft += e.deltaY;
}
});
});
// 显示复制成功的提示
function showCopyNotification(message) {
const notification = document.createElement('div');
notification.className = 'copy-notification';
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.classList.add('fade-out');
setTimeout(() => notification.remove(), 300);
}, 1000);
}
// 备用的复制方法
function fallbackCopyText(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed'; // 防止页面滚动
document.body.appendChild(textarea);
textarea.select();
try {
const successful = document.execCommand('copy');
const msg = successful ? '已复制到剪贴板' : '复制失败,请手动复制';
showCopyNotification(msg);
} catch (err) {
console.error('备用复制方法失败:', err);
showCopyNotification('复制失败,请手动复制');
}
document.body.removeChild(textarea);
}
function checkScrollable() {
document.querySelectorAll('.filter-row, .secondary-filters-container').forEach(container => {
// 检查内容宽度是否大于容器宽度