其他杂项

others
其他系统相关杂项问题

如何给网站文章页前面自动加个目录导航

2周前 (03-18)其他杂项133

一些网站文章正文前有个目录导航,这是根据本文的h标签自动添加上去的,一些朋友可能需要这样的功能,其实本站文章页面也是如此显示,但此种写法只适用Zblog系统,下面给出个通用方案。

要实现的效果类似下图

18-50.jpg

修改简要文字说明

本文分享具体代码,主要涉及正文html, JS, CSS三部分文件,请参考自己实际程序修改。使用说明

将HTML中的<div id="toc-container"></div>放在你想要显示目录的位置

确保文章内容包含在<article class="content">中(可修改配置中的选择器)

标题需要包含在配置的heading标签内(默认h2-h4)

可选功能:

修改config.scrollOffset调整滚动偏移量

设置config.collapseDepth控制默认折叠层级

通过CSS自定义目录样式

正文HTML模板文件

<!-- HTML 部分 -->
<div id="toc-container"></div> <!-- 目录将插入到这里 -->
<article class="content">
  <!-- 你的文章内容,包含 h2/h3/h4 等标题 -->
</article>

CSS样式部分代码

/* CSS 样式 */
#toc-container {
  position: fixed;
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  background: #f5f5f5;
  padding: 15px;
  border-radius: 8px;
  max-width: 300px;
  max-height: 80vh;
  overflow-y: auto;
}
.toc-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
}
.toc-list li {
  margin: 5px 0;
  line-height: 1.4;
}
.toc-list a {
  color: #333;
  text-decoration: none;
  transition: color 0.3s;
}
.toc-list a:hover {
  color: #007bff;
}
.toc-list .active > a {
  color: #007bff;
  font-weight: bold;
}
/* 嵌套列表缩进 */
.toc-list ul {
  padding-left: 1em;
  list-style: none;
  border-left: 1px solid #ddd;
}

JS文件增加或者修改

function generateTOC() {
  // 配置参数
  const config = {
    container: '#toc-container', // 目录插入位置
    content: '.content',         // 内容区域选择器
    headings: ['h2', 'h3', 'h4'], // 要包含的标题标签
    scrollSmooth: true,          // 是否平滑滚动
    scrollOffset: 20,            // 滚动偏移量(px)
    collapseDepth: 0             // 默认展开层级(0=全部展开)
  };
  // 获取所有目标标题
  const headings = document.querySelectorAll(config.content + ' ' + config.headings.join(', '));
  if (headings.length === 0) return;
  // 创建目录容器
  const container = document.querySelector(config.container);
  const tocWrapper = document.createElement('div');
  tocWrapper.className = 'toc-wrapper';
  
  // 创建列表
  const tocList = document.createElement('ul');
  tocList.className = 'toc-list';
  let currentUl = tocList;
  const stack = [tocList];
  let previousLevel = 0;
  headings.forEach((heading, index) => {
    // 确保标题有ID
    if (!heading.id) {
      heading.id = 'heading-' + index;
    }
    // 获取标题级别
    const level = parseInt(heading.tagName.substring(1));
    // 创建列表项
    const listItem = document.createElement('li');
    const link = document.createElement('a');
    link.href = '#' + heading.id;
    link.textContent = heading.textContent;
    
    // 添加点击事件
    link.addEventListener('click', (e) => {
      e.preventDefault();
      scrollToHeading(heading);
    });
    // 处理嵌套层级
    if (level > previousLevel) {
      const newUl = document.createElement('ul');
      newUl.className = 'toc-list';
      listItem.appendChild(newUl);
      stack.push(newUl);
      currentUl = newUl;
    } else if (level < previousLevel) {
      const popCount = previousLevel - level;
      for (let i = 0; i < popCount; i++) {
        stack.pop();
      }
      currentUl = stack[stack.length - 1];
    }
    listItem.appendChild(link);
    currentUl.appendChild(listItem);
    previousLevel = level;
  });
  // 插入目录
  tocWrapper.appendChild(tocList);
  container.appendChild(tocWrapper);
  // 平滑滚动函数
  function scrollToHeading(heading) {
    const offset = heading.getBoundingClientRect().top + window.scrollY - config.scrollOffset;
    window.scrollTo({
      top: offset,
      behavior: config.scrollSmooth ? 'smooth' : 'auto'
    });
  }
  // 高亮当前章节(可选)
  function updateActiveLink() {
    const links = tocWrapper.querySelectorAll('a');
    links.forEach(link => {
      const section = document.querySelector(link.getAttribute('href'));
      const rect = section.getBoundingClientRect();
      if (rect.top <= config.scrollOffset && rect.bottom >= 0) {
        link.parentElement.classList.add('active');
      } else {
        link.parentElement.classList.remove('active');
      }
    });
  }
  // 滚动监听
  window.addEventListener('scroll', () => {
    updateActiveLink();
  });
}
// 初始化目录生成
document.addEventListener('DOMContentLoaded', generateTOC);

