展开目录中的当前列表

问题描述 投票:0回答:1

我在每个网页上都有一个基本的目录,并且有 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
}

问题是我不确定如何在页面加载时扩展当前部分。

javascript html css dom html-lists
1个回答
0
投票

要使当前部分在页面加载时展开,首先您必须确定哪个是当前部分。

我认为可以同时展开多个部分(例如,当它们在屏幕上可见时)。

因此,要查找所有可见部分,我们可以使用以下脚本:

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))
    );
}

来源:如何判断 DOM 元素在当前视口中是否可见?

现在您可以扩展您的脚本并检查每个部分是否可见,如果可见则切换“常见问题解答”。

...
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");
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.