[js] 快捷键实现在文档树上遍历

本贴最后更新于 237 天前,其中的信息可能已经天翻地覆

操作&效果

  1. 使用 alt+shift+上/下键 遍历文档树
    上: 打开 当前文档的上一个文档(当前文档树的上一个)
    下: 打开 当前文档的下一个文档(当前文档树的下一个)
  2. 使用 alt+shift+左/右键 展开折叠文档树
    左: 如果当前文档展开, 就折叠; 如果是折叠, 就跳转到父文档
    右: 如果当前文档折叠, 就展开; 如果是展开, 就跳转到第一个子文档

备注

  1. 生效前提: 左侧文档有被选中, 像这样 image.png
  2. 需要将这项配置打开: 始终定位打开的文档
  3. 与插件 文档层级导航 自带的快捷键冲突, 请自行解决

js 代码

(() => { function set_file_open(now_ele, next_ele) { if (!next_ele) return if (next_ele.getAttribute('data-type') == 'navigation-root') { // 笔记本 now_ele.classList.remove("b3-list-item--focus"); next_ele.classList.add("b3-list-item--focus"); } else { // 普通文档 next_ele.click() } // console.log(next_ele) } function handle_file_navigation(now_ele, type) { if (!now_ele) return if (type == 'ArrowUp' || type == 'ArrowDown') { // 上 let ele_list = Array.from(document.querySelectorAll('div.sy__file li')) let idx = ele_list.indexOf(now_ele) if (idx == -1) return if (type == 'ArrowUp' && idx != 0) idx-- else if (type == 'ArrowDown' && idx != ele_list.length - 1) idx++ else return let next_ele = ele_list[idx] set_file_open(now_ele, next_ele) } else if (type == 'ArrowLeft') { let next_ele = now_ele.querySelector('.b3-list-item__arrow--open') if (next_ele) { // 有下层展开按钮: 折叠 next_ele.parentElement.click() } else { // 其他情况, 跳转到上层 next_ele = now_ele.parentElement.previousElementSibling if (next_ele?.tagName.toLowerCase() == 'li') { set_file_open(now_ele, next_ele) } } } else if (type == 'ArrowRight') { let next_ele = now_ele.querySelector('span.b3-list-item__toggle:not(.fn__hidden)') if (next_ele) { // 有下层展开按钮: 展开 if (next_ele.querySelector('.b3-list-item__arrow--open')) { now_ele.nextElementSibling.firstChild.click() } else { next_ele.click() } } } } setTimeout(() => document.querySelector('[data-type="focus"]')?.click(), 1000); // 事件监听 document.addEventListener('keydown', async (event) => { // 上/下, 遍历列表 // 左: 没有下层: 跳转到上层 // 有下层&下层展开: 折叠 // 有下层&下层折叠: 跳转到上层 // 右: 没有下层: 不处理 // 有下层&下层展开: 跳转到第一个子节点 // 有下层&下层折叠: 展开 if (event.altKey && event.shiftKey && (event.key == 'ArrowUp' || event.key == 'ArrowDown' || event.key == 'ArrowLeft' || event.key == 'ArrowRight')) { let now_ele = document.querySelector('div.sy__file li.b3-list-item--focus') // console.log(now_ele) // console.log(event.key) handle_file_navigation(now_ele, event.key); } }); })()
  • 思源笔记

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

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

    26421 引用 • 109899 回帖
  • 代码片段

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

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

    206 引用 • 1492 回帖 • 1 关注

相关帖子

欢迎来到这里!

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

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

    由于 siyuan 屏蔽了 alt+shift+左右键 的快捷键, 现在改为 alt+ctrl+上下左右键

    (() => { function set_file_open(now_ele, next_ele) { if (!next_ele) return if (next_ele.getAttribute('data-type') == 'navigation-root') { // 笔记本 now_ele.classList.remove("b3-list-item--focus"); next_ele.classList.add("b3-list-item--focus"); } else { // 普通文档 next_ele.click() } // console.log(next_ele) } function handle_file_navigation(now_ele, type) { if (!now_ele) return if (type == 'ArrowUp' || type == 'ArrowDown') { // 上 let ele_list = Array.from(document.querySelectorAll('div.sy__file li')) let idx = ele_list.indexOf(now_ele) if (idx == -1) return if (type == 'ArrowUp' && idx != 0) idx-- else if (type == 'ArrowDown' && idx != ele_list.length - 1) idx++ else return let next_ele = ele_list[idx] set_file_open(now_ele, next_ele) } else if (type == 'ArrowLeft') { let next_ele = now_ele.querySelector('.b3-list-item__arrow--open') if (next_ele) { // 有下层展开按钮: 折叠 next_ele.parentElement.click() } else { // 其他情况, 跳转到上层 next_ele = now_ele.parentElement.previousElementSibling if (next_ele?.tagName.toLowerCase() == 'li') { set_file_open(now_ele, next_ele) } } } else if (type == 'ArrowRight') { let next_ele = now_ele.querySelector('span.b3-list-item__toggle:not(.fn__hidden)') if (next_ele) { // 有下层展开按钮: 展开 if (next_ele.querySelector('.b3-list-item__arrow--open')) { now_ele.nextElementSibling.firstChild.click() } else { next_ele.click() } } } } setTimeout(() => document.querySelector('[data-type="focus"]')?.click(), 1000); // 事件监听 document.addEventListener('keydown', async (event) => { // 上/下, 遍历列表 // 左: 没有下层: 跳转到上层 // 有下层&下层展开: 折叠 // 有下层&下层折叠: 跳转到上层 // 右: 没有下层: 不处理 // 有下层&下层展开: 跳转到第一个子节点 // 有下层&下层折叠: 展开 if (event.altKey && event.ctrlKey && (event.key == 'ArrowUp' || event.key == 'ArrowDown' || event.key == 'ArrowLeft' || event.key == 'ArrowRight')) { let now_ele = document.querySelector('div.sy__file li.b3-list-item--focus') // console.log(now_ele) // console.log(event.key) handle_file_navigation(now_ele, event.key); } }); })()
    1 回复
  • 这个问题不是只会出现在编辑器里吗?会影响到文档树?

    他把快捷键屏蔽了呀, addEventListener 监听不到这个快捷键, 不会触发回调
    HugZephyr
    @EmberSky 我这里实测只有在段落开头才监听不到,其他地方都是可以的
    JeffreyChen 1