在本站,并不是所有页面都需要全局组件。而有些仅适用于单页的CSS也并不会加入整个网站的全局CSS中。
当然……这些组件对于文章编写与网站运行同样具有重要意义。

所以说……在下面找到自己想使用的组件吧……
别忘了使用以下的代码来将你选择的组件框选上以让其可在页面中以完整的HTML格式正常工作。

!!!
这里是组件代码
!!!

目录

页面内目录

注意:因为该站版式与博客系统的特性,在使用该组件时,请将页面的讨论区关闭。讨论区的标题使用的不是H2。

组件特点

该组件可绕过博客站的pjax设置,避免在删除原页面内容后无法加载目录的情况出现。

有意思的是,本组件的css可以影响博客站版式自带的目录。

组件源代码

<!-- 目录容器 -->
<div class="toc-container">
  <div class="toc-heading">目录</div>
  <div class="toc-list"></div>
</div>

<style>
/* 保持原有容器样式 */
.toc-container {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 1.2rem;
  margin: 1.5rem 0;
  background: #f8f9fa;
}

.toc-heading {
  font-size: 1.25rem;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 0.8rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid #3498db;
}

/* 调整列表容器 */
.toc-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* 目录项样式 */
.toc-item {
  line-height: 1.5;
  transition: transform 0.2s ease;
  position: relative;
}

.toc-item:hover {
  transform: translateX(5px);
}

/* 层级缩进 */
.toc-item.h3 { margin-left: 1rem; }
.toc-item.h4 { margin-left: 2rem; }
.toc-item.h5 { margin-left: 3rem; }

/* 链接样式 */
.toc-item a {
  text-decoration: none;
  color: #34495e;
  display: block;
  padding: 0.3rem 0.8rem;
  border-radius: 4px;
  position: relative;
}

.toc-item a:hover {
  color: #2980b9;
  background: #ecf5ff;
}

/* 可选的连接线样式 */
.toc-item::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 50%;
  height: 1px;
  width: 6px;
  background: #3498db;
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity 0.2s;
}

.toc-item:hover::before {
  opacity: 1;
}
</style>

<script>
// 将目录生成逻辑封装成函数
function generateTOC() {
  const tocList = document.querySelector('.toc-list');
  // 清空旧内容
  tocList.innerHTML = '';
  
  // 使用更精确的选择器避免获取到其他区域标题
  const headings = document.querySelectorAll('.post-content h2, .post-content h3, .post-content h4, .post-content h5');

  headings.forEach(heading => {
    // 添加防重复ID生成逻辑
    if (!heading.id) {
      const baseID = heading.textContent
        .toLowerCase()
        .replace(/[^\w\u4e00-\u9fa5]+/g, '-')
        .replace(/^-|-$/g, '');
      
      // 添加唯一性校验
      let uniqueID = baseID;
      let counter = 1;
      while (document.getElementById(uniqueID)) {
        uniqueID = `${baseID}-${counter++}`;
      }
      heading.id = uniqueID;
    }

    // 创建目录项(保持之前的div结构)
    const item = document.createElement('div');
    item.className = `toc-item ${heading.tagName.toLowerCase()}`;
    
    const link = document.createElement('a');
    link.href = `#${heading.id}`;
    link.textContent = heading.textContent;
    
    // 增强的滚动定位逻辑
    link.addEventListener('click', (e) => {
      e.preventDefault();
      const target = document.getElementById(heading.id);
      if (target) {
        const offset = 96; // 根据实际header高度调整
        const topPos = target.getBoundingClientRect().top + window.pageYOffset - offset;
        
        window.scrollTo({
          top: topPos,
          behavior: 'smooth'
        });
        
        // PJAX兼容的hash更新
        history.replaceState({}, '', `#${heading.id}`);
      }
    });

    item.appendChild(link);
    tocList.appendChild(item);
  });
}

// 初始加载
document.addEventListener('DOMContentLoaded', generateTOC);

// PJAX兼容处理
document.addEventListener('pjax:complete', generateTOC); // 通用PJAX事件
document.addEventListener('pjax:success', generateTOC);  // 部分库使用这个事件

// 如果使用WordPress等CMS,可能需要以下适配
document.addEventListener('DOMSubtreeModified', function(e) {
  if (document.querySelector('.pjax-container')) {
    generateTOC();
  }
});
</script>

组件预览

看到页面上的目录了嘛?那个目录用的就是这个组件哦~