[js][css] 斜杠菜单,导航栏,状态栏,文档树美化和增强

本贴最后更新于 228 天前,其中的信息可能已经时移俗易

之前用 Asri 主题,觉得 Asri 主题吸引我的主要有 3 个功能。

  1. 斜杠命令菜单可以展开
  2. 标签导航栏漂亮
  3. 状态栏浮动到右侧节省空间

但,使用过程中也发现 Asri 有些兼容性问题,比如有些模板,在 Asri 下错位或有问题,要说兼容性最好,估计还得是默认主题了。

那既然这 3 个功能不错,是否可以移植到其他主题下呢?

说干就干,经过一番努力,成功实现了这 3 大功能,另外又增加了状态栏可拖动和文档树显示背景线 2 大功能。

补充说明: 我已在思源集市中测试了 8 个主题(即下载量超过 1 万 + 的主题)均没有任何问题,如果你的主题有问题,可以参考下面的使用说明第 2 项进行调整。

斜杠命令菜单展开和支持左右方向键

由于在 Asri 主题里这个功能并不支持左右方向键,这只能看不能用,让这个功能的优势少了大半呀。

不过,在之前的帖子里我实现了这个功能,但这次迁移,我在这个基础上做了一些调整,以更好的适应其他主题。

使用方法:

首先,css 代码片段中添加以下代码

@media screen and (min-width: 1292px) { .protyle-hint.hint--menu { width: 75vw !important; max-width: 84em; max-height: 65vh; } .protyle-hint.hint--menu>div { -moz-column-width: 12em; column-width: 12em!important; -moz-column-gap: 4px; column-gap: 4px; -moz-column-rule: 1px solid var(--b3-border-color); column-rule: 1px solid var(--b3-border-color); columns: 12em!important; } .protyle-hint.hint--menu>div .b3-list-item .b3-list-item__text { width: -moz-max-content; width: max-content; margin-right: 4px } .protyle-hint.hint--menu>div .b3-menu__separator:not(:nth-of-type(2n + 4)) { -moz-column-break-before: column; break-before: column; margin-bottom: -5px; background-color: rgba(0,0,0,0); } .protyle-hint.hint--menu>.emojis { min-width: 50vw } }

然后,js 代码片段中添加以下代码即可

使用说明

  1. 理论上所有主题都适用,如果你想仅在某个主题下应用,可以通过以下代码进行限制(下面的两个 css 片段标签美化和状态栏浮动的原理也是一样的,都可以通过这种方法进行限制,不再赘述)。

首先,css 片段外层包裹这段代码加以限制

[data-theme-mode="light"][data-light-theme="你的亮色系主题名"], [data-theme-mode="dark"][data-dark-theme="你的暗色系主题名"]{}

然后,js 代码片段里增加这个代码判断加以限制即可

const theme = siyuan.config.appearance.mode === 0 ? siyuan.config.appearance.themeLight : siyuan.config.appearance.themeDark; if(theme !== '你的亮色系主题名' && theme !== '你的暗色系主题名' ) return;
  1. 如果你的主题下左右方向键跳转有问题,可以通过 js 代码片段中的校正因子参数 correctionFactor 进行调整,此时控制台会输出当前计算出的分组大小,只要输出结果和实际一致就可以了,原理及详情可参考源码 calcSearchGroupSize() 函数。那么,为什么要计算这个分组大小呢?这是因为,正常情况下区分分组是通过 b3-menu__separator 元素的分割来区分的,但在筛选情况下没有该元素的,就只通过菜单高度和菜单项的高度,动态计算出每个分组的大小了,这里叫做虚拟分组。详情请参考之前的帖子 求大佬代码片段支持 / 分组 ←→ 快速切换分组
  2. 如果你的 css 样式有问题,通过 css 代码片段调整即可。如果还有其他方面的问题也可以在下面发帖进行讨论。当然,如果你通过自己的调整完善了某个主题,也欢迎在下面分享你的成果。

效果:

r28.gif

标签导航栏美化

css 代码片段增加以下样式即可

.layout-tab-bar .item__close{ padding: 0; } .layout-tab-bar .item{ min-height: 30px; margin-right: 2px; margin-top: 3px; margin-left: 4px; } li.item.item--focus { background-color: oklch(from var(--b3-theme-primary) 0.43 calc(c * 0.9 * var(--asri-c-0, 1)) h/0.2); border-radius: 5px; /*border-top-left-radius: 5px; border-top-right-radius: 5px;*/ } [data-theme-mode="dark"] li.item.item--focus { background-color: oklch(from var(--b3-theme-primary) 0.99 calc(c * 0.9 * var(--asri-c-0, 1)) h/0.21) } .layout-tab-bar .item__text{ padding-left: 6px; padding-right: 6px; } li.item .item__close{ padding-left: 0px; padding-right: 6px; } .layout__wnd--active .layout-tab-bar .item:after{ display:none; } .layout-tab-bar { border-bottom: 1px solid rgba(0,0,0,0); }

效果:

image.png

状态栏浮动到右侧

css 片段增加以下样式即可

