我用contenteditable构建所见即所得编辑器的痛苦 2021-11-02 默认分类 暂无评论 1789 次阅读 ![WeCom20211102-101615@2x.png][1] 自然,当讨论中出现文本编辑器时,创建一个自定义的解决方案并不是人们首先想到的事情。所以我继续前进,我开始寻找我可以使用的可靠的所见即所得编辑器。互联网上有相当多的现成解决方案。有些是著名的,被知名的平台使用,如WordPress。但也有很多被抛弃了,被丢在GitHub仓库里积灰。 ![WeCom20211102-101722@2x.png][2] 经过大量的时间在网上搜索和测试编辑器,结果发现我们有一些相当独特的要求。没有一个可用的编辑器符合我们的标准,所以我就开始了一个冒险,编写一个自定义的所见即所得编辑器。 在我多年的前端经验中,这个项目在罕见的bug和意外行为方面给了我最疯狂的旅程。我拼命地搜索,以至于我最终找到了十年前就没有关闭的晦涩难懂的WebKit bug!我想说明的是,我在这个项目中遇到了很多问题。 我想说明的是,我只使用了现代的Chrome和Firefox。在Safari和老式浏览器中的Conteditable是另一个世界,我将在未来的博文中介绍。 **2021年的自定义所见即所得编辑器?** ---------------------- 你可能会问自己,既然有数百种选择,我们还需要一个内部解决方案吗?答案是令人惊讶的,是的--我们需要!我们的服务性质要求我们需要一个内部解决方案。 我们的服务性质要求我们这样做;我们需要一个自定义的数据类型来存储和处理contenteditable的内容,以便以后在我们的产品线上使用。例如,你通过我们的编辑器创建的内容必须是可搜索的,同时它在我们所有的产品中以非常多样化的风格呈现--例如在帮助台小部件、搜索小部件或我们的知识库平台。 ![WeCom20211102-101835@2x.png][3] 目前的解决方案在处理来自contenteditable的数据方面没有提供太多的控制--输出总是肮脏的HTML,而在数据库中存储和处理由contenteditable产生的HTML是不可能的。 哦,我们还需要尽可能多的元素,包括定制的元素,这些元素不仅目前的库不支持--而且除非你分叉整个东西,否则不可能扩展功能或注册新元素。 我们的编辑器目前支持: - 粗体 - 斜体 - 下划线 - 标题 - 列举式列表 - URLs - 内联代码 - 图片 - 表格 - 横向分隔线 - 区块引语 - 代码块(具有语法高亮和多语言支持)。 - Youtube视频 - 和其他一些 **开始开发** -------- 我的思考过程是使用contenteditable属性首先创建一个简单的编辑器--通过遵循网上的最佳实践。那种只支持粗体、斜体和下划线的编辑器。然后找出一种方法来扩展功能,并根据我们的需要添加自定义元素。 ![WeCom20211102-102017@2x.png][4] 我的想法采取了这个方向,因为当我看到Firefox或Chromium这样的开源项目时,"不一致的混乱 "并不是我脑海中的第一个想法。我以为目前的contenteditable属性可以处理这样一个简单的编辑器--但我错了。 **痛苦#1:execCommand被弃用了** ------------------------ 要用contenteditable使文本变粗,你必须使用JavaScript方法execCommand,如果你在MDN中查找,它是一个被废弃的方法!而且没有其他方法可用。而且没有其他方法可用。这是你唯一可以用来给contenteditable中的文本设置样式的方法。 ![WeCom20211102-102107@2x.png][5] 坦率地说,这是一个相当大的红旗,但我还是决定向前推进。 当浏览器供应商决定完全放弃execCommand时,现在地球上的许多编辑器都有可能在下一个版本的Chrome或Firefox中直接停止工作。我还没有看到任何不使用execCommand方法的编辑器。 **痛苦#2:来自地狱的退格合并** ------------------ 想象一下这个场景。你的光标在一个段落的开头。就在这一段的前面,有一个标题(H2),你点击了退格。应该发生什么? ![WeCom20211102-102302@2x.png][6] 通俗地说:该段应与标题相连。用更多的技术术语来说:P标签的内容应该放在H2标签的内容里面。但当我在开发工具中查看时,情况并非如此。 ``` My heading My very short paragraph. ``` ``` My headingMy very short paragraph. ``` 点击退格键后,浏览器决定将P标签转换成SPAN,然后对这个SPAN应用一些内联CSS,使其看起来像H2标签,然后将这个新的SPAN元素放在H2标签内。 ``` My headingMy very short paragraph. ``` 更加复杂的是,如果该段落有粗体和斜体等样式--它还会将B和I元素转换成SPAN,并通过text-style属性用内联CSS保留文字样式。 当我发现contenteditable对HTML元素犯了罪时,我怀疑我是否会完成这个项目。但这只是第2个痛苦,所以请继续阅读以了解更多信息 **痛苦#3:有趣的换行** -------------- 自Firefox 1以来,最著名的添加断行(垂直空间)的方法是使用BR标签。 当光标位于一大块文本的中间,而你敲了两次回车键--你会很自然地认为这一大块文本被一分为二,然后contenteditable在中间添加了两个BR标签。 ``` .. some very long paragraph with multiple styles such as, bold and itallic ``` ``` .. some very long paragraph with multiple styles such as, bold and italic ``` 相反,发生的情况是,两个BR标签确实被添加了,但由于某些原因,contenteditable也将BR包裹在标签周围,而这些标签恰好在你点击两次回车之前包裹了文本--导致我所看到的一些最漂亮的BR标签 无论标记是如何嵌套的,这些有趣的br标记都会随之而来。 比如说 --- ``` ``` ``` ``` ``` ``` 这种行为一开始似乎是一个bug,因为其结果根本就是伏笔。但是(我认为)浏览器试图保留文本样式,以备你决定在这些换行符内书写文本。 痛苦 #4:你可以为所有的东西设计样式! 只要你能在contenteditable中选择一段文字,快捷键CTRL+B就能使文字变粗,而且不管它在哪里,也不管是什么原因。 ![WeCom20211102-102816@2x.png][7] 正如我在这篇博文的开头提到的,我们的编辑器有自定义元素,如表格或代码亮点。允许许多这些自定义元素的文本造型是没有意义的,但无论如何,这是有可能的! ![WeCom20211102-102908@2x.png][8] 不过,我通过在自定义元素的包装DIV中添加contenteditable=false,解决了这个问题。 **下一步是什么** ---------- contenteditable的默认行为并不有趣。它给人的感觉就像黑客上的黑客--它不会想得太远,如果你允许它,只要内容在屏幕上看起来不错,它就会无限地嵌套你的HTML。 我正在创建一个新的编辑器的开源版本--在从Answerly的编辑器工作中获得所有这些经验和知识之后,我将建立这样一个编辑器。 这个新的编辑器将手动处理所有的击键事件,并允许一些非常一致的配置和功能,如。 选择使用什么元素作为文本样式 - 一致的换行 - 更好的合并 - 添加和编辑自定义元素 - 配置contenteditable的结果(如JSON,Markdown)。 **真正的contenteditable的未来** ------------------------- Contenteditable将是一致的,最终,无论是现有的建议还是全新的东西。但是,如果说它明天就更新了,那就需要很多时间,直到浏览器的采用越来越多--所以直到现在,我们还停留在现有的解决方案上。 如果你在互联网上搜索,有两个提议似乎最有吸引力,并有望改善目前的contenteditable。 **contenteditable=minimal** 本-彼得斯(Ben Peters)@ 微软提出了一个极简版本的contenteditable,它只支持光标的绘制和移动、一些键盘事件和输入字符。这个contenteditable将允许用户手动处理样式,这与我将在我的开源项目中所做的类似。 **Polymer elements和阴影DOM** 一个旧的提议包括用Polymer elements和阴影DOM重建contenteditable。它可以像现在的contenteditable一样工作,但允许更多的定制和更多的事件。 [1]: http://guobacai.com/usr/uploads/2021/11/1881111356.png [2]: http://guobacai.com/usr/uploads/2021/11/2571460327.png [3]: http://guobacai.com/usr/uploads/2021/11/2587403046.png [4]: http://guobacai.com/usr/uploads/2021/11/2854402388.png [5]: http://guobacai.com/usr/uploads/2021/11/2710340218.png [6]: http://guobacai.com/usr/uploads/2021/11/2332289235.png [7]: http://guobacai.com/usr/uploads/2021/11/3500527109.png [8]: http://guobacai.com/usr/uploads/2021/11/1184232261.png 标签: javascript, css, 富文本编辑器, 编辑器
评论已关闭