我想等前端页面加载好后然后在对其修改有什么好的方式嘛

前言

我想做一个插件,就是 通过 替换 [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] 的,这样就很方便

1 个赞

你用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+'行')
    
    
}
         

输出结果如下:
image

这样就能知道当前渲染进度了,希望以上能帮到你