Skip to content

思维导图全屏

概述

本文档描述了 Hugo Markmap shortcode 的全屏功能实现,包括功能特性、使用方法、技术实现和故障排除。

功能特性

🖥️ 全屏显示

  • 点击工具栏的全屏按钮进入全屏模式
  • 支持多种退出方式:
  • 点击右上角的关闭按钮 (×)
  • 按 ESC 键
  • 再次点击工具栏的全屏按钮

📱 响应式设计

  • 桌面端:显示完整的工具栏(放大、缩小、适应窗口、折叠所有、全屏显示)
  • 移动端:仅显示核心按钮(适应窗口、折叠所有、全屏显示)

🌓 暗黑模式支持

  • 自动检测并适配暗黑模式
  • 全屏模式下保持正确的颜色主题

🔄 智能按钮状态管理

  • 全屏按钮图标动态切换:
  • 非全屏:fa-expand (展开图标)
  • 全屏:fa-compress (压缩图标)
  • 工具提示自动更新:
  • 非全屏:「全屏显示」
  • 全屏:「退出全屏」

使用方法

基本用法

{{< markmap file="path/to/mindmap.md" height="600px" >}}

全屏操作

  1. 进入全屏
  2. 点击工具栏最右侧的全屏按钮(展开图标)
  3. 或在移动端点击右下角的第三个按钮

  4. 退出全屏

  5. 点击右上角的关闭按钮(×)
  6. 按键盘的 ESC 键
  7. 点击工具栏的全屏按钮(压缩图标)

技术实现

核心组件

1. 全屏按钮创建

const fullscreenBtn = document.createElement('div');
fullscreenBtn.className = 'mm-toolbar-item';
fullscreenBtn.innerHTML = '<i class="fas fa-expand"></i>';
fullscreenBtn.setAttribute('title', '全屏显示');

2. 智能状态切换

fullscreenBtn.addEventListener('click', () => {
  const isCurrentlyFullscreen = containerElement.classList.contains('markmap-container-fullscreen');

  if (isCurrentlyFullscreen) {
    // 退出全屏
    fullscreenBtn.innerHTML = '<i class="fas fa-expand"></i>';
    fullscreenBtn.setAttribute('title', '全屏显示');
  } else {
    // 进入全屏
    fullscreenBtn.innerHTML = '<i class="fas fa-compress"></i>';
    fullscreenBtn.setAttribute('title', '退出全屏');
  }

  toggleFullscreen();
});

3. 退出全屏按钮

const exitBtn = document.createElement('button');
exitBtn.className = 'markmap-fullscreen-exit';
exitBtn.innerHTML = '<i class="fas fa-times"></i>';
exitBtn.onclick = function(e) {
  e.preventDefault();
  e.stopPropagation();

  // 更新全屏按钮状态
  const toolbar = containerElement.querySelector('.mm-toolbar');
  if (toolbar) {
    const allToolbarItems = toolbar.querySelectorAll('.mm-toolbar-item');
    const fullscreenBtn = allToolbarItems[allToolbarItems.length - 1];
    if (fullscreenBtn) {
      fullscreenBtn.innerHTML = '<i class="fas fa-expand"></i>';
      fullscreenBtn.setAttribute('title', '全屏显示');
    }
  }
  exitFullscreen();
};

CSS 样式

全屏容器

