在线富文本编辑器里面,做以下操作:
在大部分其他的编辑器里面,到第二步的时候,刚才加粗的所有文字都回复了正常状态:
而知乎的编辑器的效果是这样:
从 HTML 上面看,它是把一个<b></b>节点拆成了三个节点:
<b>some</b>inserted text<b>bold text</b>.
问题是:在 contentEditable 上的编辑操作只能更新当前节点的文本内容,也就是说如果没有 js 干预,效果是这样:
<b>some inserted text bold text</b>
知乎的编辑器是怎样完成分拆动作的?
监听 keypress 事件?那输入中文怎样实现?
监听 change ?
1
morethansean 2016-02-19 13:45:47 +08:00
知呼这个不是浏览器的默认处理方式吗……
|
2
wangleineo OP @morethansean 不是,浏览器本身并不知道已经取消了 Bold 样式。
|
3
EXDestroyer 2016-02-19 13:55:45 +08:00
表示 ueditor 也跟知乎一样
|
4
kfll 2016-02-19 13:59:05 +08:00 3
|
5
wangleineo OP 刚刚看了一下 UEditor ,行为和知乎的一样,用了一种很取巧的方法:在步骤 2 的时候,它就把原来的<b></b>分拆成两个,并在中间增加了一个不可见字符节点,<b></b>& 1234 ;<b></b>,这样,接下来插入文字就是在不可见字符的节点上插入的,是没有加粗的。
但是知乎的编辑器不是这样做的。 |
6
morethansean 2016-02-19 14:31:49 +08:00
@wangleineo 我用 Chrome 试了,浏览器本身的行为就是这样。你明明第二次点了 B ,浏览器怎么可能不知道呢?
你随便找个 contenteditable 的输入框,打一串文字按 command/ctrl + b , 然后点一个中间的地方,再按下 command/ctrl + b ,然后打字,不就是你所谓的效果吗?明明按了第二次 B 取消了 bold ,为什么叫浏览器不知道呢?还是我理解有问题? 你要是觉得自己按 bold 和 js 执行的不一样(其实就是一样的),那我给你写了个小 demo : https://jsfiddle.net/cvqzfbb2/ |
7
wangleineo OP |
8
morethansean 2016-02-19 14:41:51 +08:00 1
@wangleineo ……有啊,你看我的 demo
都有哪些命令的话: https://w3c.github.io/editing/execCommand.html editing 相关: https://w3c.github.io/editing/ |
9
wangleineo OP @morethansean 谢谢。
zhihu 就是用 execCommand 实现的 |
10
jsq2627 2016-02-19 15:09:21 +08:00
其实非常简单的
判断当前光标下是否为粗体 document.queryCommandState('bold') 切换当前光标下粗体状态 document.execCommand('bold') |
11
wangleineo OP @morethansean
那这样的话,写一个富文本编辑器不是很简单吗?只要用 execCommand 做命令映射就好了,所有的 DOM 变更操作都由浏览器实现好了。 尝试做这个主要是因为看到这个问题: https://www.zhihu.com/question/26739121 那些说很难做的,到底难度在哪里? |
12
morethansean 2016-02-19 16:50:01 +08:00 via iPhone 1
@wangleineo 看你的富文本编辑器有哪些功能了。如果就是那几个很基本的功能,调调 api 就能实现的那是可能比较简单。
即便如此实际上你做的时候可能遇到各种各样奇怪的 case ,比如从外部复制粘贴过来的时候。还有就是浏览器兼容性问题。 不过不管简单还是难,对最终数据的处理比如过滤什么的也是比较麻烦的。安全性也是很重要的呢。 |
13
wangleineo OP @morethansean 同意。
也有一些编辑器不是完全利用 execCommand 来实现编辑操作的,比如 Medium 的编辑器实现了一个自定义的 Model ,操作是对这个 Model 的修改,然后再把 Model 映射成 DOM 。 https://medium.com/medium-eng/why-contenteditable-is-terrible-122d8a40e480#.8ew1h1af2 W3c 的文档里提到了这篇博客,业界实践也能推动标准。 |
14
jsq2627 2016-02-19 17:35:17 +08:00 1
@wangleineo 浏览器自带的那一套主要问题是不同浏览器有不少小差异,比如剪切板 API 差异,换行处理的差异,键盘事件差异, executeCommand 行为不一致等等,要完全搞清楚这一套还是得看不少源码好好总结的。
DOM 模型针对一个编辑器而言过于复杂了,另外 executeCommand 在不同浏览器行为略有差异,所以有些编辑器搞一个自己的文档模型,这样也好保证各种命令行为一致。 编辑器还有一个难题,是怎么抽象一个可扩展的接口,方便扩充能力。 ckeditor 扩展做得好,生态才比较好,想要什么功能,网上都有插件。 另外还了解过 quill.js ,开发很活跃,代码很清晰。也是自己搞的一套文档模型,很有学习价值。不过这家伙原来用 coffeescript ,一次推翻重来改用 ES6 重写,现在已经不敢在产品里用它了。。 另外推荐 tower.im 出的 simditor ,这个是没有自己的文档模型的,但是已经很成熟了,也在不少产品中有使用( teambition 也是用的它,哈哈)。我们产品上个月刚换它,效果还不错的,也很方便自己扩展。 |
15
minggeJS 2016-02-24 19:50:56 +08:00
我以前写过这种编辑器,就是比较费时间,但是这东西真心不难
|