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

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

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

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 积分 • 9 打赏
  • 思源笔记

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

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

    25748 引用 • 106543 回帖
  • 代码片段

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

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

    174 引用 • 1208 回帖 • 1 关注
2 操作
JeffreyChen 在 2024-10-06 14:33:50 更新了该帖
JeffreyChen 在 2024-10-04 02:38:04 更新了该帖

相关帖子

欢迎来到这里!

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

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

    求助!

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

    目的:

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

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

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

    // 右键文档树定位按钮时先折叠再定位 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 回复
  • xnyshu 2 评论 via macOS

    是的。

    @JeffreyChen 抱歉,这个真的不会写
    zxkmm
  • 你这个症状是不是用了文档树自定义插件?

    1 回复
  • 查看全部回帖
JeffreyChen
思源是支持 Markdown 语法输入的块编辑器,不是 Markdown 文件编辑器; 思源笔记同步教程:https://ld246.com/article/1692089679062 爱发电:https://afdian.com/a/JeffreyChen

推荐标签 标签

  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 122 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 394 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 675 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖
  • Lute

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

    29 引用 • 202 回帖 • 27 关注
  • 996
    13 引用 • 200 回帖 • 3 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 543 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    240 引用 • 224 回帖 • 1 关注
  • OneDrive
    2 引用 • 2 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 652 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    59 引用 • 25 回帖 • 2 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 400 关注
  • Hprose

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

    9 引用 • 17 回帖 • 641 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    90 引用 • 122 回帖 • 623 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    98 引用 • 903 回帖
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    118 引用 • 54 回帖
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    178 引用 • 3866 回帖 • 1 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 556 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖 • 3 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 78 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 233 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 176 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 1 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 47 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