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

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

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

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

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

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

    26237 引用 • 109036 回帖
  • 代码片段

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

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

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

相关帖子

欢迎来到这里!

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

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

    大佬给力,感谢!

    等试一下再给您反馈

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

    // 右键文档树定位按钮时先折叠再定位 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 回复
  • shiyuankill

    这个我是真喜欢

  • JeffreyChen 1 1 赞同
    1. 帖子更新了代码片段,在代码开头增加了一个变量切换
    2. 始终显示文档树上的按钮可以用下面这个 CSS:
      #layouts .layout-tab-container > .file-tree .block__icon {
          opacity: 1;
      }
      
  • 查看全部回帖
JeffreyChen
思源笔记同步教程:https://ld246.com/article/1692089679062 爱发电:https://afdian.com/a/JeffreyChen

推荐标签 标签

  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 564 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    188 引用 • 319 回帖 • 239 关注
  • PostgreSQL

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

    22 引用 • 22 回帖 • 1 关注
  • 叶归
    12 引用 • 56 回帖 • 23 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖 • 9 关注
  • 倾城之链
    23 引用 • 66 回帖 • 166 关注
  • 百度

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

    63 引用 • 785 回帖 • 70 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 2 关注
  • 博客

    记录并分享人生的经历。

    273 引用 • 2389 回帖
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 734 关注
  • Unity

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

    25 引用 • 7 回帖 • 120 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 1 关注
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 68 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 522 关注
  • danl
    178 关注
  • Dubbo

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

    60 引用 • 82 回帖 • 616 关注
  • Follow
    4 引用 • 12 回帖 • 1 关注
  • SOHO

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

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

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

    5 引用 • 74 回帖 • 519 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖 • 3 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    61 引用 • 29 回帖 • 10 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 393 关注
  • Word
    13 引用 • 41 回帖 • 2 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 312 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    16 引用 • 236 回帖 • 244 关注