toc js 整理

This commit is contained in:
liuzhihang 2022-10-27 09:23:43 +08:00
parent f7bd196c56
commit fac6dc30f3
1 changed files with 103 additions and 48 deletions

View File

@ -23,56 +23,111 @@ document.addEventListener("DOMContentLoaded", function () {
}
}
function S() {
var t = document.getElementById("card-toc"), r = t.getElementsByClassName("toc-content")[0],
s = r.querySelectorAll(".toc-link"), c = document.getElementById("article-container");
function scrollFnToDo() {
const $cardTocLayout = document.getElementById("card-toc");
const $cardToc = $cardTocLayout.getElementsByClassName("toc-content")[0];
const $tocLink = $cardToc.querySelectorAll(".toc-link");
const $article = document.getElementById("article-container");
window.tocScrollFn = function () {
return btf.throttle(function () {
var t = window.scrollY || document.documentElement.scrollTop;
e(t), i(t)
}, 100)()
};
window.addEventListener("scroll", tocScrollFn);
var e = function (t) {
var e = c.clientHeight, n = document.documentElement.clientHeight,
o = (t - c.offsetTop) / (n < e ? e - n : document.documentElement.scrollHeight - n),
i = Math.round(100 * o), a = 100 < i ? 100 : i <= 0 ? 0 : i;
r.setAttribute("progress-percentage", a)
}, o = function () {
t.style.animation = "toc-close .2s", setTimeout(function () {
t.style.cssText = "opacity:''; animation: ''; right: ''"
}, 100)
};
document.getElementById("mobile-toc-button").addEventListener("click", function () {
("0" === window.getComputedStyle(t).getPropertyValue("opacity") ? n : o)()
});
r.addEventListener("click", function (t) {
t.preventDefault();
var e = t.target.classList.contains("toc-link") ? t.target : t.target.parentElement;
btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI(e.getAttribute("href")).replace("#", ""))), 300), window.innerWidth < 900 && o()
});
var d = c.querySelectorAll("h1,h2,h3,h4,h5,h6"), u = "", i = function (n) {
if (0 === s.length || 0 === n) return !1;
var t, e, o = "", i = "";
if (d.forEach(function (t, e) {
n > btf.getEleTop(t) - 80 && (o = "#" + encodeURI(t.getAttribute("id")), i = e)
}), u !== i) {
if (l && (t = o, window.history.replaceState && t !== window.location.hash && (t = t || location.pathname, e = GLOBAL_CONFIG_SITE.title, window.history.replaceState({
url: location.href, title: e
}, e, t))), "" === o) return r.querySelectorAll(".active").forEach(function (t) {
t.classList.remove("active")
}), void (u = i);
u = i, r.querySelectorAll(".active").forEach(function (t) {
t.classList.remove("active")
});
var a = s[i];
a.classList.add("active"), setTimeout(function () {
var t, e;
t = a.getBoundingClientRect().top, e = r.scrollTop, t > document.documentElement.clientHeight - 100 && (r.scrollTop = e + 150), t < 100 && (r.scrollTop = e - 150)
}, 0);
for (var c = a.parentNode; !c.matches(".toc"); c = c.parentNode) c.matches("li") && c.classList.add("active")
}
const currentTop = window.scrollY || document.documentElement.scrollTop;
scrollPercent(currentTop)
findHeadPosition(currentTop);
}, 100)();
}
window.addEventListener("scroll", tocScrollFn);
function scrollPercent(currentTop) {
const docHeight = $article.clientHeight;
const winHeight = document.documentElement.clientHeight;
const headerHeight = $article.offsetTop;
const scrollPercent = (currentTop - headerHeight) /
(winHeight < docHeight ? docHeight - winHeight : document.documentElement.scrollHeight - winHeight);
const scrollPercentRounded = Math.round(100 * scrollPercent);
const percentage = 100 < scrollPercentRounded ? 100 : scrollPercentRounded <= 0 ? 0 : scrollPercentRounded;
$cardToc.setAttribute("progress-percentage", percentage);
}
var l = GLOBAL_CONFIG.isanchor
function close() {
$cardTocLayout.style.animation = "toc-close .2s";
setTimeout(function () {
$cardTocLayout.style.cssText = "opacity:''; animation: ''; right: ''";
}, 100);
}
function open() {
$cardTocLayout.style.cssText = "animation: toc-open .3s; opacity: 1; right: 45px";
}
//
document.getElementById("mobile-toc-button")
.addEventListener("click", function () {
("0" === window.getComputedStyle($cardTocLayout).getPropertyValue("opacity")
? open()
: close())();
});
// toc 元素点击
$cardToc.addEventListener("click", e => {
e.preventDefault();
const $target = e.target.classList.contains("toc-link") ? e.target : e.target.parentElement;
btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI($target.getAttribute("href")).replace("#", ""))), 300);
window.innerWidth < 900 && close();
});
// find head position & add active class
const list = $article.querySelectorAll("h1,h2,h3,h4,h5,h6");
let detectItem = "";
const findHeadPosition = function (top) {
if (0 === $tocLink.length || 0 === top) return !1;
var t,
e,
o = "",
i = "";
if ((list.forEach(function (ele, index) {
top > btf.getEleTop(ele) - 80 &&
((o = "#" + encodeURI(ele.getAttribute("id"))), (i = index));
}), detectItem !== i)
) {
if (
(l &&
((t = o),
window.history.replaceState &&
t !== window.location.hash &&
((t = t || location.pathname),
(e = GLOBAL_CONFIG_SITE.title),
window.history.replaceState(
{url: location.href, title: e},
e,
t
))),
"" === o)
)
return (
$cardToc.querySelectorAll(".active").forEach(function (t) {
t.classList.remove("active");
}),
void (detectItem = i)
);
(detectItem = i),
$cardToc.querySelectorAll(".active").forEach(function (t) {
t.classList.remove("active");
});
var a = $tocLink[i];
a.classList.add("active"),
setTimeout(function () {
var t, e;
(t = a.getBoundingClientRect().top),
(e = $cardToc.scrollTop),
t > document.documentElement.clientHeight - 100 &&
($cardToc.scrollTop = e + 150),
t < 100 && ($cardToc.scrollTop = e - 150);
}, 0);
for (var c = a.parentNode; !c.matches(".toc"); c = c.parentNode)
c.matches("li") && c.classList.add("active");
}
};
}
var d = !1, n = function () {
@ -111,7 +166,7 @@ document.addEventListener("DOMContentLoaded", function () {
f.style.overflow = "", f.style.paddingRight = "", btf.fadeOut(u, .5), d.classList.remove("open")
}
adjustMenu(), document.getElementById("nav").classList.add("show"), GLOBAL_CONFIG_SITE.isPost ? (GLOBAL_CONFIG_SITE.isToc && S(), void 0 !== GLOBAL_CONFIG.noticeOutdate && (r = GLOBAL_CONFIG.noticeOutdate, (s = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)) >= r.limitDay && ((a = document.createElement("div")).className = "post-outdate-notice", a.textContent = r.messagePrev + " " + s + " " + r.messageNext, c = document.getElementById("article-container"), "top" === r.position ? c.insertBefore(a, c.firstChild) : c.appendChild(a))), GLOBAL_CONFIG.relativeDate.post && I(document.querySelectorAll("#post-meta time"))) : (GLOBAL_CONFIG.relativeDate.homepage && I(document.querySelectorAll("#recent-posts time")), !GLOBAL_CONFIG.runtime || (i = document.getElementById("runtimeshow")) && (o = i.getAttribute("data-publishDate"), i.innerText = btf.diffDate(o) + " " + GLOBAL_CONFIG.runtime), (n = document.getElementById("last-push-date")) && (e = n.getAttribute("data-lastPushDate"), n.innerText = btf.diffDate(e, !0)), (t = document.querySelectorAll("#aside-cat-list .card-category-list-item.parent i")).length && t.forEach(function (t) {
adjustMenu(), document.getElementById("nav").classList.add("show"), GLOBAL_CONFIG_SITE.isPost ? (GLOBAL_CONFIG_SITE.isToc && scrollFnToDo(), void 0 !== GLOBAL_CONFIG.noticeOutdate && (r = GLOBAL_CONFIG.noticeOutdate, (s = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)) >= r.limitDay && ((a = document.createElement("div")).className = "post-outdate-notice", a.textContent = r.messagePrev + " " + s + " " + r.messageNext, c = document.getElementById("article-container"), "top" === r.position ? c.insertBefore(a, c.firstChild) : c.appendChild(a))), GLOBAL_CONFIG.relativeDate.post && I(document.querySelectorAll("#post-meta time"))) : (GLOBAL_CONFIG.relativeDate.homepage && I(document.querySelectorAll("#recent-posts time")), !GLOBAL_CONFIG.runtime || (i = document.getElementById("runtimeshow")) && (o = i.getAttribute("data-publishDate"), i.innerText = btf.diffDate(o) + " " + GLOBAL_CONFIG.runtime), (n = document.getElementById("last-push-date")) && (e = n.getAttribute("data-lastPushDate"), n.innerText = btf.diffDate(e, !0)), (t = document.querySelectorAll("#aside-cat-list .card-category-list-item.parent i")).length && t.forEach(function (t) {
t.addEventListener("click", function (t) {
t.preventDefault();
this.classList.toggle("expand");