自定义 css 块属性实时渲染(QYL 同款自定义属性 css)
然后块按右键——属性——自定义——设置为 css 标题——下面写自定义块 css 代码
自定义块 css 属性渲染 css(JS 片段)
/**
* 通过为块添加 'custom-css' 属性,为思源笔记中的任意块应用自定义CSS样式。
*/
class BlockCustomCSS {
constructor() {
// 用于动态创建的 <style> 标签的唯一ID
this.styleId = 'siyuan-block-custom-css-dynamic';
// 用于监听DOM变化的 MutationObserver 实例
this.observer = null;
// 用于防抖的定时器
this.debounceTimer = null;
this.init();
}
/**
* 初始化脚本,执行首次扫描并设置MutationObserver来监听后续变化。
*/
init() {
console.log('块自定义CSS功能已初始化');
this.applyStyles(); // 首次加载时应用一次样式
this.observeDOMChanges(); // 开始监听DOM变化
}
/**
* 销毁实例,断开observer并移除注入的style标签,用于清理。
*/
destroy() {
if (this.observer) {
this.observer.disconnect();
this.observer = null;
}
const styleTag = document.getElementById(this.styleId);
if (styleTag) {
styleTag.remove();
}
console.log('块自定义CSS功能已销毁');
}
/**
* 扫描整个文档,查找所有带有 'custom-css' 属性的块,并应用其样式。
* 这就是核心的工作原理实现。
*/
applyStyles() {
// 1. 扫描属性 & 2. 读取属性值
const elements = document.querySelectorAll('[custom-css]');
const cssRules = [];
// 定义一个通用的父容器选择器,确保样式在笔记正文、预览、导出图片等场景下都能生效
const containerSelector = ':is(#layouts, #preview, [data-key="dialog-exportimage"], #editor)';
elements.forEach((element) => {
const cssValue = element.getAttribute('custom-css');
const nodeId = element.getAttribute('data-node-id');
if (cssValue && nodeId) {
// 3. 构建CSS规则
// 使用 :is() 伪类来应用到多个可能的容器中
// 精确地为每个块构建一个唯一的CSS规则
const rule = `${containerSelector} div[data-node-id="${nodeId}"] { ${cssValue} }`;
cssRules.push(rule);
}
});
// 4. 注入 <style> 标签
// 先移除旧的style标签,以防重复注入
const oldStyleTag = document.getElementById(this.styleId);
if (oldStyleTag) {
oldStyleTag.remove();
}
// 如果有任何CSS规则需要应用,则创建新的style标签
if (cssRules.length > 0) {
const styleTag = document.createElement('style');
styleTag.id = this.styleId;
styleTag.type = 'text/css';
styleTag.textContent = cssRules.join('\n'); // 将所有规则合并
document.head.appendChild(styleTag);
}
}
/**
* 设置 MutationObserver 来监听 'custom-css' 属性的变化。
* 当属性被添加、修改或删除时,会自动重新应用所有样式。
*/
observeDOMChanges() {
// 优先选择 .layout__center,如果没有则降级到 body
const targetNode = document.querySelector('.layout__center') || document.body;
if (!targetNode) {
// 如果初始时找不到目标节点,则稍后重试
setTimeout(() => this.observeDOMChanges(), 100);
return;
}
// 配置 observer:监听属性变化、子节点变化,并递归到整个子树
const config = {
attributes: true,
childList: true,
subtree: true,
attributeFilter: ['custom-css'] // 只关心 'custom-css' 属性
};
const callback = (mutationsList, observer) => {
// 使用防抖(debounce)来避免在短时间内频繁地重新计算样式
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => this.applyStyles(), 250);
};
this.observer = new MutationObserver(callback);
this.observer.observe(targetNode, config);
}
}
// 实例化并初始化该功能
const blockCustomCSS = new BlockCustomCSS();
// 如果需要,你可以通过在控制台调用 blockCustomCSS.destroy() 来手动停止该功能。
css 代码渲染的 js 使用说明:
为块添加属性:
在你想要添加自定义样式的块上,右键点击块标选择“属性”。
添加一个名为 css 的块属性。
编写 CSS 代码:
在 custom-css 属性的值中,输入你想要应用的 CSS 代码。
你可以输入任何标准的 CSS 样式规则,例如 background-color: lightblue; border-left: 3px solid blue;
案例如下:
你可以输入任何标准的 CSS 样式规则,例如 background-color: lightblue; border-left: 3px solid blue;
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于