求 js 代码,只展开当前活动页签的文档树

本贴最后更新于 304 天前,其中的信息可能已经时移俗易

求 js 代码,在使用“始终定位打开的文档”功能时,只展开当前文档的文档树,自动关闭(不展开)其它无关的文档树。例如:

有笔记本 A,内有文档 A1,子文档 A2、子子文档 A3。

有笔记本 B,内有文档 B1,子文档 B2、子子文档 B3。

已将文档 A2、B2 打开,显示在上方页签栏中。

启用“始终定位打开的文档”功能。

点击 A2 页签,左侧文档树自动展开,并定位到 A-A1-A2;A3 列表不展开

点击 B2 页签,左侧文档树自动展开,定位到 B-B1-B2;同时关闭 A-A1-A2 文档树的展开状态,恢复到笔记本 A。也就是仅保留当前活动页签对应的文档树是展开状态,其它文档树分支全部关闭,包括当前活动文档的子文档树。

  • 思源笔记

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

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

    24875 引用 • 102362 回帖
  • Q&A

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

    9445 引用 • 43009 回帖 • 108 关注
1 操作
wenbocn 在 2024-06-02 13:54:35 更新了该帖

相关帖子

被采纳的回答
  • wilsons 1

    时隔 1 个多月,你解决了吗?相见即是有缘,看到此贴感觉有些思路,就尝试写了下,实现了这个功能。由于刚接触思源,对思源 api 还不是很了解,所以选择用 js 代码片段实现,纯原生 js 实现,方法比较笨,勉强能用。

    不足之处也请论坛里的大佬们多多批评指正!

    效果如下:

    t2.gif

    完整代码如下:

    // 等待标签页容器渲染完成后开始监听 whenElementExist('.layout__center').then(async element => { // 等待笔记列表加载完毕 await sleep(40); // 监听页签切换事件 observeTabChanged(element, (tab) => { // 折叠所有笔记,然后定位当前笔记 collapseAllBooksThenFocusCurrentBook(element, tab); }); }); // 折叠所有笔记,然后定位当前笔记 async function collapseAllBooksThenFocusCurrentBook(element, tab) { // 等待激活文档加载完毕 await whenElementExist(()=>{ const content = element.querySelector('.layout-tab-container [data-id="'+tab.getAttribute("data-id")+'"]'); return content && content.getAttribute("data-loading") === "finished"; }); // 折叠所有笔记 document.querySelectorAll("ul.b3-list[data-url]").forEach(async book => { const bookName = tab.getAttribute("aria-label")?.split('/')[0]; if(bookName) { // 如果在本笔记中则不再折叠 const bookText = book.querySelector('li[data-type="navigation-root"] span.b3-list-item__text')?.innerText; if(bookText === bookName) { return; } } // 折叠笔记 const bookArrowBtn = book.querySelector('li[data-type="navigation-root"] span.b3-list-item__toggle'); if (bookArrowBtn && bookArrowBtn.firstElementChild.classList.contains("b3-list-item__arrow--open")) { bookArrowBtn.click(); } }); // 定位当前笔记 document.querySelector(".layout-tab-container .block__icons span[data-type=focus]")?.click(); } // 监听页签切换事件 function observeTabChanged(parentNode, callback) { // 创建一个回调函数来处理观察到的变化 const observerCallback = function(mutationsList, observer) { // 用常规方式遍历 mutationsList 中的每一个 mutation for (let mutation of mutationsList) { // 属性被修改 if (mutation.type === 'attributes' && mutation.attributeName === 'class') { const element = mutation.target; if (element.tagName.toLowerCase() === 'li' && element.getAttribute('data-type') === 'tab-header' && element.classList.contains('item--focus')) { if(typeof callback === 'function') callback(element); } } // 如果有新的子节点被添加 if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'li') { if (node.getAttribute('data-type') === 'tab-header' && node.classList.contains('item--focus')) { if(typeof callback === 'function') callback(node); } } }); } } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(observerCallback); // 配置观察器:传递一个对象来指定观察器的行为 const config = { attributes: true, attributeFilter: ['class'], childList: true, subtree: true }; // 开始观察目标节点 observer.observe(parentNode, config); // 返回一个函数,用于停止观察 return function stopObserving() { observer.disconnect(); }; } // 延迟执行 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 等待元素渲染完成后执行 function whenElementExist(selector) { 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 { requestAnimationFrame(checkForElement); } }; checkForElement(); }); }

    使用方法:

    设置 》外观 》代码片段 》js 中新增加代码片段,然后把上面的代码粘贴过去即可。

    image.png

