其他杂项

others
其他系统相关杂项问题

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

1个月前 (03-18)其他杂项533

一些网站文章正文前有个目录导航,这是根据本文的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%;
  }
}


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

分享给朋友:

相关文章

pbootcms多语言建站常见问题(转载)

pbootcms多语言建站常见问题(转载)

一、如何搭建多语言站?多语言/区域建站用于使用同一个后台建立多语言网站。1、使用步骤1)在后台”系统管理>数据区域”添加相应的区域,具体参考默认区域;2)将多语言的模板放入模板目录,不同语言的模板均放在template目录下;3)在后...

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

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

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

Win10系统22H2版本如何关闭讨厌的热门搜索推荐栏

Win10系统22H2版本如何关闭讨厌的热门搜索推荐栏

本人电脑以前是win10系统21H1版本,已经手动关闭了系统自带所有广告提示,今天电脑自动升级到了22H2版本,居然在使用本地搜索功能时出现一个热门搜索栏。里面显示乱七八糟的推荐内容,一旦点击,就会跳转到Edge浏览器中Bing搜索结果页面...

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

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

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

Zblog搜索无结果时增加一个友好提示

Zblog搜索无结果时增加一个友好提示

Zblog是个不错的博客程序,但官方不知道怎么回事不去用心完善一些基本功能,我使用时就频频发现一些缺陷bug,都有些怀疑官方故意如此是为了卖付费插件增加收入。上次发了通过修改js文件,避免前台空搜索bug的解决办法。还有一个不大不小的问题,...

百度UEditor编辑器自定义标题样式修改教程

百度UEditor编辑器自定义标题样式修改教程

因为自己运营的某个网站后台编辑器使用的是百度UEditor,用这个编辑器自带功能给文章可以加四个自带标题样式,但这个标题样式令人难以满意,故决定自己动手修改。从网上搜索教程,发现可能涉及到两个文件的修改,一个是该编辑器目录下editor/u...

发表评论

访客

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

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

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