目录
前言:我的编程成果
编程中遇到的挑战
为什么要做这个编辑器?
最后:我的的想法
前言:我的编程成果
目前在写作的世界里,已有许多优秀精致的 Markdown 编辑器横空出世,比如大名鼎鼎的 Ulyless、Bear、MarkEditor、MWeb、Typora 等等。
然而作为一个编程新手,你可能想要尝试做一个完全属于自己、适合自己的 Markdown 编辑器。
随心所欲、私人定制的背后总是有着无数的坑,你必须跳下去。😂
在花费了一周的时间之后,我终于创造了我的 「Markdown 编辑器 01 版」。在这个过程中,我不断地经历着编程的错误百出以及需求的失败与变更,希望通过我的介绍可以帮助你了解这个过程。其中实现的功能:
- Markdown 预览
- 代码高亮
- 设置 CSS 属性
- 输入 CSS 语句
- 响应式布局
- 本地存储
- 生成 PDF
当然也有最终没有实现而被替换的功能:
- 选择 CSS 模板❎
- 生成图片❎
编程中遇到的挑战
以下部分,正文就开始了。
Markdown 预览
如果利用原生 JavaScript 语言,可能需要不断进行 # hello world
<h1>hello world</h1>、```my code```
<pre><code>my code</code><pre>之类的替换。为了减少这个重复的过程,利用现有轮子,我使用了 marked.js
这个成熟的库,帮助我简化代码。
html_area.innerHTML = marked( markdownArea.value, { sanitize: true } )
代码高亮
当大家使用那些已经商业化的编辑器时,它们均内置了代码高亮这个功能。然而它并不是原生 Markdown 就具备的。在自制 Markdown 编辑器中,即使你已经在第一行说明了代码语言类型,它依然无法起效,代码仍然默认为黑色。
```javascript
console.log( [ 'a', 'b', 'c' ] )
```
有一个最简单的方法,就是直接在 CSS 中宣称代码的颜色。请注意观察下图右侧代码的颜色。⚠️
code { color: red; }
然而,它只是通过颜色区别设置将代码部分与正文文字分开,并未实现我们真正需要的代码高亮。
我的解决办法是导入 highlight.js
这个代码高亮库及其配套的 CSS 库。由于 HTML 其实是动态生成的,所以必须设置相应的事件监听器,保证其高亮的代码部分可以及时刷新、更新。
html_area.querySelectorAll( 'code' ).forEach( ( block ) => {
hljs.highlightBlock( block );
});
最后看实现的效果,是不是还不错?
设置 CSS 属性
在大多数 Markdown 编辑器的设置部分,用户可以自动调整一些基础样式,比如字体、行高等等。当任意改变一个滑动条时,文章内容的样式改变会即刻生效。
如果没有设计 CSS ,那么整个页面基本就是黑白两色了。
要如何实现多样化的CSS 属性定制呢?
首先你需要利用 CSS3的变量功能,设置一些基础的可调节变量,如padding
、weight
、height
、font-size
、color
、background-color
等。在设置这边变量的同时,也要设定它们的默认值哦。更重要的,将它们与相应的 input
联系在一起。
:root {
--padding : 10px;
--width : 100%;
--font-size : 16px;
--color: #336699;
}
<input type="number" name="padding" value="10" data-sizing="px">
最后一步,就是利用 JavaScript 将这些改变生效1 。
function handelControl() {
const suffix = this.dataset.sizing || '';
document.documentElement.style.setProperty( `--${ this.name }`, this.value + suffix );
}
inputs.forEach( input => input.addEventListener( 'change', handelControl ))
输入 CSS 语句
input 导入文件 -> 获取文件地址 -> 插入到 link -> CSS 文件生效
input 导入文件 -> 获取文件地址 ❌
为什么呢?原来是因为为了阻止恶意软件猜测文件路径,路径字符串以C:\fakepath\为前缀
。2 没有真实路径,我怎么让用户导入CSS 文件呢?所以,就让用户直接在文本输入框输入 CSS语句吧。
响应式设计
在平板、甚至电脑屏幕上,我选择了三列式的设计,从左到右分别是设置区域、Markdown 区域、HTML 区域。这样可以最大限度地利用宽屏空间。
然而,在手机页面,我选择了自上而下的三行式布局,这很明显是因为手机屏幕宽度不够。另外,大多数人在手机上的操作为上下滑动。这样也是符合了用户交互的原则吧。
@media screen and (max-width: 500px) {
div#app {
display: grid;
grid-template-rows: repeat(3,1fr);
}
}
本地存储
由于这个「自制 Markdown 编辑器」本质上只是一个 HTML 文件,为了方便测试过程,保存 CSS 语句、Markdown 语句等,我设置了本地存储功能。因此在下次加载过程中,不需要重新输入内容,大大提高开发效率,或者说提高了用户满意度。毕竟,好不容易设计的 CSS 我可不想一下子没了。😉
生成 PDF
为什么我没有生成图片呢?因为我没有找到一个合适的方法将创建的 HTML 生成图片。所以我只能另辟蹊径,利用window.print()
功能生成一份 PDF。
看起来不错吧。但这功能背后也有很多挑战。这可一点也不容易啊,30行 JavaScript 代码,花费了我2天的时间,还是靠我的灵机一动呢🌟
- 新建一个窗口文档(难度⬆️,灵机一动⬆️⬆️)
- 导入其 HTML内容
- 导入动态滑动条的 CSS 变量属性(难度⬆️,灵机一动⬆️⬆️⬆️)
- 导入已输入的 CSS 语句
- 创建导入 highlight.js 代码高亮
为什么要做这个编辑器
如果有编程新手练习 Vue 前端框架。那么就会有一个学习案例:简易 Markdown 编辑器。这个案例很简单,只用到了几行 Vue 语句。
如果大家尝试过 Text2Image这款软件,它的主要功能是:将输入的 Markdown 文件最终转换成图片保存。对我而言要实现这个比较困难,开发者主要利用 Python、jinja 进行编程。
所以作为一个折衷的想法,我尽自己所能,用前端三剑客 HTML、CSS、Javascript 完成了部分编程需求。
最后:我的想法
说实话,编程比我想象的更加困难,但是有了目标,有了方向,完成第一步总比永远没有出发好太多,也厉害太多。所以争取做一个厉害的人吧!👑