进一步完善代码

通过上面的代码修改已经实现了基本需求功能,下面代码是让显示更加完美。

这个实现方案有以下特点:

自动识别标题层级并生成嵌套目录

支持平滑滚动定位

自动添加锚点ID

当前阅读位置高亮

响应式设计

可通过CSS完全自定义样式

你可以根据实际需求调整配置参数和样式表现。要修改包含的标题级别,只需修改配置中的headings数组即可(例如改为['h2', 'h3'])

JS增加部分代码实现点击展开折叠

// 在link.addEventListener点击事件中添加:
if (e.target.nextElementSibling?.tagName === 'UL') {
  e.target.nextElementSibling.classList.toggle('collapsed');
}

在CSS中添加下面代码实现自动添加序号和自适应

.toc-list li {
  counter-increment: section;
}
.toc-list li a::before {
  content: counters(section, ".") ". ";
}
@media (max-width: 768px) {
  #toc-container {
    position: static;
    max-width: 100%;
  }
}


版权声明:本文由贝联科技发布,如需转载请注明出处,如需分享可点击上方生成海报按钮。

分享给朋友:

相关文章

如何屏蔽PetalBot蜘蛛等垃圾蜘蛛办法分享

如何屏蔽PetalBot蜘蛛等垃圾蜘蛛办法分享

本人有一个 小网站,后台可以查看蜘蛛数据,经常发现有许多国外蜘蛛爬取。作为一个面向国内特定地域用户的网站,着实用不着那些蜘蛛来消耗资源,网上找到一段Nginx配置代码,加上后很灵敏,那些国外蜘蛛第二天就不来了。 if (...

互联网项目引流的指导思想和误区

互联网项目引流的指导思想和误区

本文源自义乌之狼微信群内一个群友分享的三张引流图片,觉得挺有价值,特在此分享。一、引流指导思想1.1引流(革命)思想,指导路线革命指导思想--农村包围城市,武装夺取政权;引流指导思想-广告化(形式)策略,流水化(批量)生产。1.2思想策略,...

win10系统如何删除任务栏图标残留

win10系统如何删除任务栏图标残留

本人win10电脑上装过一些软件后已删除,但是发现在“选择哪些图标显示在任务栏上”里面仍然存在这些软件名字,让完美倾向者看着非常难受。网上搜索发现不少人也遇到这问题,并提出了解决方法。我参照一个方案进行操作,发现没起作用。后来经过反复对比,...

正则表达式自学教程

正则表达式自学教程

因为本人有时需要批量替换改写文章,简单的关键词替换不能满足需求,不得不学习正则表达式,作为一个新手,这里记录一些正则规则和遇到的问题。 一、正则常用到符号含义1.1.第一批正则学习[]匹配列表之中的任何单个字符.例如,"...

华为云主机重装系统、宝塔环境一点总结

华为云主机重装系统、宝塔环境一点总结

因为朋友的华为云主机出了问题,我需要给重新安装系统和做好一个企业网站。本人也是摸索学习,这里总结下经验,附宝塔官方安装教程步骤一:华为云重装系统打开网址 https://www.huaweicloud.com 登录进入弹...

转载的CSS两列布局,三列布局方法

转载的CSS两列布局,三列布局方法

下面方法主要用的display:inline-block属性,设置同行DIV宽度,另一个DIV用margin限制宽度。按照文档流默认显示方法CSS两列布局,右侧固定,左侧自适应宽度 <div style="widt...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
现在,非常期待与您的又一次邂逅

我们努力让每一次邂逅总能超越期待

智能客服
欢迎咨询智能客服,我可以回答些简单问题