熊猫别熬夜
(噗~)
1
Note Toolbar 它可以为不同的文件夹配置不同的工具栏,并能够在文件夹之间自适应切换,而且可以非常方便的编辑工具栏按钮。
不过我比较喜欢cmenu插件那种简洁的按钮格式,于是修改了下插件样式,可以用下面的样式定制 Note Toolbar 布局以模拟 Cmenu 显示,效果如下。

对应设置如下:
样式设置
您可以将 Note Toolbar 的显示样式更改为类似于 Cmenu 插件的样式。这种设置仅在工具栏名称中包含“cmenu”时生效。


- 将工具栏的位置设置为“置顶(固定位置)”即可,其他设置保持默认。
- 注意:目前,该设置暂不支持移动端,因此建议在移动设备上隐藏此工具栏。
自带的分割符和行号符可以正常运行
CSS 样式
对应的 Style Setting 设置有如下:

cmenu 对齐方式:flex-start、flex-end、space-around、space-between、space-evenly

图片来自《深入解析 CSS》P137 5.4.1 理解弹性容器的属性
/* @settings
name: Note Toolbar 仿 cMenu 的菜单栏
id: Note Toolbar 仿 cMenu 的菜单栏
settings:
-
id: cmenu-note-toolbar-width
title: cmenu宽度
type: variable-number
default: 460
format: px
-
id: cmenu-flex-just-content
title: cmenu对齐方式
description:
type: variable-select
default: flex-start
options:
- flex-start
- flex-end
- space-around
- space-between
- space-evenly
*/
body {
--cmenu-note-toolbar-width: 460px;
--cmenu-flex-justily-content: flex-start;
}
/* note toolbar 像 cmenu那样显示 */
div[data-name *="cmenu"] {
z-index: var(--layer-status-bar);
position: absolute;
bottom: 60px;
width: 100% !important;
pointer-events: none !important;
display: flex;
justify-content: center !important;
background-color: transparent !important;
div.callout, .callout-content {
background-color: transparent !important;
border: 0 !important;
margin: 0 !important;
opacity: 1 !important;
/* width: fit-content;
height: fit-content; */
}
ul[role="menu"] {
pointer-events: auto !important;
width: fit-content;
max-width: var(--cmenu-note-toolbar-width);
/* display: grid !important;
grid-template-columns: repeat(10, minmax(0, 1fr)); */
display: flex;
flex-flow: row wrap;
justify-content: var(--cmenu-flex-just-content);
gap: 8px 5px !important;
padding: 10px !important;
transition: 200ms ease;
height: auto;
border-radius: 6px;
z-index: var(--layer-status-bar);
box-shadow: 0px 3px 30px rgb(31 38 135 / 15%);
margin: 33px !important;
border: 1px solid var(--background-modifier-border);
/* 添加毛玻璃效果 */
background-color: rgba(255, 255, 255, 0.1) !important;
backdrop-filter: blur(10px);
li {
border-radius: 6px;
background-color: var(--background-secondary);
&>span {
width: 40px;
display: flex;
align-items: center;
justify-content: center;
padding: 6px !important;
svg {
transform: scale(1.2);
}
}
.cg-note-toolbar-item-label {
display: none;
}
}
}
}
原文链接:PKMer_Obsidian 插件样式:修改 note toolbar 插件布局像 cmenu 那样显示
1 个赞
Echors
(Echors)
2
大佬,您好,我根据您的设计做了一些改动,使工具栏支持拖动和折叠,效果如图



