之前用 Asri 主题,觉得 Asri 主题吸引我的主要有 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 代码片段中添加以下代码即可
使用说明
- 理论上所有主题都适用,如果你想仅在某个主题下应用,可以通过以下代码进行限制(下面的两个 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;
- 如果你的主题下左右方向键跳转有问题,可以通过 js 代码片段中的校正因子参数
correctionFactor
进行调整,此时控制台会输出当前计算出的分组大小,只要输出结果和实际一致就可以了,原理及详情可参考源码calcSearchGroupSize()
函数。那么,为什么要计算这个分组大小呢?这是因为,正常情况下区分分组是通过b3-menu__separator
元素的分割来区分的,但在筛选情况下没有该元素的,就只通过菜单高度和菜单项的高度,动态计算出每个分组的大小了,这里叫做虚拟分组。详情请参考之前的帖子 求大佬代码片段支持 / 分组 ←→ 快速切换分组 - 如果你的 css 样式有问题,通过 css 代码片段调整即可。如果还有其他方面的问题也可以在下面发帖进行讨论。当然,如果你通过自己的调整完善了某个主题,也欢迎在下面分享你的成果。
效果:
标签导航栏美化
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);
}
效果:
状态栏浮动到右侧
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;
}
效果:
让状态栏可拖动
让状态栏可拖动,双击可还原状态栏状态
左侧文档树显示层级关系背景线
新增: 左侧文档树,显示层级关系背景线,如图
代码
(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();
});
}
})();
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于