first initial commit
This commit is contained in:
150
assets/js/mobile-menu.js
Normal file
150
assets/js/mobile-menu.js
Normal file
@@ -0,0 +1,150 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
let drawerElement = null;
|
||||
let isDrawerOpen = false;
|
||||
|
||||
// 创建抽屉 (从隐藏的 div 克隆)
|
||||
function createDrawer() {
|
||||
const template = document.getElementById('mobile-drawer-template');
|
||||
if (!template) {
|
||||
console.error('Drawer template not found');
|
||||
return null;
|
||||
}
|
||||
|
||||
const overlay = template.querySelector('#mobile-sidebar-overlay');
|
||||
if (!overlay) {
|
||||
console.error('Overlay element not found in template');
|
||||
return null;
|
||||
}
|
||||
|
||||
const clone = overlay.cloneNode(true);
|
||||
clone.id = 'mobile-sidebar-overlay-active';
|
||||
|
||||
// --- [新增逻辑] 自动搬运侧边栏挂件 ---
|
||||
const sidebarWidgets = document.getElementById('sidebar-widgets');
|
||||
const drawerContent = clone.querySelector('.p-5.space-y-6'); // 抽屉的内容容器
|
||||
|
||||
if (sidebarWidgets && drawerContent) {
|
||||
// 创建一个专门存放侧边栏内容的容器
|
||||
const sidebarMobileContainer = document.createElement('section');
|
||||
sidebarMobileContainer.className = 'mobile-sidebar-content space-y-6 pt-4 border-t border-gray-100';
|
||||
sidebarMobileContainer.innerHTML = '<h3 class="text-xs font-bold text-gray-400 uppercase tracking-wider mb-4">实时资讯</h3>';
|
||||
|
||||
// 克隆侧边栏所有的子元素(欢迎卡片、计时器等)
|
||||
const widgetsClone = sidebarWidgets.cloneNode(true);
|
||||
// 移除原本的 ID 避免冲突
|
||||
widgetsClone.removeAttribute('id');
|
||||
// 将侧边栏内容追加到抽屉中
|
||||
sidebarMobileContainer.appendChild(widgetsClone);
|
||||
drawerContent.appendChild(sidebarMobileContainer);
|
||||
}
|
||||
// ------------------------------------
|
||||
|
||||
document.body.appendChild(clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
function openDrawer() {
|
||||
if (isDrawerOpen) return;
|
||||
|
||||
if (!drawerElement) {
|
||||
drawerElement = createDrawer();
|
||||
if (!drawerElement) return;
|
||||
bindDrawerEvents();
|
||||
}
|
||||
|
||||
// 锁定背景滚动
|
||||
const scrollY = window.scrollY;
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.position = 'fixed';
|
||||
document.body.style.top = `-${scrollY}px`;
|
||||
document.body.style.width = '100%';
|
||||
|
||||
drawerElement.style.display = 'block';
|
||||
isDrawerOpen = true;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
const backdrop = drawerElement.querySelector('.drawer-backdrop');
|
||||
const panel = drawerElement.querySelector('.drawer-panel');
|
||||
if (backdrop) backdrop.style.opacity = '1';
|
||||
if (panel) panel.style.transform = 'translateX(0)';
|
||||
});
|
||||
});
|
||||
|
||||
// 如果克隆的内容里包含计时器,需要重新初始化计时器逻辑
|
||||
if (window.initTimers) window.initTimers(drawerElement);
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
if (!isDrawerOpen || !drawerElement) return;
|
||||
|
||||
const backdrop = drawerElement.querySelector('.drawer-backdrop');
|
||||
const panel = drawerElement.querySelector('.drawer-panel');
|
||||
|
||||
if (backdrop) backdrop.style.opacity = '0';
|
||||
if (panel) panel.style.transform = 'translateX(100%)';
|
||||
|
||||
setTimeout(() => {
|
||||
if (drawerElement) {
|
||||
drawerElement.style.display = 'none';
|
||||
}
|
||||
|
||||
// 恢复滚动
|
||||
const scrollY = document.body.style.top;
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.top = '';
|
||||
document.body.style.width = '';
|
||||
window.scrollTo(0, parseInt(scrollY || '0') * -1);
|
||||
|
||||
isDrawerOpen = false;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function bindDrawerEvents() {
|
||||
if (!drawerElement) return;
|
||||
|
||||
const closeBtn = drawerElement.querySelector('#drawer-close-btn');
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
closeDrawer();
|
||||
});
|
||||
}
|
||||
|
||||
const backdrop = drawerElement.querySelector('.drawer-backdrop');
|
||||
if (backdrop) {
|
||||
backdrop.addEventListener('click', closeDrawer);
|
||||
}
|
||||
|
||||
const links = drawerElement.querySelectorAll('.drawer-link, .mobile-nav-grid a, a');
|
||||
links.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
setTimeout(closeDrawer, 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const trigger = document.getElementById('mobile-menu-trigger');
|
||||
if (trigger) {
|
||||
trigger.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openDrawer();
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && isDrawerOpen) closeDrawer();
|
||||
});
|
||||
});
|
||||
|
||||
window.mobileMenu = {
|
||||
open: openDrawer,
|
||||
close: closeDrawer,
|
||||
isOpen: () => isDrawerOpen
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user