拖动到右侧可以竖排显示
下面是调整后的css,添加了一些样式设置
/* @settings
name: Note Toolbar 仿 cMenu 的菜单栏
id: Note Toolbar 仿 cMenu 的菜单栏
settings:
-
id: cmenu-note-toolbar-width
title: cmenu宽度
type: variable-number
default: 460
format: px
-
id: cmenu-flex-just-content
title: cmenu对齐方式
description:
type: variable-select
default: flex-start
options:
- flex-start
- flex-end
- space-around
- space-between
- space-evenly
*/
body {
--cmenu-note-toolbar-width: 460px;
--cmenu-flex-justily-content: flex-start;
}
/* note toolbar 像 cmenu那样显示 */
div[data-name *="cmenu"] {
z-index: var(--layer-status-bar);
position: absolute;
bottom: 60px;
width: 100% !important;
pointer-events: none !important;
display: flex;
justify-content: center !important;
background-color: transparent !important;
div.callout, .callout-content {
background-color: transparent !important;
border: 0 !important;
margin: 0 !important;
opacity: 1 !important;
}
ul[role="menu"] {
pointer-events: auto !important;
width: fit-content;
max-width: var(--cmenu-note-toolbar-width);
display: flex;
flex-flow: row wrap;
justify-content: var(--cmenu-flex-just-content);
gap: 4px !important;
padding: 6px !important;
transition: 200ms ease;
height: auto;
border-radius: 6px;
z-index: var(--layer-status-bar);
margin: 20px !important;
border: 1px solid var(--background-modifier-border);
/* 添加毛玻璃效果 */
backdrop-filter: blur(10px);
background-color: transparent;
li {
border-radius: 6px;
background-color: var(--background-secondary);
&>span {
width: 30px;
display: flex;
align-items: center;
justify-content: center;
padding: 3px !important;
svg {
transform: scale(1.2);
}
}
.cg-note-toolbar-item-label {
display: none;
}
/* 拖动手柄样式 - 与其他按钮保持一致 */
&.toolbar-handle {
background-color: var(--background-secondary) !important;
cursor: move !important;
order: -2;
&:hover {
background-color: var(--background-modifier-hover) !important;
}
&>span {
color: var(--text-normal) !important;
}
/* 添加拖动图标 */
&>span>svg {
opacity: 0.7;
}
&:hover>span>svg {
opacity: 1;
color: var(--text-normal);
}
}
/* 折叠按钮样式 - 与其他按钮保持一致 */
&.toolbar-toggle {
background-color: var(--background-secondary) !important;
cursor: pointer !important;
order: -1;
&:hover {
background-color: var(--background-modifier-hover) !important;
}
&>span {
transition: transform 200ms ease;
color: var(--text-normal) !important;
}
&>span>svg {
opacity: 0.7;
}
&:hover>span>svg {
opacity: 1;
}
&.is-collapsed>span {
transform: rotate(180deg);
}
}
}
/* 折叠状态 */
&.is-collapsed {
li:not(.toolbar-handle):not(.toolbar-toggle) {
display: none !important;
}
}
/* 拖动状态 */
&.is-dragging {
z-index: calc(var(--layer-status-bar) + 10);
}
}
/* 自定义位置 */
&.has-custom-position {
position: fixed !important;
bottom: auto !important;
justify-content: flex-start !important;
width: auto !important;
ul[role="menu"] {
margin: 0 !important;
}
}
}
/* 响应式适配 */
@media (max-width: 768px) {
div[data-name *="cmenu"] ul[role="menu"] {
max-width: calc(100vw - 40px);
margin: 15px !important;
padding: 5px !important;
}
}
/* 防止拖动时选中文本 */
body.dragging-toolbar {
user-select: none !important;
-webkit-user-select: none !important;
}
下面是JavaScript脚本,放在库中即可
// 工具栏增强脚本 - 最简单直接的拖动实现
(function() {
'use strict';
let toolbar = null;
let container = null;
let isDragging = false;
let lastX = 0;
let lastY = 0;
let isCollapsed = false;
function init() {
console.log('🔧 初始化工具栏增强');
findToolbar();
const observer = new MutationObserver(() => {
if (!document.querySelector('.toolbar-handle')) {
setTimeout(findToolbar, 1000);
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
function findToolbar() {
container = document.querySelector('div[data-name*="cmenu"]');
toolbar = container?.querySelector('ul[role="menu"]');
if (!toolbar) {
setTimeout(findToolbar, 1000);
return;
}
if (!toolbar.querySelector('.toolbar-handle')) {
createButtons();
} else {
bindExisting();
}
}
function createButtons() {
// 拖动手柄
const handle = document.createElement('li');
handle.className = 'toolbar-handle';
handle.innerHTML = `<span><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg></span>`;
// 折叠按钮
const toggle = document.createElement('li');
toggle.className = 'toolbar-toggle';
toggle.innerHTML = `<span><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6,9 12,15 18,9"/></svg></span>`;
toolbar.insertBefore(toggle, toolbar.firstChild);
toolbar.insertBefore(handle, toolbar.firstChild);
bindEvents(handle, toggle);
console.log('✅ 按钮已创建');
}
function bindExisting() {
const handle = toolbar.querySelector('.toolbar-handle');
const toggle = toolbar.querySelector('.toolbar-toggle');
bindEvents(handle, toggle);
console.log('✅ 重新绑定按钮');
}
function bindEvents(handle, toggle) {
// 拖动开始
handle.addEventListener('mousedown', function(e) {
e.preventDefault();
e.stopPropagation();
isDragging = true;
lastX = e.clientX;
lastY = e.clientY;
// 首次拖动时,计算并存储容器内边距导致的偏移
if (!container.dataset.offsetX) {
const toolbarInContainer = container.querySelector('ul[role="menu"]');
if (toolbarInContainer) {
const containerRect = container.getBoundingClientRect();
const toolbarRect = toolbarInContainer.getBoundingClientRect();
container.dataset.offsetX = (toolbarRect.left - containerRect.left).toString();
container.dataset.offsetY = (toolbarRect.top - containerRect.top).toString();
} else {
container.dataset.offsetX = '0';
container.dataset.offsetY = '0';
}
}
// 只在第一次拖动时切换到固定定位
if (!container.classList.contains('has-custom-position')) {
const rect = container.getBoundingClientRect();
container.classList.add('has-custom-position');
container.style.left = rect.left + 'px';
container.style.top = rect.top + 'px';
}
toolbar.classList.add('is-dragging');
document.body.classList.add('dragging-toolbar');
console.log('🎯 开始拖动');
});
// 折叠功能
toggle.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
isCollapsed = !isCollapsed;
if (isCollapsed) {
toolbar.classList.add('is-collapsed');
toggle.classList.add('is-collapsed');
} else {
toolbar.classList.remove('is-collapsed');
toggle.classList.remove('is-collapsed');
}
console.log('🔄 切换折叠');
});
// 防止默认行为
handle.ondragstart = () => false;
handle.onselectstart = () => false;
}
// 全局鼠标移动 - 使用相对移动
document.addEventListener('mousemove', function(e) {
if (!isDragging) return;
// 计算鼠标移动的距离
const deltaX = e.clientX - lastX;
const deltaY = e.clientY - lastY;
// 更新记录的鼠标位置
lastX = e.clientX;
lastY = e.clientY;
// 获取当前位置
const currentLeft = parseInt(container.style.left) || 0;
const currentTop = parseInt(container.style.top) || 0;
// 计算新位置
let newLeft = currentLeft + deltaX;
let newTop = currentTop + deltaY;
// --- 智能边界检测 ---
const rootEl = document.documentElement;
const leftSidebar = document.querySelector('.mod-left-split');
const rightSidebar = document.querySelector('.mod-right-split');
const titleBar = document.querySelector('.workspace-tabs');
const statusBar = document.querySelector('.status-bar');
const bounds = {
left: leftSidebar && leftSidebar.classList.contains('is-open') ? leftSidebar.getBoundingClientRect().right : (document.querySelector('.workspace-ribbon')?.getBoundingClientRect().right || 0),
right: rightSidebar && rightSidebar.classList.contains('is-open') ? rightSidebar.getBoundingClientRect().left : rootEl.clientWidth,
top: titleBar ? titleBar.getBoundingClientRect().bottom : 0,
bottom: statusBar ? statusBar.getBoundingClientRect().top : rootEl.clientHeight
};
// 获取容器尺寸和内边距偏移
const containerRect = container.getBoundingClientRect();
const offsetX = parseFloat(container.dataset.offsetX) || 0;
const offsetY = parseFloat(container.dataset.offsetY) || 0;
// 边界限制 (考虑内边距补偿)
const minLeft = bounds.left - offsetX;
const maxLeft = bounds.right - containerRect.width;
const minTop = bounds.top - offsetY;
const maxTop = bounds.bottom - containerRect.height;
newLeft = Math.max(minLeft, Math.min(newLeft, maxLeft));
newTop = Math.max(minTop, Math.min(newTop, maxTop));
// 应用新位置
container.style.left = newLeft + 'px';
container.style.top = newTop + 'px';
});
// 全局鼠标释放
document.addEventListener('mouseup', function() {
if (!isDragging) return;
isDragging = false;
toolbar.classList.remove('is-dragging');
document.body.classList.remove('dragging-toolbar');
console.log('✅ 拖动结束');
});
// 重置功能
window.resetToolbar = function() {
container.classList.remove('has-custom-position');
container.style.left = '';
container.style.top = '';
toolbar.classList.remove('is-collapsed');
const toggle = document.querySelector('.toolbar-toggle');
if (toggle) toggle.classList.remove('is-collapsed');
isCollapsed = false;
console.log('🔄 工具栏已重置');
};
init();
console.log('✅ 工具栏增强脚本加载完成');
})();
2 个赞