我在每个网页上都有一个基本的目录,并且有 CSS 在用户当前所在的部分周围添加边框。这只是一个展示其工作原理的片段:
<ol>
<li><a href="#">Home Lab Overview</a>
<ol class="toc-collapse-level">
<li><a href="#">Diagrams</a>
<ol>
<li><a href="#s1">Full Network Diagram</a></li>
<li><a href="#s2">Reverse Proxy and VPN Diagram</a></li>
</ol>
</li>
</ol>
</li>
</ol>
class=toc-collapse-level 表示要折叠的最外层列表。
我正在使用以下脚本使列表可折叠。
(t => {
const e = "faq-list",
n = "faq-clicked";
function l(l, o) {
const i = l.children;
if (0 === i.length) return;
for (let t of i)
if (t.childElementCount < 2) return;
let c = l.classList;
if (c.length > 0 && !c.contains(e)) return;
c.add(e);
const s = t.createElement("span");
let a = !1;
s.className = "faq-button", s.innerText = "⊕", s.onclick = function() {
a = !a, this.innerText = a ? "⊖" : "⊕";
for (const t of l.children) t.classList.toggle(n, a)
}, l.before(s);
for (let t = 0; t < i.length; t++) {
let e = i[t];
e.id = "faq-" + (o ? o + "-" : "") + (t + 1);
let l = e.firstElementChild;
l.insertAdjacentHTML("beforeend", ` <span class="anchor"><a href="#${e.id}">#</a></span>`), location.hash === "#" + e.id && (e.scrollIntoView(), e.classList.add(n)), l.onclick = function(t) {
e.classList.toggle(n)
}
}
}
const o = t.querySelectorAll(["div", "main", "section", "article"].map((t => t + ":not(.footnotes) > ol")).join(","));
for (let t = 0; t < o.length; t++) {
l(o[t], o.length > 1 ? t + 1 : 0)
}
})(document);
以及用于可折叠列表工作的 CSS:
.faq-button {
cursor: pointer
}
.faq-list>li>:first-child {
display: block;
cursor: pointer;
background: #fafafa;
margin: -.5em;
padding: .5em
}
.faq-list>:not(.faq-clicked)>* {
display: none
}
.faq-button {
float: right;
margin-left: 1em
}
.faq-list .anchor {
display: none
}
.faq-list>li:hover .anchor {
display: inline
}
.faq-list>li {
border: 1px solid #eee;
padding: .5em
}
问题是我不确定如何在页面加载时扩展当前部分。
要使当前部分在页面加载时展开,首先您必须确定哪个是当前部分。
我认为可以同时展开多个部分(例如,当它们在屏幕上可见时)。
因此,要查找所有可见部分,我们可以使用以下脚本:
function isElementVisible(el) {
var rect = el.getBoundingClientRect(),
vWidth = window.innerWidth || document.documentElement.clientWidth,
vHeight = window.innerHeight || document.documentElement.clientHeight,
efp = function (x, y) {
return document.elementFromPoint(x, y)
};
// Return false if it's not in the viewport
if (rect.right < 0 || rect.bottom < 0
|| rect.left > vWidth || rect.top > vHeight)
return false;
// Return true if any of its four corners are visible
return (
el.contains(efp(rect.left, rect.top))
|| el.contains(efp(rect.right, rect.top))
|| el.contains(efp(rect.right, rect.bottom))
|| el.contains(efp(rect.left, rect.bottom))
);
}
现在您可以扩展您的脚本并检查每个部分是否可见,如果可见则切换“常见问题解答”。
...
const o = t.querySelectorAll(["div", "main", "section", "article"].map((t => t + ":not(.footnotes) > ol")).join(","));
for (let t = 0; t < o.length; t++) {
l(o[t], o.length > 1 ? t + 1 : 0)
// This is the new code
if(isElementVisible(o[t])){
o[t].classList.toggle("faq-clicked");
}
}