目录悬浮
This commit is contained in:
parent
e6b0407b07
commit
10ac27a069
|
@ -77,24 +77,36 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|
||||||
// 滚动处理
|
// 滚动处理
|
||||||
const scrollFnToDo = function () {
|
const scrollFnToDo = function () {
|
||||||
let $cardTocLayout = document.getElementById("card-toc");
|
|
||||||
// let $cardToc = $cardTocLayout.getElementsByClassName("toc-content")[0];
|
|
||||||
// let $tocLink = $cardToc.querySelectorAll(".toc-link");
|
|
||||||
let $article = document.getElementById("article-container");
|
|
||||||
|
|
||||||
// let scrollPercent;
|
const isToc = GLOBAL_CONFIG.htmlType === 'post';
|
||||||
// if (GLOBAL_CONFIG.htmlType === 'post') {
|
const isAnchor = true;
|
||||||
// scrollPercent = function (currentTop) {
|
const $article = document.getElementById("article-container");
|
||||||
// const docHeight = $article.clientHeight;
|
|
||||||
// const winHeight = document.documentElement.clientHeight;
|
if (!($article && (isToc || isAnchor))) return
|
||||||
// const headerHeight = $article.offsetTop;
|
|
||||||
// const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : (document.documentElement.scrollHeight - winHeight)
|
let $tocLink, $cardToc, scrollPercent, autoScrollToc, isExpand
|
||||||
// const scrollPercent = (currentTop - headerHeight) / (contentMath);
|
|
||||||
// const scrollPercentRounded = Math.round(100 * scrollPercent);
|
if (isToc) {
|
||||||
// const percentage = 100 < scrollPercentRounded ? 100 : scrollPercentRounded <= 0 ? 0 : scrollPercentRounded;
|
|
||||||
// $cardToc.setAttribute("progress-percentage", percentage);
|
const $cardTocLayout = document.getElementById("card-toc");
|
||||||
// };
|
$cardToc = $cardTocLayout.getElementsByClassName("toc-content")[0];
|
||||||
// }
|
$tocLink = $cardToc.querySelectorAll(".toc-link");
|
||||||
|
|
||||||
|
// const $tocPercentage = $cardTocLayout.querySelector(".toc-percentage");
|
||||||
|
isExpand = $cardToc.classList.contains("is-expand");
|
||||||
|
|
||||||
|
scrollPercent = function (currentTop) {
|
||||||
|
const docHeight = $article.clientHeight;
|
||||||
|
const winHeight = document.documentElement.clientHeight;
|
||||||
|
const headerHeight = $article.offsetTop;
|
||||||
|
const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : (document.documentElement.scrollHeight - winHeight);
|
||||||
|
const scrollPercent = (currentTop - headerHeight) / (contentMath);
|
||||||
|
const scrollPercentRounded = Math.round(scrollPercent * 100);
|
||||||
|
const percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded;
|
||||||
|
// $tocPercentage.textContent = percentage
|
||||||
|
$cardToc.setAttribute("progress-percentage", percentage);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
window.mobileToc = {
|
window.mobileToc = {
|
||||||
open: () => {
|
open: () => {
|
||||||
|
@ -110,79 +122,90 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// toc 元素点击
|
// toc 元素点击
|
||||||
// $cardToc.addEventListener("click", e => {
|
$cardToc.addEventListener("click", e => {
|
||||||
// e.preventDefault();
|
e.preventDefault();
|
||||||
// const target = e.target.classList.contains("toc-link") ? e.target : e.target.parentElement;
|
const target = e.target.classList;
|
||||||
//
|
if (target.contains('toc-content')) return;
|
||||||
// btf.scrollToDest(
|
const $target = e.target.classList.contains("toc-link") ? e.target : e.target.parentElement;
|
||||||
// btf.getEleTop(
|
|
||||||
// document.getElementById(
|
|
||||||
// decodeURI(target.getAttribute("href")).replace("#", "")
|
|
||||||
// )
|
|
||||||
// ),
|
|
||||||
// 300
|
|
||||||
// );
|
|
||||||
// if (window.innerWidth < 900) {
|
|
||||||
// window.mobileToc.close();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI($target.getAttribute("href")).replace("#", ""))), 300);
|
||||||
|
if (window.innerWidth < 900) {
|
||||||
|
window.mobileToc.close()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
autoScrollToc = item => {
|
||||||
|
const activePosition = item.getBoundingClientRect().top
|
||||||
|
const sidebarScrollTop = $cardToc.scrollTop
|
||||||
|
if (activePosition > (document.documentElement.clientHeight - 100)) {
|
||||||
|
$cardToc.scrollTop = sidebarScrollTop + 150
|
||||||
|
}
|
||||||
|
if (activePosition < 100) {
|
||||||
|
$cardToc.scrollTop = sidebarScrollTop - 150
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
// find head position & add active class
|
// find head position & add active class
|
||||||
// const list = $article.querySelectorAll("h1,h2,h3,h4,h5,h6");
|
const list = $article.querySelectorAll("h1,h2,h3,h4,h5,h6");
|
||||||
// let detectItem = "";
|
let detectItem = "";
|
||||||
// const findHeadPosition = function (top) {
|
const findHeadPosition = function (top) {
|
||||||
//
|
|
||||||
// if (0 === $tocLink.length || 0 === top) {
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let currentId = "";
|
|
||||||
// let currentIndex = "";
|
|
||||||
//
|
|
||||||
// list.forEach(function (ele, index) {
|
|
||||||
// if (top > btf.getEleTop(ele) - 80) {
|
|
||||||
// currentId = "#" + encodeURI(ele.getAttribute("id"));
|
|
||||||
// currentIndex = index
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// })
|
|
||||||
// if (detectItem === currentIndex) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// detectItem = currentIndex
|
|
||||||
//
|
|
||||||
// $cardToc.querySelectorAll(".active").forEach(i => {
|
|
||||||
// i.classList.remove("active")
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// if (currentId === "") {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const currentActive = $tocLink[currentIndex]
|
|
||||||
// currentActive.classList.add("active")
|
|
||||||
//
|
|
||||||
// setTimeout(() => {
|
|
||||||
// autoScrollToc(currentActive)
|
|
||||||
// }, 0)
|
|
||||||
//
|
|
||||||
// if (isExpand) return
|
|
||||||
// let parent = currentActive.parentNode
|
|
||||||
//
|
|
||||||
// for (; !parent.matches(".toc"); parent = parent.parentNode) {
|
|
||||||
// if (parent.matches("li")) parent.classList.add("active")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// window.tocScrollFn = function () {
|
if (0 === $tocLink.length || 0 === top) {
|
||||||
// return btf.throttle(function () {
|
return false
|
||||||
// let currentTop = window.scrollY || document.documentElement.scrollTop;
|
}
|
||||||
// // scrollPercent(currentTop)
|
|
||||||
// findHeadPosition(currentTop);
|
let currentId = "";
|
||||||
// }, 100)();
|
let currentIndex = "";
|
||||||
// };
|
|
||||||
// window.addEventListener("scroll", tocScrollFn);
|
list.forEach(function (ele, index) {
|
||||||
|
if (top > btf.getEleTop(ele) - 80) {
|
||||||
|
const id = ele.id
|
||||||
|
currentId = id ? "#" + encodeURI(id) : ""
|
||||||
|
currentIndex = index
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
if (detectItem === currentIndex) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAnchor) btf.updateAnchor(currentId);
|
||||||
|
|
||||||
|
detectItem = currentIndex
|
||||||
|
|
||||||
|
if (isToc) {
|
||||||
|
$cardToc.querySelectorAll(".active").forEach(i => {
|
||||||
|
i.classList.remove("active")
|
||||||
|
});
|
||||||
|
if (currentId === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentActive = $tocLink[currentIndex];
|
||||||
|
|
||||||
|
currentActive.classList.add("active");
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
autoScrollToc(currentActive)
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (isExpand) return;
|
||||||
|
let parent = currentActive.parentNode;
|
||||||
|
|
||||||
|
for (; !parent.matches(".toc-list"); parent = parent.parentNode) {
|
||||||
|
if (parent.matches("li")) parent.classList.add("active")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.tocScrollFn = function () {
|
||||||
|
return btf.throttle(function () {
|
||||||
|
let currentTop = window.scrollY || document.documentElement.scrollTop;
|
||||||
|
scrollPercent(currentTop)
|
||||||
|
findHeadPosition(currentTop);
|
||||||
|
}, 100)();
|
||||||
|
};
|
||||||
|
window.addEventListener("scroll", tocScrollFn);
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabsFn = {
|
const tabsFn = {
|
||||||
|
|
|
@ -179,6 +179,17 @@ const btf = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return actualTop
|
return actualTop
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAnchor: (anchor) => {
|
||||||
|
if (anchor !== window.location.hash) {
|
||||||
|
if (!anchor) anchor = location.pathname
|
||||||
|
const title = "123111111111"
|
||||||
|
window.history.replaceState({
|
||||||
|
url: location.href,
|
||||||
|
title: title
|
||||||
|
}, title, anchor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
|
@ -1,13 +1,34 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<!-- 侧边栏 -->
|
||||||
<div class="aside-content" id="aside-content" th:fragment="aside(widgets)"
|
<div class="aside-content" id="aside-content" th:fragment="aside(widgets)"
|
||||||
th:if="${theme.config.sidebar.location != 'hide-aside' && not #strings.isEmpty(widgets)}">
|
th:if="${theme.config.sidebar.location != 'hide-aside' && not #strings.isEmpty(widgets)}">
|
||||||
|
|
||||||
<!-- 侧栏部件不确定都有什么 -->
|
<!-- 侧栏部件,不包含 toc 则直接遍历 -->
|
||||||
|
<th:block th:if="${not #strings.contains(widgets, 'toc')}">
|
||||||
<th:block th:each="widget : ${#strings.listSplit(widgets, ',')}">
|
<th:block th:each="widget : ${#strings.listSplit(widgets, ',')}">
|
||||||
<th:block th:replace="'modules/widgets/aside/'+ ${widget}"/>
|
<th:block th:replace="'modules/widgets/aside/'+ ${widget}"/>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<!-- 侧栏部件,toc 之后的组件需要被 sticky_layout 包裹 -->
|
||||||
|
<th:block th:if="${#strings.contains(widgets, 'toc')}">
|
||||||
|
|
||||||
|
<th:block th:each="widget : ${#strings.listSplit(#strings.substringBefore(widgets, 'toc'), ',')}">
|
||||||
|
|
||||||
|
<th:block th:replace="'modules/widgets/aside/'+ ${widget}"/>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<!-- toc 之后的组件需要被 sticky_layout 包裹 -->
|
||||||
|
<div class="sticky_layout">
|
||||||
|
<th:block th:replace="modules/widgets/aside/toc :: toc"/>
|
||||||
|
|
||||||
|
<th:block th:each="widget : ${#strings.listSplit(#strings.substringAfter(widgets, 'toc'), ',')}">
|
||||||
|
<th:block th:replace="'modules/widgets/aside/'+ ${widget}"/>
|
||||||
|
</th:block>
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -47,10 +47,9 @@
|
||||||
});
|
});
|
||||||
tocbot.init({
|
tocbot.init({
|
||||||
tocSelector: '.toc-content',
|
tocSelector: '.toc-content',
|
||||||
contentSelector: '.post-content',
|
contentSelector: content,
|
||||||
headingSelector: headerEl,
|
headingSelector: headerEl,
|
||||||
hasInnerContainers: true,
|
hasInnerContainers: true,
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue