Yank Note 是我编写的一款面向程序员的笔记应用。这里我将会写下一些关于 Yank Note 的文章Yank Note 实现了从源码到预览的单向同步滚动。研究了一些同步滚动方案,大体分为下面三种。
行号匹配 Yank Note 最初就是采用的这种方案,简单直接,前提是渲染出的 Dom 节点需要包含行号信息。
- 监听编辑器可视区域变化/滚动事件,获取顶部的行号
- 拿着行号找到对应行号的 Dom 元素
- 调用 Dom 元素的
scrollIntoView
方法
等比例滚动 这个方案就是不管行号匹配,直接按照编辑器滚动高度和可视区域滚动高度来等比例设定滚动条位置。
文章图片
这个方案优点是不用计算行号,适合 textarea 做编辑器的场景,滚动也比较平滑。缺点则是滚动不太精准,特别是有图片的时候。
综合方案 根据标题做等比例滚动
掘金的 Markdown 编辑器是使用的字节的 Bytemd 编辑器。
每次编辑器滚动,标题到顶时候,始终保证标题元素是平齐的。也就是两个标题之间的滚动做等比例滚动。
优点是滚动非常平滑,也兼顾了一部分滚动精确性,只能精确到标题。
行号匹配和等比例结合
Markdown-it Demo 是用的这种算法。
在行号匹配的基础上:
- 如果能找到对应行号的 Dom 元素,直接将对应 Dom 元素滚动到可视区域顶部。
- 如果不能找到对应行号的 Dom 元素,那就获取该行号的上一个 Dom 元素 和下一个 Dom 元素。直接根据行号偏移做等比例滚动。
因为 Yank Note 里这种场景比较多(Mermaid 图形、脑图、HTML 小工具等),滚动平滑度我个人觉得不是那么重要,所以最终采用了这个方案。
进一步 在使用 Sublime Merge 的过程中,我发现它的解决冲突界面,同步滚动做得比较符合我的预期。这种交互我觉得可以再研究一下,看能不能作为 Markdown 编辑和预览同步滚动的另一种方法。
文章图片
参考
- markdown编辑与预览窗口同步算法 - 少年小白 - 博客园
- markdown-it.github.io/index.js at master
- bytemd/editor.svelte at main
本文由「Yank Note - 一款面向程序员的 Markdown 笔记应用」撰写