导航栏背景
功能概述
本次修改实现了移动端导航栏的以下功能:
- 毛玻璃遮罩效果 - 当导航栏打开时显示半透明的遮罩层
- 只能通过按钮关闭 - 移除了点击外部区域关闭导航栏的功能
- 禁用页面滚动 - 导航栏打开时禁用 body 滚动
- 禁用移动端 TOC 按钮 - 导航栏打开时禁用移动 TOC 浮动按钮
修改的文件
1. /assets/js/main.js
修改的函数
updateIconStates()
- 添加了调用showNavigationBackdrop()
和hideNavigationBackdrop()
的逻辑- 新增
showNavigationBackdrop()
- 创建并显示遮罩层,禁用滚动 - 新增
hideNavigationBackdrop()
- 移除遮罩层,恢复滚动 - 移除点击外部关闭功能 - 删除了外部点击事件监听器
关键代码片段
// Function to show navigation backdrop
function showNavigationBackdrop() {
console.log('showNavigationBackdrop called');
// Remove any existing backdrop first
const existingBackdrop = document.getElementById('navbar-backdrop');
if (existingBackdrop) {
existingBackdrop.remove();
}
// Create new backdrop
const backdrop = document.createElement('div');
backdrop.id = 'navbar-backdrop';
backdrop.style.cssText = `
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
background: rgba(0, 0, 0, 0.5) !important;
z-index: 985 !important;
opacity: 1 !important;
visibility: visible !important;
pointer-events: auto !important;
`;
document.body.appendChild(backdrop);
document.body.style.overflow = 'hidden';
// Disable mobile TOC floating button
const mobileTocBtn = document.getElementById('mobile-toc-btn');
if (mobileTocBtn) {
mobileTocBtn.style.pointerEvents = 'none';
mobileTocBtn.style.opacity = '0.3';
}
}
2. /assets/scss/templates/_navigation.scss
添加的样式
// 移动端导航栏毛玻璃遮罩效果
.navbar-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
z-index: 985;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
pointer-events: none;
&.show {
opacity: 1;
visibility: visible;
pointer-events: auto;
}
/* Dark mode support */
.dark-mode & {
background: rgba(0, 0, 0, 0.6);
}
}
/* 确保移动端导航栏在遮罩之上 */
@media (max-width: 991px) {
.header {
z-index: 991 !important;
}
.navbar-collapse {
position: relative;
z-index: 992;
background: var(--nav-bg);
}
}
3. /assets/js/mobile-toc-optimized.js
修改内容
- 在
click
事件处理函数中添加导航栏状态检查 - 在
handlePointerEnd
函数中添加导航栏状态检查
关键代码片段
// 主要的点击事件处理
tocBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// 检查导航栏是否打开,如果打开则不允许操作 TOC
const navigation = document.getElementById('navigation');
if (navigation && navigation.classList.contains('show')) {
console.log('Navigation is open, TOC button disabled');
return;
}
// 检查按钮是否被禁用
if (tocBtn.style.pointerEvents === 'none') {
console.log('TOC button is disabled');
return;
}
// ... 原有逻辑
});
实现原理
- 遮罩层创建 - 当导航栏打开时,动态创建一个全屏的 div 元素作为遮罩层
- 层级管理 - 使用 z-index 确保遮罩层在内容之上,但在导航栏之下
- 滚动控制 - 通过设置
body.style.overflow = 'hidden'
禁用页面滚动 - 交互控制 - 通过修改
pointerEvents
和opacity
禁用其他交互元素 - 状态同步 - 在导航栏状态改变时同步更新遮罩层状态
浏览器兼容性
- backdrop-filter - 支持现代浏览器,包括 Safari、Chrome、Firefox 等
- -webkit-backdrop-filter - 提供对旧版 WebKit 浏览器的支持
- fallback - 对于不支持 backdrop-filter 的浏览器,仍有半透明背景效果
测试建议
- 在移动设备或浏览器开发者工具的移动视图中测试
- 验证导航栏打开时是否出现遮罩层
- 确认页面无法滚动
- 确认只能通过汉堡菜单按钮关闭导航栏
- 确认 mobile TOC 按钮被正确禁用
- 测试暗色模式下的效果
注意事项
- 遮罩层使用内联样式确保优先级
- z-index 值需要与其他组件协调
- 考虑了暗色模式的支持
- 添加了适当的 console.log 用于调试