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

操作&效果

  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);
    }
});

})()

  • 思源笔记

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

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

    22410 引用 • 89717 回帖
  • 代码片段

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

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

    72 引用 • 376 回帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
EmberSky
如果感觉我的回答对你有帮助, 请点击 感谢 支持一下, 谢谢! 杭州