以下将展示微信小程序之表单组件editor源码官方组件能力,组件样式仅供参考,开发者可根据自身需求定义组件样式,具体属性参数详见小程序开发文档。
功能描述:
富文本编辑器,可以对图片、文字进行编辑。
编辑器导出内容支持带标签的 html和纯文本的 text,编辑器内部采用 delta 格式进行存储。
通过setContents接口设置内容时,解析插入的 html 可能会由于一些非法标签导致解析错误,建议开发者在小程序内使用时通过 delta 进行插入。
富文本组件内部引入了一些基本的样式使得内容可以正确的展示,开发时可以进行覆盖。需要注意的是,在其它组件或环境中使用富文本组件导出的 html 时,需要额外引入 这段样式,并维护的结构。
图片控件仅初始化时设置有效。
相关 api:EditorContext
属性说明:
编辑器内支持部分 HTML 标签和内联样式,不支持class和id
支持的标签
不满足的标签会被忽略,
会被转行为
储存。
支持的内联样式
内联样式仅能设置在行内元素或块级元素上,不能同时设置。例如 font-size 归类为行内元素属性,在 p 标签上设置是无效的。
Bug& Tip
1.tip:使用catchtouchend 绑定事件则不会使编辑器失去焦点(2.8.3)
2.tip:插入的 html 中事件绑定会被移除
3.tip:formats 中的 color 属性会统一以 hex 格式返回
4.tip:粘贴时仅纯文本内容会被拷贝进编辑器
5.tip:插入 html 到编辑器内时,编辑器会删除一些不必要的标签,以保证内容的统一。例如
xxx
会改写为
xxx
6.tip:编辑器聚焦时页面会被上推,系统行为以保证编辑区可见
示例代码:
JAVASCRIPT:
Page({ data: { formats: {}, readOnly: false, placeholder: '开始输入...', editorHeight: 300, keyboardHeight: 0, isIOS: false }, readOnlyChange() { this.setData({ readOnly: !this.data.readOnly }) }, onLoad() { const platform = wx.getSystemInfoSync().platform const isIOS = platform === 'ios' this.setData({ isIOS}) const that = this this.updatePosition(0) let keyboardHeight = 0 wx.onKeyboardHeightChange(res => { if (res.height === keyboardHeight) return const duration = res.height > 0 ? res.duration * 1000 : 0 keyboardHeight = res.height setTimeout(() => { wx.pageScrollTo({ scrollTop: 0, success() { that.updatePosition(keyboardHeight) that.editorCtx.scrollIntoView() } }) }, duration) }) }, updatePosition(keyboardHeight) { const toolbarHeight = 50 const { windowHeight, platform } = wx.getSystemInfoSync() let editorHeight = keyboardHeight > 0 ? (windowHeight - keyboardHeight - toolbarHeight) : windowHeight this.setData({ editorHeight, keyboardHeight }) }, calNavigationBarAndStatusBar() { const systemInfo = wx.getSystemInfoSync() const { statusBarHeight, platform } = systemInfo const isIOS = platform === 'ios' const navigationBarHeight = isIOS ? 44 : 48 return statusBarHeight + navigationBarHeight }, onEditorReady() { const that = this wx.createSelectorQuery().select('#editor').context(function (res) { that.editorCtx = res.context }).exec() }, blur() { this.editorCtx.blur() }, format(e) { let { name, value } = e.target.dataset if (!name) return // console.log('format', name, value) this.editorCtx.format(name, value) }, onStatusChange(e) { const formats = e.detail this.setData({ formats }) }, insertDivider() { this.editorCtx.insertDivider({ success: function () { console.log('insert divider success') } }) }, clear() { this.editorCtx.clear({ success: function (res) { console.log("clear success") } }) }, removeFormat() { this.editorCtx.removeFormat() }, insertDate() { const date = new Date() const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}` this.editorCtx.insertText({ text: formatDate }) }, insertImage() { const that = this wx.chooseImage({ count: 1, success: function (res) { that.editorCtx.insertImage({ src: res.tempFilePaths[0], data: { id: 'abcd', role: 'god' }, width: '80%', success: function () { console.log('insert image success') } }) } }) } })
WXML:
0 ? false : true}}" style="bottom: {{isIOS ? keyboardHeight : 0}}px">
WXSS:
.container { position: absolute; top: 0; left: 0; width: 100%; } .ql-container { box-sizing: border-box; width: 100%; height: 100%; font-size: 16px; line-height: 1.5; overflow: auto; padding: 10px 10px 20px 10px; border: 1px solid #ECECEC; } .ql-active { color: #22C704; } .iconfont { display: inline-block; width: 30px; height: 30px; cursor: pointer; font-size: 20px; } .toolbar { box-sizing: border-box; padding: 0 10px; height: 50px; width: 100%; position: fixed; left: 0; right: 100%; bottom: 0; display: flex; align-items: center; justify-content: space-between; border: 1px solid #ECECEC; border-left: none; border-right: none; }