优质回帖
  • wilsons 2

    @wenbocn 我已完美实现了不闪动的版本,并且改进了官方定位,在未打开目录树时,左侧 dock 区目录树显示隐藏按钮样式会获取焦点的 bug

    效果如下

    t6.gif

    完整代码如下

    由于链滴代码长度有限制,只能放到 jsrun 了。

  • player 1 赞同

    ToolbarBox

    这里有除了自动定位的其他代码。 自动定位就做个监听, 针对 class layout__wnd--active ,发现有 tab 的变化,就触发一次,locateDoc() 即可。

  • wilsons 1

    时隔 1 个多月,你解决了吗?相见即是有缘,看到此贴感觉有些思路,就尝试写了下,实现了这个功能。由于刚接触思源,对思源 api 还不是很了解,所以选择用 js 代码片段实现,纯原生 js 实现,方法比较笨,勉强能用。

    不足之处也请论坛里的大佬们多多批评指正!

    效果如下:

    t2.gif

    完整代码如下:

    // 等待标签页容器渲染完成后开始监听 whenElementExist('.layout__center').then(async element => { // 等待笔记列表加载完毕 await sleep(40); // 监听页签切换事件 observeTabChanged(element, (tab) => { // 折叠所有笔记,然后定位当前笔记 collapseAllBooksThenFocusCurrentBook(element, tab); }); }); // 折叠所有笔记,然后定位当前笔记 async function collapseAllBooksThenFocusCurrentBook(element, tab) { // 等待激活文档加载完毕 await whenElementExist(()=>{ const content = element.querySelector('.layout-tab-container [data-id="'+tab.getAttribute("data-id")+'"]'); return content && content.getAttribute("data-loading") === "finished"; }); // 折叠所有笔记 document.querySelectorAll("ul.b3-list[data-url]").forEach(async book => { const bookName = tab.getAttribute("aria-label")?.split('/')[0]; if(bookName) { // 如果在本笔记中则不再折叠 const bookText = book.querySelector('li[data-type="navigation-root"] span.b3-list-item__text')?.innerText; if(bookText === bookName) { return; } } // 折叠笔记 const bookArrowBtn = book.querySelector('li[data-type="navigation-root"] span.b3-list-item__toggle'); if (bookArrowBtn && bookArrowBtn.firstElementChild.classList.contains("b3-list-item__arrow--open")) { bookArrowBtn.click(); } }); // 定位当前笔记 document.querySelector(".layout-tab-container .block__icons span[data-type=focus]")?.click(); } // 监听页签切换事件 function observeTabChanged(parentNode, callback) { // 创建一个回调函数来处理观察到的变化 const observerCallback = function(mutationsList, observer) { // 用常规方式遍历 mutationsList 中的每一个 mutation for (let mutation of mutationsList) { // 属性被修改 if (mutation.type === 'attributes' && mutation.attributeName === 'class') { const element = mutation.target; if (element.tagName.toLowerCase() === 'li' && element.getAttribute('data-type') === 'tab-header' && element.classList.contains('item--focus')) { if(typeof callback === 'function') callback(element); } } // 如果有新的子节点被添加 if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'li') { if (node.getAttribute('data-type') === 'tab-header' && node.classList.contains('item--focus')) { if(typeof callback === 'function') callback(node); } } }); } } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(observerCallback); // 配置观察器:传递一个对象来指定观察器的行为 const config = { attributes: true, attributeFilter: ['class'], childList: true, subtree: true }; // 开始观察目标节点 observer.observe(parentNode, config); // 返回一个函数,用于停止观察 return function stopObserving() { observer.disconnect(); }; } // 延迟执行 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 等待元素渲染完成后执行 function whenElementExist(selector) { 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 { requestAnimationFrame(checkForElement); } }; checkForElement(); }); }

    使用方法:

    设置 》外观 》代码片段 》js 中新增加代码片段,然后把上面的代码粘贴过去即可。

    image.png

欢迎来到这里!

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

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

推荐标签 标签

  • OneNote
    1 引用 • 3 回帖
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • Q&A

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

    9445 引用 • 43007 回帖 • 108 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    183 引用 • 1011 回帖 • 1 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 101 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖 • 1 关注
  • abitmean

    有点意思就行了

    31 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 608 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 445 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖 • 1 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 16 关注
  • C

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

    85 引用 • 165 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 3 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 6 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 805 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 147 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    143 引用 • 442 回帖
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    226 引用 • 476 回帖 • 1 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 3 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    7 引用 • 27 回帖 • 1 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    28 引用 • 197 回帖 • 27 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