运营同事在微信公众号发布文章时,经常按照如下步骤操做:html
打开“秀米”网 =》 挑选模版 =》 编辑好内容 =》 一键复制代码vue
打开微信公众平台 =》 新建文章 =》 粘贴到编辑器里 =》 确认发布react
紧接着,这个工做多了一块内容 —— 把内容同步到某个产品的触屏网站中。jquery
因为当下尚未资源开发一款相似“秀米”的产品,最终决定在以前的基础上增长以下步骤:git
打开触屏网站的内容管理平台 =》 新建文章 =》 粘贴到编辑器里 =》 确认发布github
本来觉得只是像在微信公众平台同样,在富文本编辑器里粘贴便可,过程当中却发现粘贴后部分样式和标签丢失微信
内容管理平台中基于 Vue.js 开发,富文本编辑器使用的是 Quill。微信公众平台
而 Quill 简洁易用的优势,现在成了它的缺点 —— 它只保留特定的标签和样式,且没有可供修改的配置。less
因而,决定选型其它富文本编辑器。编辑器
默认配置下和 Quill 问题同样,而 Simditor 能够经过配置来添加所需标签和样式。但有以下问题:
标签须要手动一个个加进去,而样式则须要针对每一个标签分别添加。这种方案过程太费劲、容易遗漏
github 上大约是 2-3 年前的更新
依赖 jquery 实现
记得它早期版本依赖 jquery,在 github 上粗看了最新的代码,3天前还在更新,已经无依赖,但兼容性要求 ie10 +。
注意到一个惊喜之处,他配套了 vue 和 react 相关的组件。
惋惜的是,它的问题和 Quill 同样 —— 无法配置。
一些早期版本的富文本编辑器,基本上没有对标签和样式的限制,但缺乏工程化支持
考虑到,无非是粘贴这么一个简单的需求,并且由于是内部系统,兼容性不是太大问题。
那么,何苦费劲用功能那么复杂的编辑器呢。
能够经过事件对象来访问黏贴板
event.clipboardData.getData('text/html')
MDN 上对 getData(format) 的惟一必填参数 format
的解释,有点难理解
A DOMString representing the type of data to retrieve.
经过网上的一些例子,取值范围大概能够认为等价于 MIME ,还包括 'Text'
、null
其实,解决了黏贴的问题,已经能够告一段落了。
恰巧这时候查到了 contenteditable
相关资料,发现就是一个活脱脱的原生富文本编辑器。
<template> <div class="ui-editor" contenteditable="true" @paste="paste" @input="input"></div> </template> <script> export default { props: { value: String }, data() { return { html: '' } }, methods: { paste(e) { e.preventDefault() const html = e.clipboardData.getData('text/html') document.execCommand('insertHTML', false, html) this.input() }, input() { const v = this.$el.innerHTML this.html = v this.$emit('input', v) } }, watch: { value(v) { if (v !== this.html) { this.$el.innerHTML = v } } }, mounted() { const v = this.value if (v) { this.$el.innerHTML = v this.html = v } } } </script> <style lang="less"> .ui-editor { margin: 10px auto; width: 374px; min-height: 300px; padding: 0 15px; box-shadow: inset 0 0 12px rgba(63, 70, 82, 0.5); background-color: #fff; overflow: hidden; user-select: all; &:hover { outline: 1px solid red; } } </style>
例子
<template> <uEditor v-model="content" /> </template> <script> import uEditor from './editor.vue' export default { components: { uEditor }, data() { return { content:'' } } } </script>