优化项目配置和页面结构
- 更新settings.local.json,移除冗余的权限设置,添加新的Playwright相关权限。 - 删除exhibition_demo_project_2025.md文档,清理不再使用的文件。 - 更新多个HTML页面,统一viewport设置,添加页面加载动画、错误处理和性能优化脚本。 - 统一使用Tailwind CSS的引入方式,提升页面加载性能。 - 增强导航组件,支持移动端菜单和返回顶部功能,改善用户体验。
This commit is contained in:
188
web_frontend/web_result/js/back-to-top.js
Normal file
188
web_frontend/web_result/js/back-to-top.js
Normal file
@@ -0,0 +1,188 @@
|
||||
// 返回顶部按钮组件
|
||||
(function() {
|
||||
// 创建返回顶部按钮HTML
|
||||
function createBackToTopButton() {
|
||||
const button = document.createElement('div');
|
||||
button.id = 'back-to-top';
|
||||
button.className = 'fixed bottom-8 right-8 z-40 opacity-0 pointer-events-none transition-all duration-300';
|
||||
button.innerHTML = `
|
||||
<button class="back-to-top-btn group relative w-12 h-12 bg-gradient-to-br from-emerald-400 to-blue-500 rounded-full shadow-lg hover:shadow-xl transform hover:scale-110 transition-all duration-300">
|
||||
<span class="absolute inset-0 rounded-full bg-white opacity-0 group-hover:opacity-10 transition-opacity duration-300"></span>
|
||||
<svg class="w-6 h-6 text-white absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18"></path>
|
||||
</svg>
|
||||
<span class="absolute -top-10 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity duration-300 whitespace-nowrap">
|
||||
返回顶部
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
document.body.appendChild(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
// 添加样式
|
||||
function addStyles() {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
#back-to-top.show {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#back-to-top:not(.show) {
|
||||
transform: translateY(100px);
|
||||
}
|
||||
|
||||
.back-to-top-btn {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.back-to-top-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.back-to-top-btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.back-to-top-btn svg {
|
||||
animation: float 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-50%) translateY(calc(-50% - 3px));
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
#back-to-top {
|
||||
bottom: 1.5rem;
|
||||
right: 1.5rem;
|
||||
}
|
||||
|
||||
.back-to-top-btn {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.back-to-top-btn svg {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 平滑滚动行为 */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* 防止按钮与其他元素冲突 */
|
||||
@media (max-width: 640px) {
|
||||
#back-to-top {
|
||||
bottom: 5rem; /* 避免与移动端菜单按钮重叠 */
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
// 滚动到顶部功能
|
||||
function scrollToTop() {
|
||||
// 使用 smooth 滚动
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
|
||||
// 可选:添加动画反馈
|
||||
const button = document.querySelector('.back-to-top-btn');
|
||||
if (button) {
|
||||
button.style.transform = 'scale(0.9)';
|
||||
setTimeout(() => {
|
||||
button.style.transform = '';
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
// 控制按钮显示/隐藏
|
||||
function handleScroll() {
|
||||
const button = document.getElementById('back-to-top');
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
// 当滚动超过一屏高度时显示按钮
|
||||
if (scrollTop > windowHeight * 0.5) {
|
||||
button.classList.add('show');
|
||||
} else {
|
||||
button.classList.remove('show');
|
||||
}
|
||||
|
||||
// 可选:根据滚动位置调整按钮透明度
|
||||
if (scrollTop > windowHeight) {
|
||||
const maxScroll = document.documentElement.scrollHeight - windowHeight;
|
||||
const scrollProgress = Math.min(scrollTop / maxScroll, 1);
|
||||
const opacity = 0.5 + scrollProgress * 0.5; // 从50%到100%透明度
|
||||
button.style.opacity = button.classList.contains('show') ? opacity : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
function init() {
|
||||
// 添加样式
|
||||
addStyles();
|
||||
|
||||
// 创建按钮
|
||||
const button = createBackToTopButton();
|
||||
|
||||
// 添加点击事件
|
||||
button.addEventListener('click', scrollToTop);
|
||||
|
||||
// 添加滚动监听(使用节流)
|
||||
let scrollTimer;
|
||||
window.addEventListener('scroll', () => {
|
||||
if (scrollTimer) {
|
||||
clearTimeout(scrollTimer);
|
||||
}
|
||||
scrollTimer = setTimeout(handleScroll, 50);
|
||||
});
|
||||
|
||||
// 初始检查
|
||||
handleScroll();
|
||||
|
||||
// 键盘快捷键支持(按 'T' 键返回顶部)
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// 排除输入框等元素
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
|
||||
return;
|
||||
}
|
||||
|
||||
// 按 T 键或 Home 键返回顶部
|
||||
if (e.key === 't' || e.key === 'T' || e.key === 'Home') {
|
||||
e.preventDefault();
|
||||
scrollToTop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// DOM加载完成后初始化
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user