[js] 希望尽量折叠大纲

本贴最后更新于 238 天前,其中的信息可能已经时移世改

之前在社区发布一个关于折叠大纲的代码求助(希望鼠标悬浮自动展开大纲 - 链滴),很高兴看到有热心的人进行帮助,但是最近复习的时候,发现有一点需要优化一下

大纲折叠可以方便我们快速获取文章的大致结构,方便我们去进行定位,但是当我们复习的时候,也就是鼠标点击大纲跳到对应的标题时,如果想回去大纲再进行点击,就需要再次寻找标题对应的大纲,然而此时大纲的加深效果(光标对应标题的大纲定位效果)已经消失,寻找对应的标题就需要重新一个字一个字的核对,这对复习效果造成极大的不便,望请大佬们帮我修改下代码片段

这是目前的效果

image.png

这是我理想的效果

image.png

示例代码

// see https://ld246.com/article/1727096963532 (async ()=>{ whenElementExist('.sy__outline > .fn__flex-1').then(async el => { // 监听大纲标题被添加 observeChildAddition(el, node => { return node.tagName.toLowerCase() === 'ul' && node.classList.contains('b3-list') && node.querySelector('.b3-list-item') }, uls => { // 获取大纲列表 const ul = uls[0]; // 遍历大纲第一级子元素 Array.from(ul.children).forEach(item => { // 初始时,仅打开第一级 if(item.tagName === 'LI') { const toggleBtn = item.querySelector('.b3-list-item__toggle'); const svg = toggleBtn?.querySelector('svg.b3-list-item__arrow'); if(!svg.classList.contains('b3-list-item__arrow--open')) { svg.classList.add('b3-list-item__arrow--open'); } } if(item.tagName === 'UL') { if(item.classList.contains('fn__none')) { item.remove('fn__none'); } // 初始时,隐藏第一级下面的后代元素 itemsShow(item, false); } // 监听大纲鼠标移入事件 const ul = item.tagName === 'LI' ? item.nextElementSibling : item; item.addEventListener('mouseenter', (event) => { if(!ul || ul?.tagName !== 'UL') return; // 鼠标移入显示第一级后面的后代元素 itemsShow(ul, true); }) // 监听大纲鼠标移出事件 item.addEventListener('mouseleave', (event) => { if(!ul || ul?.tagName !== 'UL') return; // 鼠标移出隐藏第一级后面的后代元素 itemsShow(ul, false); }); }); }); }); // 动态显示隐藏子标题 function itemsShow(ul, isOpen) { if(isOpen){ const svgs = ul.querySelectorAll('span.b3-list-item__toggle svg:not(.b3-list-item__arrow--open)'); svgs.forEach(item => { item.classList.add('b3-list-item__arrow--open'); }); const uls = ul.querySelectorAll('ul.fn__none'); uls.forEach(item => { item.classList.remove('fn__none'); }); } else { const svgs = ul.querySelectorAll('span.b3-list-item__toggle svg.b3-list-item__arrow--open'); svgs.forEach(item => { item.classList.remove('b3-list-item__arrow--open'); }); const uls = ul.querySelectorAll('ul:not(.fn__none)'); uls.forEach(item => { item.classList.add('fn__none'); }); } } function observeChildAddition(el, filter, handler) { // 配置观察器选项 const config = { attributes: false, childList: true, subtree: false }; // 定义回调函数 const callback = function(mutationsList, observer) { // 遍历 mutation 列表 for (let mutation of mutationsList) { if (mutation.type === 'childList') { console.log(mutation, 111); // 查找新增加的具有类名 'b3-list' 的 ul 元素 const newULs = Array.from(mutation.addedNodes).filter(node => node.nodeType === Node.ELEMENT_NODE && filter(node)); // 如果有新的 ul 元素被添加,则调用处理函数 if(newULs.length > 0) { handler(newULs); } } } }; // 创建一个新的 MutationObserver 实例 const observer = new MutationObserver(callback); // 开始观察目标节点 observer.observe(el, config); // 返回一个函数来停止观察 return () => { observer.disconnect(); }; } // 等待元素渲染完成后执行 function whenElementExist(selector, bySetTimeout = false, delay = 40) { return new Promise(resolve => { const checkForElement = () => { let element = null; if (typeof selector === 'function') { element = selector(); } else { element = document.querySelector(selector); } if (element) { resolve(element); } else { if (bySetTimeout) { setTimeout(checkForElement, delay); } else { requestAnimationFrame(checkForElement); } } }; checkForElement(); }); } })();
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    25984 引用 • 107778 回帖
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    181 引用 • 1283 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9975 引用 • 45339 回帖 • 75 关注
1 操作
CongSec 在 2024-10-23 20:16:25 置顶了该帖

相关帖子

被采纳的回答

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • CongSec

    感谢你的更新,能否做出最后的优化?能否保留原版本(标题处)在大纲处快速跳转的功能

    因为如果我们想在大纲处进行多处的快速跳转时,这个突然折叠打乱原来的大纲状态,需要重新查找并展开

    理想的效果:

    实际的效果:

    ❤️ ❤️ ❤️

    1 回复
  • 其他回帖
  • wilsons 1

    抱歉,还是没理解你的问题。之所以没理解,是因为我这边没有你说的这些问题。

    所以,我怀疑你的代码可能有冲突或受其他代码影响了,建议你在完全新空间测试试试,以排除干扰项。

    这个代码就是在原来的基础上修改的,仅仅增加了光标处的标题会在大纲处定位而已,对原有逻辑没有影响。

    如果确定新空间仍有问题,可以尝试注释 openCursorHeading() 函数调用试试。

    光标处的标题在大纲处定位的函数就是 openCursorHeading(),一共有 3 处调用,你可以分别尝试注释这些调用试试,看看哪种是你想要的效果,3 处都注释就是原来的代码。

    这三处调用的作用分别是:

    第一处,在文档被打开时,默认使用上次的光标定位,注释掉则打开时不会定位光标位置。

    第二处,在鼠标离开大纲时,使用当前文档的光标定位,注释掉则鼠标离开大纲后定位消失。

    第三处,当光标移动时,使用当前光标定位,注释掉则光标移动不会定位标题在大纲中的位置(如果注释掉这个的话,就失去本改进版的意义了)。

    总之,你觉得效果不满意可以尝试注释这些调用看看是否你想要的效果,前提是确保代码没受到其他因素的影响。再次强调,本次修改仅仅增加了光标处的标题在大纲处定位而已,原有逻辑和功能并未有改变。

    1 回复
  • CongSec

    感谢大佬的代码片段,非常好用 ❤️ ❤️ ❤️

  • CongSec

    没有人做这个吗?这个对喜欢用大纲的人来说很友善

  • 查看全部回帖
CongSec
新手可以看我发的求助帖以及汇总帖子,很有帮助的!_! 网安笔记分享:http://congsec.xyz 广州

推荐标签 标签

  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    1 引用 • 28 回帖 • 2 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 79 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    435 引用 • 1238 回帖 • 589 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 1 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    86 引用 • 165 回帖 • 1 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 159 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖 • 1 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖 • 5 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 2 关注
  • V2Ray
    1 引用 • 15 回帖 • 2 关注
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    954 引用 • 944 回帖 • 1 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 675 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 1 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 627 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 830 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 643 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 73 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 4 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 672 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    554 引用 • 675 回帖
  • 笔记

    好记性不如烂笔头。

    310 引用 • 794 回帖 • 1 关注
  • RemNote
    2 引用 • 16 回帖 • 20 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 707 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 519 关注