[js] 右键文档树定位按钮时先折叠再定位

本贴最后更新于 206 天前,其中的信息可能已经物是人非

效果是右键文档树上的定位按钮时,先折叠其他打开的笔记本,再定位到当前文档

image.png

JS 代码片段:

设置开头的变量为 true 时是“左键定位, 右键折叠定位”,为 false 时互换为“左键折叠定位, 右键定位”

// 右键文档树定位按钮时先折叠再定位 JS片段 // author by JeffreyChen https://ld246.com/article/1727980528164 (function() { // 设置为 true 时是“左键定位, 右键折叠定位”,为 false 时互换为“左键折叠定位, 右键定位” const originalBehavior = true; function addFocusHandler() { const MAX_RETRIES = 100; // 最大重试次数 const RETRY_INTERVAL = 200; // 重试间隔(毫秒) let retryCount = 0; const FOCUS_BUTTON_SELECTOR = '.layout-tab-container > .file-tree .block__icon[data-type="focus"]'; const FILE_TREE_SELECTOR = ".layout-tab-container > .file-tree > .fn__flex-1 > ul.b3-list[data-url]"; function collapseLists() { const fileTreeLists = document.querySelectorAll(FILE_TREE_SELECTOR); fileTreeLists.forEach(list => { const fragment = new DocumentFragment(); Array.from(list.children).forEach(item => { if (item.matches('li.b3-list-item')) { const toggleElement = item.querySelector('.b3-list-item__toggle'); const arrowElement = item.querySelector('.b3-list-item__arrow'); if (toggleElement && arrowElement.classList.contains('b3-list-item__arrow--open')) { arrowElement.classList.remove('b3-list-item__arrow--open'); const nextSibling = item.nextElementSibling; if (nextSibling && nextSibling.matches('ul')) { fragment.appendChild(nextSibling); } } } }); // 批量清空节点 requestAnimationFrame(() => fragment.replaceChildren()); }); } function tryModifyAriaLabelAndAddHandler() { const focusButton = document.querySelector(FOCUS_BUTTON_SELECTOR); if (focusButton) { if (originalBehavior) { // 原始逻辑 focusButton.setAttribute('aria-label', '左键定位, 右键折叠定位'); focusButton.addEventListener('contextmenu', function(e) { e.preventDefault(); // 阻止默认右键行为 collapseLists(); focusButton.click(); // 模拟点击当前按钮 }); } else { // 左右互换逻辑 focusButton.setAttribute('aria-label', '左键折叠定位, 右键定位'); function leftClickHandler(e) { e.preventDefault(); // 阻止左键点击的默认行为 collapseLists(); focusButton.click(); // 模拟点击当前按钮 } function contextMenuHandler(e) { e.preventDefault(); // 阻止右键点击的默认行为 focusButton.removeEventListener('click', leftClickHandler); focusButton.click(); // 模拟点击当前按钮 setTimeout(() => { focusButton.addEventListener('click', leftClickHandler); }, 0); } // 为左键和右键添加相应的监听器 focusButton.addEventListener('click', leftClickHandler); focusButton.addEventListener('contextmenu', contextMenuHandler); } } else { retryCount++; if (retryCount < MAX_RETRIES) { setTimeout(tryModifyAriaLabelAndAddHandler, RETRY_INTERVAL); // 继续重试 } else { console.error('代码片段报错:无法找到文档树上的定位按钮'); } } } // 初次调用 tryModifyAriaLabelAndAddHandler(); } // 添加处理程序 addFocusHandler(); })();

目前已知的问题是:

  1. 如果当前文档所在的笔记本是展开的,使用时会有一点不必要的抖动。开发需求已经反馈到:Issue #12695 · siyuan-note/siyuan
  2. 有时候不能定位到预期中的文档,这个是思源的问题,已经反馈到:Issue #12694 · siyuan-note/siyuan