.markmap-container-fullscreen {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  z-index: 9999 !important;
  background: var(--bg-color, #fff) !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
  border-radius: 0 !important;
}

退出按钮

.markmap-fullscreen-exit {
  position: fixed !important;
  top: 1rem !important;
  right: 1rem !important;
  z-index: 10000 !important;
  width: 2.5rem !important;
  height: 2.5rem !important;
  border: none !important;
  border-radius: 50% !important;
  background: rgba(0, 0, 0, 0.7) !important;
  color: white !important;
  cursor: pointer !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 1.25rem !important;
  transition: all 0.2s ease !important;
}

移动端适配

@media (max-width: 768px) {
  .mm-toolbar .mm-toolbar-item:nth-child(3),
  .mm-toolbar .mm-toolbar-item:nth-child(4),
  .mm-toolbar .mm-toolbar-item:nth-child(5) {
    display: flex !important;
  }
}

关键技术点

1. 作用域管理

由于 JavaScript 闭包的限制,使用 DOM 查询而非变量引用:

// 避免作用域问题
const toolbar = containerElement.querySelector('.mm-toolbar');
const allToolbarItems = toolbar.querySelectorAll('.mm-toolbar-item');
const fullscreenBtn = allToolbarItems[allToolbarItems.length - 1];

2. 事件处理

使用多重事件绑定确保可靠性:

// 主要事件处理
exitBtn.onclick = function(e) { /* ... */ };

// 备用事件处理
exitBtn.addEventListener('click', function(e) { /* ... */ });

3. 响应式控制

JavaScript 动态控制移动端按钮显示:

function updateMobileToolbar() {
  const isMobile = window.innerWidth <= 768;
  if (isMobile) {
    // 只显示第 3、4、5 个按钮
    if (index === 2 || index === 3 || index === 4) {
      item.style.setProperty('display', 'flex', 'important');
    } else {
      item.style.setProperty('display', 'none', 'important');
    }
  }
}

兼容性

浏览器支持

  • ✅ Chrome 60+
  • ✅ Firefox 55+
  • ✅ Safari 12+
  • ✅ Edge 79+

设备支持

  • ✅ 桌面端(Windows、macOS、Linux)
  • ✅ 移动端(iOS、Android)
  • ✅ 平板电脑

主题支持

  • ✅ 亮色模式
  • ✅ 暗黑模式
  • ✅ 自动主题切换

故障排除

常见问题

1. 全屏按钮不显示

原因:Font Awesome 图标库未加载 解决方案

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

2. 移动端按钮布局异常

原因:CSS 优先级冲突 解决方案:检查自定义 CSS 是否覆盖了 !important 样式

3. 退出按钮无响应

原因:JavaScript 错误或 DOM 结构问题 解决方案

  1. 检查浏览器控制台错误
  2. 确认 markmap 正确加载
  3. 验证 CSS 样式未被覆盖

4. ESC 键无效

原因:事件监听器未正确绑定 解决方案:确保进入全屏后事件监听器已添加

调试技巧

  1. 检查元素状态
// 检查全屏状态
console.log(containerElement.classList.contains('markmap-container-fullscreen'));

// 检查按钮是否存在
console.log(document.querySelector('.markmap-fullscreen-exit'));
  1. 验证工具栏
// 检查工具栏按钮数量
const toolbar = containerElement.querySelector('.mm-toolbar');
console.log(toolbar.querySelectorAll('.mm-toolbar-item').length);
  1. 测试事件绑定
// 手动触发全屏切换
toggleFullscreen();

更新日志

v1.3.0 (当前版本)

  • ✅ 优化了加载动画样式,解决双重旋转图标问题
  • ✅ 改进了加载状态的视觉设计和用户体验
  • ✅ 添加了优雅的淡入动画和文字动效
  • ✅ 增强了移动端加载样式的响应式适配

v1.2.0

  • ✅ 修复了全屏按钮状态同步问题
  • ✅ 改进了移动端响应式布局
  • ✅ 解决了 JavaScript 作用域问题
  • ✅ 增强了事件处理可靠性
  • ✅ 优化了 CSS 样式优先级

v1.1.0

  • ✅ 添加了 ESC 键退出功能
  • ✅ 实现了移动端工具栏适配
  • ✅ 支持暗黑模式

v1.0.0

  • ✅ 基础全屏功能
  • ✅ 工具栏按钮集成

贡献指南

如需改进此功能,请:

  1. Fork 项目
  2. 创建功能分支
  3. 测试所有设备和浏览器
  4. 提交 Pull Request

许可证

本功能遵循项目主许可证。


最后更新:2025 年 6 月 20 日