/* 状态栏浮动到右侧 */ #status { position: fixed; right: 42px!important; bottom: -8px; border-radius: 20px; height: 26px; padding: 0px 5px 0px!important; margin: 0px 0px 10px; overflow: hidden; z-index: 3; border: none; background: var(--b3-theme-background); } #barDock { position: relative; color: var(--b3-theme-on-background); top: 2px; order: 1; } #statusHelp { position: relative; top: 2px; }

效果:

image.png

让状态栏可拖动

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

https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E8%AE%A9%E7%8A%B6%E6%80%81%E6%A0%8F%E5%8F%AF%E6%8B%96%E5%8A%A8.js

image.png

左侧文档树显示层级关系背景线

新增: 左侧文档树,显示层级关系背景线,如图

r40.gif

代码

(async () => { // 注入css样式,样式可在这里或css片段中进行修改 const countStyle = document.createElement('style'); countStyle.textContent = ` /* 通过给ul背景色添加固定宽度实现 */ .file-tree:hover li.b3-list-item + ul { background: linear-gradient(to right, transparent var(--file-toggle-width), var(--b3-theme-background-light) var(--file-toggle-width), var(--b3-theme-background-light) calc(var(--file-toggle-width) + 1px), transparent calc(var(--file-toggle-width) + 1px)); }` document.head.appendChild(countStyle); // 等待文档树加载完毕 let treeEl; await whenElementExist(()=>{ treeEl = document.querySelector("ul.b3-list[data-url]")?.parentElement; return treeEl; }); // 监控子目录展开 observeSubtreeForUl(treeEl, async (ul) => { await sleep(150); if(ul.previousElementSibling?.dataset?.path === '/'){ // 笔记左侧ul背景线的左侧距离=笔记标题左外边距+笔记标题左内边距+箭头图标宽度的一半 const noteLi = document.querySelector('ul.b3-list[data-url] li[data-path="/"]'); const noteLiStyle = getComputedStyle(noteLi, null); const noteLiMarginLeft = parseFloat(noteLiStyle.marginLeft); const noteLiPaddingLeft = parseFloat(noteLiStyle.paddingLeft); const noteLiToggle = noteLi.querySelector(".b3-list-item__toggle"); const noteLiToggleArrowHalfWidth = noteLiToggle.offsetWidth / 2; const fileToggleWidth = noteLiMarginLeft + noteLiPaddingLeft + noteLiToggleArrowHalfWidth; ul.setAttribute("style", "--file-toggle-width:"+fileToggleWidth+"px"); } else { // 匹配ul的前面的兄弟结点li的--file-toggle-width的值 let prevSiblingStyle = ul.previousElementSibling?.getAttribute("style")?.match(/--file-toggle-width:\s*([\d.]+px)/i); if(prevSiblingStyle) prevSiblingStyle = prevSiblingStyle[0]; ul.setAttribute("style", prevSiblingStyle||""); } //console.log('tree', ul) }); // 监控子目录展开函数 function observeSubtreeForUl(parentElement, callback) { // 回调函数,处理DOM变化 const handleMutations = (mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node.tagName === 'UL') { callback(node); } }); } } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(handleMutations); // 配置观察选项 const config = { childList: true, subtree: true }; // 选择需要观察变动的节点 observer.observe(parentElement, config); // 返回一个关闭函数,以便在不再需要监听时停止观察 return () => { observer.disconnect(); }; } // 延迟执行 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 等待元素渲染完成后执行 function whenElementExist(selector) { return new Promise(resolve => { const checkForElement = () => { let element = null; if (typeof selector === 'function') { element = selector(); } else { element = document.querySelector(selector); } if (element) { resolve(element); } else { requestAnimationFrame(checkForElement); } }; checkForElement(); }); } })();
  • 思源笔记

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

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

    24981 引用 • 102911 回帖 • 1 关注
  • 代码片段

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

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

    136 引用 • 912 回帖 • 1 关注
  • 主题
    27 引用 • 187 回帖 • 5 关注
6 操作
wilsons 在 2025-01-05 10:50:25 更新了该帖
wilsons 在 2024-12-19 14:09:51 更新了该帖
wilsons 在 2024-12-18 19:55:55 更新了该帖
wilsons 在 2024-12-18 19:51:46 更新了该帖 wilsons 在 2024-12-18 19:46:45 更新了该帖 wilsons 在 2024-08-24 13:53:20 更新了该帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • vincents
    @media screen and (min-width: 1292px) { [data-dark-theme="sy-dark-purple"] { .protyle-hint.hint--menu>div{ columns: 12em; column-rule: 1px outset var(--b3-border-color); } } }

    添加了这个 css,完全兼容紫夜主题,感谢大佬的分享 🙏

  • 其他回帖
  • wilsons

    默认積読主题没问题,你自定义的样式是否冲突就不知道了,你可以先关闭自定义的样式看看,然后排查找出原因。

    image.png

    1 回复
  • shiyuankill

    image.png出现了遮挡问题

  • wilsons 1

    试试把第一行和最后一行删除

    即删除 @media screen and (min-width: 1292px) { 和最后一行的 }

  • 查看全部回帖