前言
我想做一个插件,就是 通过 替换 [toc] 根据 H 标签形成 目录,东西已经写好了,就是有一点 我尝试用
registerMarkdownPostProcessor
这个函数,发现这个函数是一行一行的标签进行加载的,而我想要的是等所有的标签加载完成后在执行我的函数
我想做一个插件,就是 通过 替换 [toc] 根据 H 标签形成 目录,东西已经写好了,就是有一点 我尝试用
registerMarkdownPostProcessor
这个函数,发现这个函数是一行一行的标签进行加载的,而我想要的是等所有的标签加载完成后在执行我的函数
应该有文档加载完毕的api,但我也不知道。
我这里有一种笨方法:
每个页面的加载过程是短时间内有连续多个registerMarkdownPostProcessor函数被触发。
就好比你守在一个门口,一队一队的人排队进门。如何知道目前这一对人员全部进门?
每有一个人进门,就在桌子上放一个沙漏计时器(如果桌上已有一个计时器就重置它),计时器结束就判定这一队人员已全部进入。
具体做法就是在全局定义一个变量timer,不赋值。
registerMarkdownPostProcessor每返回一个元素el,就查看timer是否为空值,是则为其赋值一个timeout计时器,否则删除计时器并为其重新赋值。
计时器时长可以设置为500ms,计时器结束后的回调函数用来触发你要进行的动作,回调函数最后别忘了清除存在变量timer中的计时器
至于计时器时长设置多长可以多试试,设置短了会频繁更新浪费性能。设置长了会产生插件反应慢的感觉
频繁的读取写入dom会造成性能下降,因此js鼓励将要更改的dom元素内容先存在变量中,在结束时候一次性写入dom。但一篇文章标题也就几十个,应该不在乎这点性能的浪费。
直接检测每个el元素,如果有标题元素就将其附加到toc中。每渲染一个含有标题的div元素,toc都会动态更新
话说回来,ob不是提供了大纲功能吗?这个toc有什么独到之处?我平时不用toc,但总听论坛里有朋友讨论
这玩意儿需要用到codemirror extension,具体如何写,找几个插件看看就好了。我记得bon写了个task插件,还有cease插件都用到了codemirror扩展。
因为 [toc] 的方式比较通用,方便后续的迁移,比如我有时候会将技术类型的 分享到 csdn 中,而 csdn 是识别 [toc] 的,这样就很方便
你用registerMarkdownPostProcessor
,已经有插件实现了,[toc]
你只能用codemirror。
ob版本v0.15.9:
时隔一个月,我对这个实现方法有了新的理解,应该可以满足你的需求了。不知道你这个问题解决了没?
首先是 registerMarkdownPostProcessor
的使用形式
this.registerMarkdownPostProcessor(function(){
}
)
这个函数要求输入一个函数作为其参数,每次切换到预览视图,ob会依次逐条传入div进行渲染,在当前页面所有div全部注册完成,再一次性更新到DOM中。
其实这个函数是有传入的默认参数的,尝试以下代码
this.registerMarkdownPostProcessor(function(){
console.log(arguments)
}
)
会发现,对于每个传入的div,registerMarkdownPostProcessor都会默认传入两个参数,一个是div元素(当然,传入时候这个div元素尚未注册到DOM树中),一个是上下文对象(包含当前笔记的路径、docId、当前正在注册的div元素以及其他一些方法)
this.registerMarkdownPostProcessor(function(el,ctx){
console.log('当前正在渲染'+ctx.getSectionInfo(el).lineStart+'行~'+ctx.getSectionInfo(el).lineEnd+'行')
console.log('共有——————'+ctx.getSectionInfo(el).text.match((/\n/g)).length+'行')
// console.log('共有——————'+app.workspace.activeLeaf.view.lastSavedData.match(/\n/g).length+'行')
}
输出结果如下:
这样就能知道当前渲染进度了,希望以上能帮到你