一、前言
经过近一天的折腾,写的markdown编辑器总算稍稍能用了:
不过离商业化还早的很,目前还有很多细节没有做好,估计至少还得花两三个月时间才能完成这个编辑器的基本功能,只能慢慢来了。
本文主要是来聊聊我实现的这个编辑器的功能遇到的一些坑。
不得不说,网上关于这方面的资料实在是太少了,随便一个坑可能都得让我花几十分钟、甚至一两小时去琢磨。
二、前置思路
正如上面图中所示,我的目的是完成一个实时渲染的markdown编辑器,尽量对标typora软件。
html
中拥有编辑功能的只有两个控件:input
、textarea
。
但很遗憾,对于想要自制高级编辑器来说,这两个控件都是不合适的,因为它们里面有很多默认行为是我们不希望的。
我个人认为tauri底层应该是使用了开源库实现的实时渲染,因为完全从零做起工作量实在太大了。
本文只简单谈谈我实现这个编辑器的逻辑,不一定对,因为这只是我目前的想法,未来肯定还会有所变化的。
首先是选择标签方面,为了能够高度可定制,我使用的是div
标签,只需要再为其添加一个contenteditable
属性就行了:
当然,这肯定是不够的,想要实现一个可以控制样式的编辑器,我们就需要去控制我们输入字符每一个细节。
比如当我们往里面输入多行文本时,查看其标签的变化:
可以看到,我们往这个可编辑的标签中输入文本的过程,实际上就是在往这个标签的内部插入数据与标签的过程。
除了第一行为纯文本标签Text
,只要你按一下Enter
换行,它就会自动生成一个div
子标签,并且你接下来输入的内容都会进入到这个div
子标签中,除非你再次换行。
那么想要控制这个可编辑区域的样式不就简单了吗?就像这样:
所以我们的想法很简单,那就是将不同的文本,用不同的标签将其包裹起来,最后再设置不同标签的样式就行了!
而由于我这里是想要实现一个markdown
编辑器,事实上已经有现成的包可以将markdown
格式的文本转化为html
标签,比如我是用的markdown-it
。
之所以分屏markdown
渲染常见,就是因为这样做最简单:直接将可编辑区域的文本全部读取,然后用markdown-it
包将其转换为html标签,最后将结果存放到另一半屏幕上就行了:
因为简单,所以泛滥,这种markdown编辑器一般来说自然也就很难与其它编辑器有竞争力,并且老实说,我觉得体验并不好,自然也就很难商业化,毕竟这样的免费开源库都有一大堆了。
我的目的是实现typora这样的效果:当光标聚焦时,显示原本的可编辑文本,当光标离开时,将其实时渲染出来。
这个过程是很麻烦的,因为这需要高度自定义这个编辑框的行为,下面先简单聊聊我目前踩过的一些坑,后面有空再继续聊。
三、自定义生成标签
首先是设置contenteditable
之后它的默认输入文本行为是:
- 不换行:文本会直接作为
Text
标签存入父标签的子目录 - 换行:会自动生成一个新的
div
子标签,新输入的文本会进入这个子标签的内部
这个默认行为肯定是无法接受的,不说别的,至少第一行也应该包含到一个div
子标签中吧?这样我们写样式也方便点。
也就是这么个看似简单的步骤,我大概就摸索了数个小时,总结来说有两种解决方案: