Loading

Typecho Joe主题自定义目录树

1、修改主题模版

编辑Joe主题文件夹public/aside.php文件

<section id="toc" class="joe_aside__item" style="display:none;">
  <div class="joe_aside__item-title menu_title">
    <svg t="1642997936013" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2169" width="128" height="128"><path d="M838.3 895.9H197.9c-53.9 0-97.7-43.8-97.7-97.7V236.7c0-53.9 43.8-97.7 97.7-97.7h640.3c53.9 0 97.7 43.8 97.7 97.7v561.4c0.1 53.9-43.7 97.8-97.6 97.8zM197.9 203.8c-18.1 0-32.9 14.8-32.9 32.9v561.4c0 18.1 14.8 32.9 32.9 32.9h640.3c18.1 0 32.9-14.8 32.9-32.9V236.7c0-18.1-14.8-32.9-32.9-32.9H197.9z" fill="#666666" p-id="2170"></path><path d="M695.1 455.2H341.2c-17.9 0-32.4-14.5-32.4-32.4s14.5-32.4 32.4-32.4h353.9c17.9 0 32.4 14.5 32.4 32.4s-14.5 32.4-32.4 32.4zM695.1 578.2H341.2c-17.9 0-32.4-14.5-32.4-32.4s14.5-32.4 32.4-32.4h353.9c17.9 0 32.4 14.5 32.4 32.4s-14.5 32.4-32.4 32.4zM695.1 701.2H341.2c-17.9 0-32.4-14.5-32.4-32.4s14.5-32.4 32.4-32.4h353.9c17.9 0 32.4 14.5 32.4 32.4s-14.5 32.4-32.4 32.4zM379.1 281.1c-17.9 0-32.4-14.5-32.4-32.4V115.4c0-17.9 14.5-32.4 32.4-32.4s32.4 14.5 32.4 32.4v133.2c0 17.9-14.5 32.5-32.4 32.5zM657.1 281.1c-17.9 0-32.4-14.5-32.4-32.4V115.4c0-17.9 14.5-32.4 32.4-32.4s32.4 14.5 32.4 32.4v133.2c0 17.9-14.5 32.5-32.4 32.5z" fill="#666666" p-id="2171"></path></svg>
    <span class="text">目录</span>
  </div>
</section>

2、编写目录生成脚本

toc-nav.js脚本动态生成目录树,并将目录插入到元素ID是toc的标签内

// 获取文章页面h1~h6标签
const article = document.querySelector('.joe_detail__article');
const list = article.querySelectorAll('h1, h2, h3, h4, h5, h6');

// 为标题标签添加动态ID
list.forEach(element => {
    let id = element.id || ('toc-index-' + Math.random()).replace('0.', '');
    element.id = id;
});

// 生成TOC目录
const container = document.createElement('ul');
container.classList.add('toc-container');
list.forEach(item => {
    let li = document.createElement('li');
    li.classList.add('nav-item');
    li.classList.add('nav-item-' + item.tagName.toLowerCase());

    let a = document.createElement('a');
    a.setAttribute('data', '#' + item.id);
    a.innerText = item.innerText;

    li.append(a);
    container.append(li);
});

document.querySelector('#toc').append(container);

// 目录点击跳转
const tocContainer = document.querySelector('.toc-container');
tocContainer.addEventListener('click', function(event) {
    event.preventDefault();
    let id = event.target.getAttribute('data')
    document.querySelector(id).scrollIntoView({
        behavior: 'smooth',
        block: 'center',

    });

});

function removeHighLight() {
    document.querySelectorAll('#toc .active').forEach(item => {
        item.classList.remove('active');
    });
}


// 为标题添加交叉观察器
let observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            // 删除已经高亮的元素
            removeHighLight();
            let targetId = entry.target.id;
            let anchor = document.querySelector(`a[data="#${targetId}"]`);
            anchor.classList.add('active');
        }
    });
});

list.forEach(item => {
    observer.observe(item);
});

编写样式

编辑Joe主题文件夹assets/css/toc-nav.css文件

#toc {
    background: var(--background);
    padding: 15px 15px;
    top: 50px;
    position: sticky;

}

.toc-container {
    max-height: 500px;
    overflow-y: auto;
    overflow-x: hidden;
}

.nav-item a {
    text-decoration: none;
    color: var(--main);
    line-height: 30px;
}

.nav-item a:hover {
    color: var(--theme);
    text-shadow: var(--text-shadow);
    cursor: pointer;
}

.toc-container .active {
    color: var(--theme);
    text-shadow: var(--text-shadow);
}

.nav-item-h3 {
    margin-left: 10px;
}

.nav-item-h4 {
    margin-left: 20px;
}

.nav-item-h5 {
    margin-left: 30px;
}

.nav-item-h6 {
    margin-left: 40px;
}

/*,侧边栏目录导航只在文章页面生效*/
.joe_post + .joe_aside > section {
    display: none;
}
.joe_post + .joe_aside > .author {
    display: block;
}
.joe_post + .joe_aside > #toc {
    display: block !important;
}

4、应用样式和脚本

编辑Joe主题文件夹post.php文件,在<head>标签中添加以下代码

<link rel="stylesheet" href="<?php $this->options->themeUrl('assets/css/toc-nav.css'); ?>">

编辑Joe主题文件夹post.php文件,在<body>标签中尾部添加以下代码

<script src="<?php _getAssets('assets/js/toc-nav.js'); ?>"></script>
posted @ 2024-04-06 18:47  未夏  阅读(108)  评论(0编辑  收藏  举报