[js] 批量折叠和展开标题,标题批量转换不再是梦

缘起:

看到有些小伙伴们希望有标题批量折叠或展开功能(比如 思源能否添加折叠或展开指定层级标题下内容的功能?怎样快速调整大纲级别? ),这个功能有时候确实挺有用的,比如批量转换等。

今天试着研究了下,于是整了一个 js 代码片段。

该代码主要有以下几个功能:

  1. alt + 点击标题前的箭头按钮,折叠/展开所有同级标题
  2. ctrl/meta + alt + 点击标题前的箭头按钮,折叠/展开所有标题
  3. 选择情况下,仅折叠/展开已选择的部分的标题

效果如下:

r98.gif

代码

https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E5%BF%AB%E9%80%9F%E6%8A%98%E5%8F%A0%E5%92%8C%E5%B1%95%E5%BC%80%E6%A0%87%E9%A2%98.js

思源的坑:

这里顺便吐槽下思源获取当前文档的坑,,看到很多小伙伴们使用下面的方法获取的

document.querySelector('[data-type="wnd"].layout__wnd--active .protyle:not(.fn__none)')

这样获取乍一看没问题,也能满足绝大多数场景,包括分屏。

但这种方法不适合思源刚刚启动或刚刚刷新后的情况,因为刚刚重启或刷新后的页面中并不存在 layout__wnd--active 这个类,导致这种方法失效。

那如果换成这样呢?

document.querySelector('[data-type="wnd"].layout__wnd--active .protyle:not(.fn__none)')||document.querySelector('[data-type="wnd"] .protyle:not(.fn__none)');

这种方式,当刚刚刷新或重启情况下,默认取第一个分屏的文档。

但,这在分屏情况下,不一定准确,用户正在操作的可能不是第一个分屏。

实时上,在分屏情况下是无解的,因为用户尚未操作,无法知道哪个文档是当前文档,换句话说不存在当前文档。这在逻辑上是没错的,从这个角度看也不算思源的坑。

所以,分屏情况下有没有准确获取用户操作的当前文档的办法呢?

我觉得这要具体问题具体分析了。

  1. 如果你确定你的操作被执行时,文档一定是被激活了的,可以用上面的方法实现。
  2. 如果有鼠标事件的操作,可以用 document.elementFromPoint(mouseX, mouseY) 方法实现,具体可以参考本代码中的获取方法。
  3. 如果 1 和 2 都无法确保,可以用 mouseover 或 mousemove 事件写入一个全局变量来实现。

当然,或许还有更好的方法吧,请各位大佬们不吝赐教!!!

  • 思源笔记

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

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

    23012 引用 • 92566 回帖
  • 代码片段

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

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

    90 引用 • 561 回帖 • 1 关注
1 操作
wilsons 在 2024-12-05 17:50:35 更新了该帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • Wetoria 1 1 评论

    上面的是针对思源渲染的文档,如果是自定义渲染的 block,sql 版本:

    const sqlStmt = `sql root_id from blocks where id = '${clickedDomNodeId}'`
    const res = await reqeust(`http://localhost:6806/api/query/sql`, {
      stmt: sqlStmt,
    })
    const docId = res[0]?.root_id
    
    没测试,自己拿去改吧。
    Wetoria
  • 其他回帖
  • wilsons 1

    买一赠一啦!

    借此贴分享下状态栏可拖动代码。

    功能介绍:

    让状态栏可拖动,双击可还原。

    我真的需要吗?

    让状态栏浮动后,你有没有发现,有时会遮挡住某些元素,有时挺烦人的。

    如果你曾有过这个烦恼,下面这个代码可以让你把状态栏在需要时拖动到别的地方,双击可还原。

    https://ld246.com/member/wilsons/breezemoons/1733192201673

  • wilsons

    感谢大佬!

    我明白了,你是针对我这个功能说的吧,我这个功能确实可以。

    但吐槽这里主要说的是通用情况,非特定场景下的获取方法。

    我这个功能没用接口查询,主要觉得 dom 查询可能比接口查询快些吧。

    1 回复
    1 操作
    wilsons 在 2024-12-05 18:49:18 更新了该回帖
  • Wetoria 1 1 评论

    emmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

    拿去玩

    let dom = clickedDom
    while (dom || (dom.classList && !dom.classList.contains('protyle-content'))) {
      dom = dom.parentElement
    }
    let docId = null
    if (dom) {
      const protyleTop = dom.firstElementChild
      docId = protyleTop.firstElementChild.dataset.nodeId
    }
    
    拿 dom,这种就行,最后的 dom 就是 protyle
    Wetoria
  • 查看全部回帖
wilsons
人生最大的敌人是自己,战胜自己,才能超越一切。