打赏 30 积分后可见
30 积分 • 7 打赏
  • 思源笔记

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

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

    25278 引用 • 104296 回帖
  • 代码片段

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

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

    153 引用 • 1000 回帖
2 操作
JeffreyChen 在 2024-10-06 14:33:50 更新了该帖
JeffreyChen 在 2024-10-04 02:38:04 更新了该帖

相关帖子

欢迎来到这里!

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

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

    这个我是真喜欢

  • wenbocn via Android

    👍🏻 非常棒的功能。

    请问能否左右键功能互换一下?

    请问能否提供一个 css 使定位折叠按钮不隐藏,一直显示,谢谢!

    1 回复
  • JeffreyChen 1 1 赞同
    1. 帖子更新了代码片段,在代码开头增加了一个变量切换
    2. 始终显示文档树上的按钮可以用下面这个 CSS:
      #layouts .layout-tab-container > .file-tree .block__icon { opacity: 1; }
  • wenbocn

    求助!

    大佬能否给一个定位文档后,点击展开该定位文档的功能。

    目的:

    使用了“二级文档树”插件,参考[css] 关于二级文档树的某些定制设计 - 链滴 (ld246.com),添加 css 自定义实现了左侧原文档树显示文件夹,右侧二级文档树显示文件的功能。使用原文档树的定位按钮时,只能在左侧原文档树定位,而不能使二级文档树定位。

    思路:使用原文档树的定位按钮时,在左侧原文档树定位到文档,然后点击将其展开,那么左侧(原文档树)显示该文档下的所有文件夹,同时右侧(二级文档树)显示该文档下的所有文件。

    1 回复
  • wenbocn

    @JeffreyChen 大佬能否帮忙想一下方案,非常感谢!

  • 改好了,不过左键点击的时候不行,我没研究出来为什么:

    // 右键文档树定位按钮时先折叠再定位 JS片段 // author by JeffreyChen https://ld246.com/article/1727980528164 (function() { // 设置为 true 时是“左键定位, 右键折叠定位”,为 false 时互换为“左键折叠定位, 右键定位” const originalBehavior = true; function addFocusHandler() { const MAX_RETRIES = 100; // 最大重试次数 const RETRY_INTERVAL = 200; // 重试间隔(毫秒) let retryCount = 0; const FOCUS_BUTTON_SELECTOR = '.layout-tab-container > .file-tree .block__icon[data-type="focus"]'; const FILE_TREE_SELECTOR = ".layout-tab-container > .file-tree > .fn__flex-1 > ul.b3-list[data-url]"; function collapseLists() { const fileTreeLists = document.querySelectorAll(FILE_TREE_SELECTOR); fileTreeLists.forEach(list => { const fragment = new DocumentFragment(); Array.from(list.children).forEach(item => { if (item.matches('li.b3-list-item')) { const toggleElement = item.querySelector('.b3-list-item__toggle'); const arrowElement = item.querySelector('.b3-list-item__arrow'); if (toggleElement && arrowElement.classList.contains('b3-list-item__arrow--open')) { arrowElement.classList.remove('b3-list-item__arrow--open'); const nextSibling = item.nextElementSibling; if (nextSibling && nextSibling.matches('ul')) { fragment.appendChild(nextSibling); } } } }); // 批量清空节点 requestAnimationFrame(() => fragment.replaceChildren()); }); } function simulateClickOnFocusedText() { const focusedTextElement = document.querySelector('.layout-tab-container > .file-tree > .fn__flex-1 .b3-list-item--focus > .b3-list-item__text'); if (focusedTextElement) { focusedTextElement.click(); // 模拟点击找到的第一个元素 } else { console.error('找不到聚焦文本元素'); } } function tryModifyAriaLabelAndAddHandler() { const focusButton = document.querySelector(FOCUS_BUTTON_SELECTOR); if (focusButton) { // 在点击按钮后 500ms 模拟点击目标元素 const handleButtonClick = () => { setTimeout(simulateClickOnFocusedText, 500); // 延时调用 }; if (originalBehavior) { // 原始逻辑 focusButton.setAttribute('aria-label', '左键定位, 右键折叠定位'); focusButton.addEventListener('contextmenu', function(e) { e.preventDefault(); // 阻止默认右键行为 collapseLists(); focusButton.click(); // 模拟点击当前按钮 handleButtonClick(); // 添加延时点击操作 }); } else { // 左右互换逻辑 focusButton.setAttribute('aria-label', '左键折叠定位, 右键定位'); function leftClickHandler(e) { e.preventDefault(); // 阻止左键点击的默认行为 collapseLists(); focusButton.click(); // 模拟点击当前按钮 handleButtonClick(); // 添加延时点击操作 } function contextMenuHandler(e) { e.preventDefault(); // 阻止右键点击的默认行为 focusButton.removeEventListener('click', leftClickHandler); focusButton.click(); // 模拟点击当前按钮 setTimeout(() => { focusButton.addEventListener('click', leftClickHandler); }, 0); handleButtonClick(); // 添加延时点击操作 } // 为左键和右键添加相应的监听器 focusButton.addEventListener('click', leftClickHandler); focusButton.addEventListener('contextmenu', contextMenuHandler); } } else { retryCount++; if (retryCount < MAX_RETRIES) { setTimeout(tryModifyAriaLabelAndAddHandler, RETRY_INTERVAL); // 继续重试 } else { console.error('代码片段报错:无法找到文档树上的定位按钮'); } } } // 初次调用 tryModifyAriaLabelAndAddHandler(); } // 添加处理程序 addFocusHandler(); })();
    1 回复
  • wenbocn via Android

    大佬给力,感谢!

    等试一下再给您反馈

  • wenbocn 1 评论

    非常感谢大佬,我这边左右键都是有效的。

    定位到文件夹(含有子文档)条目时,很好用。点击定位按钮后,左边定位到文件夹,右边显示该文件下的文档。

    但定位到文档(不含子文档)时,左侧原文档树和右侧 docker 文档树都没有响应。请问能否再麻烦大佬,在这种情况下,将左侧原文档树定位到这个文档所在的文件夹,如果可能的话,能否再触发一下二级文档树的定位按钮或用其他方法定位一下。

    谢谢!!!

    这个有点麻烦,我不太想写
    JeffreyChen
  • xnyshu via macOS

    这个如果文档树太长,还是目标文档还是会落到文档树栏下边去,能不能自动跳到文档树栏的中间?

    1 回复
  • 你这个症状是不是用了文档树自定义插件?

    1 回复
  • xnyshu 2 评论 via macOS

    是的。

    @JeffreyChen 抱歉,这个真的不会写
    zxkmm
请输入回帖内容 ...
JeffreyChen
思源是支持 Markdown 语法输入的块编辑器,不是 Markdown 文件编辑器; 思源笔记同步教程:https://ld246.com/article/1692089679062 爱发电:https://afdian.com/a/JeffreyChen

推荐标签 标签

  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 633 关注
  • V2Ray
    1 引用 • 15 回帖 • 1 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    93 引用 • 113 回帖
  • 正则表达式

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

    31 引用 • 94 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    63 引用 • 289 回帖 • 1 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 645 关注
  • GAE

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

    14 引用 • 42 回帖 • 813 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 1 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖
  • 区块链

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

    92 引用 • 752 回帖 • 1 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 760 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 56 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 486 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 7 关注
  • Sandbox

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

    431 引用 • 1250 回帖 • 597 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    89 引用 • 150 回帖
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 1 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖 • 2 关注
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖 • 4 关注
  • gRpc
    11 引用 • 9 回帖 • 93 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 574 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    411 引用 • 3588 回帖
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    335 引用 • 324 回帖 • 3 关注
  • H2

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

    11 引用 • 54 回帖 • 666 关注
  • Hprose

    Hprose 是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。

    9 引用 • 17 回帖 • 632 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注