啊 做这个的原因跟思源笔记折腾记录 - 任务列表的序号 - 链滴 (ld246.com)一样,还是为了绕开动态加载时的限制。
效果就像这样
首先我们需要获取全部的打开的文档,这里用面包屑来获取:
async function 生成标题序号() {
let 文档面包屑数组 = document.querySelectorAll(
".protyle-breadcrumb__bar span:first-child[data-node-id]"
);
文档面包屑数组.forEach((文档面包屑元素) => {
let 文档id = 文档面包屑元素.getAttribute("data-node-id");
生成文档内标题序号(文档id);
});
setTimeout(生成标题序号, 1000);
}
然后我们通过文档的实际全篇内容,绕开动态加载来计算章节号。
先获取文档内容:
let 文档内容 = await noobApi.核心api.getDoc({ id: 文档id, size: 102400 });
let 临时元素 = document.createElement("div");
临时元素.innerHTML = 文档内容.content;
这里把获取到的内容弄到一个临时元素里,方便直接用 css 选择器来鼓捣。
放心不渲染出来的话好像不怎么占用资源。
然后就是生成标题序号了:
let 标题元素数组 = 临时元素.querySelectorAll(
'[data-type="NodeHeading"]:not( [data-type="NodeBlockQueryEmbed"] div)'
);
let 计数器 = [0, 0, 0, 0, 0, 0];
let 上一个标题级别 = 1;
for (let i = 0; i < 标题元素数组.length; ++i) {
let 当前标题级别 = parseInt(
标题元素数组[i].getAttribute("data-subtype").replace("h", "")
);
if (当前标题级别 <= 上一个标题级别) {
for (let j = 0; j < 计数器.length; ++j) {
if (j + 1 > 当前标题级别) {
计数器[j] = 0;
}
}
}
计数器[当前标题级别 - 1] += 1;
let 标题id = 标题元素数组[i].getAttribute("data-node-id");
上一个标题级别 = 当前标题级别 + 0;
}
}
最后把这些东西都弄到文档里,就是完整的计数函数了:
async function 生成文档内标题序号(文档id) {
let 文档内容 = await noobApi.核心api.getDoc({ id: 文档id, size: 102400 });
let 临时元素 = document.createElement("div");
临时元素.innerHTML = 文档内容.content;
let 标题元素数组 = 临时元素.querySelectorAll(
'[data-type="NodeHeading"]:not( [data-type="NodeBlockQueryEmbed"] div)'
);
let 计数器 = [0, 0, 0, 0, 0, 0];
let 上一个标题级别 = 1;
for (let i = 0; i < 标题元素数组.length; ++i) {
let 当前标题级别 = parseInt(
标题元素数组[i].getAttribute("data-subtype").replace("h", "")
);
if (当前标题级别 <= 上一个标题级别) {
for (let j = 0; j < 计数器.length; ++j) {
if (j + 1 > 当前标题级别) {
计数器[j] = 0;
}
}
}
计数器[当前标题级别 - 1] += 1;
let 标题id = 标题元素数组[i].getAttribute("data-node-id");
document
.querySelectorAll(`.protyle-wysiwyg div[data-node-id='${标题id}']`)
.forEach((一级标题元素) => {
一级标题元素
.querySelector('[contenteditable="true"]')
.setAttribute(
"style",
`--custom-index:"${序号设置.默认设置[当前标题级别 - 1](
计数器[当前标题级别 - 1]
)} "`
);
});
document
.querySelectorAll(`.sy__outline [data-node-id="${标题id}"]`)
.forEach((大纲项目) => {
大纲项目.setAttribute(
"style",
`--custom-index:"${序号设置.默认设置[当前标题级别 - 1](
计数器[当前标题级别 - 1]
)} "`
);
});
上一个标题级别 = 当前标题级别 + 0;
}
}
还是一样的 不过这回我里面有一个地方因为不想文件太长用到了 noobApi,自己换成对应的接口调用应该就可以了。
let 文档内容 = await noobApi.核心api.getDoc({ id: 文档id, size: 102400 });
相当于:
let 响应 = await (
await fetch("/api/filetree/getDoc", {
method: "post",
body: JSON.stringify({
id: data.data[0].id,
size: 102400,
}),
})
).json();
let 父块内容 = 响应.data.content;
可以自己改一下嗷
其实任务列表序号可以改成用类似的方法生成,不过暂时懒得做了。
还有用属性设置序列样式,也暂时懒得做了。
链接:https://pan.baidu.com/s/12CKtZeJTBOF8vOxd4XooQA?pwd=rb3u
提取码:rb3u
--来自百度网盘超级会员 V5 的分享
整个代码片段的仓库在
leolee9086/snippets (github.com)
就是这样嗷
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于