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

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

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

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

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

    22801 引用 • 91537 回帖 • 3 关注
  • 代码片段

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

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

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

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
JeffreyChen
思源是支持 Markdown 语法输入的块编辑器,不是 Markdown 文件编辑器; 思源笔记同步教程:ld246.com/article/1692089679062

推荐标签 标签

  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • Sandbox

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

    408 引用 • 1246 回帖 • 586 关注
  • JetBrains

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

    18 引用 • 54 回帖 • 2 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 5 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 772 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 513 关注
  • iOS

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

    85 引用 • 139 回帖 • 1 关注
  • Dubbo

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

    60 引用 • 82 回帖 • 604 关注
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 1 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 1 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 6 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖 • 1 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖 • 1 关注
  • Google

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

    49 引用 • 192 回帖 • 3 关注
  • Kotlin

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

    19 引用 • 33 回帖 • 63 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 159 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖
  • Unity

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

    25 引用 • 7 回帖 • 160 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    135 引用 • 190 回帖 • 2 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 400 关注
  • 996
    13 引用 • 200 回帖 • 9 关注
  • flomo

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

    5 引用 • 107 回帖 • 4 关注
  • Git

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

    209 引用 • 358 回帖
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    230 引用 • 1454 回帖 • 2 关注
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 588 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    78 引用 • 391 回帖