后浪云百度小程序教程:Editor 富文本编辑器

  • Editor 富文本编辑器
    • 介绍
    • 使用方法
      • 1. 在项目中引用动态库
      • 2. 在使用到富文本编辑器组件的页面配置动态库
      • 3. 编写*.swan文件
    • Editor 组件属性列表
      • 支持的标签
      • 支持的内联样式
    • EditorContext 实例
      • 使用方法
      • EditorContext.blur(Object object)
      • EditorContext.clear(Object object)
      • EditorContext.format(String name, String value)
      • EditorContext.getContents(Object object)
      • EditorContext.getSelectionText(Object object)
      • EditorContext.insertDivider(Object object)
      • EditorContext.insertImage(Object object)
      • EditorContext.insertText(Object object)
      • EditorContext.removeFormat(Object object)
      • EditorContext.setContents(Object object)
      • EditorContext.scrollIntoView()
      • EditorContext.redo(Object object)
      • EditorContext.undo(Object object)
    • 示例
      • 图片示例

    Editor 富文本编辑器

    介绍

    Editor 富文本编辑器动态库提供了支持富文本编辑的editor组件和操作editor组件的createEditorContext方法,通过使用该动态库,用户可以对图片、文本进行编辑。编辑器导出内容支持带标签的html和纯文本的text,编辑器内部采用delta格式进行存储。

    富文本编辑器组件中设置了一些基本样式使得内容可以正确展示,在开发过程中可以进行覆盖,在其他组件或者环境中使用富文本编辑器导出的html时,需要额外维护以下DOM结构:

     
     
     
    1. <ql-container>
    2. <ql-editor></ql-editor>
    3. </ql-container>

    使用方法

    1. 在项目中引用动态库

    参考使用动态库中提供的方法,在app.json中增添一项dynamicLib,与pages同级。

    • JSON
     
     
     
    1. "dynamicLib": {
    2. "editorLib": {
    3. "provider": "swan-editor"
    4. }
    5. },

    2. 在使用到富文本编辑器组件的页面配置动态库

    在每个使用到富文本编辑器组件的页面,配置*.json文件如:

    • JSON
     
     
     
    1. {
    2. "usingSwanComponents": {
    3. "editor": "dynamicLib://editorLib/editor"
    4. }
    5. }

    3. 编写*.swan文件

    • SWAN
     
     
     
    1. <editor
    2. read-only="{{readOnly}}"
    3. placeholder="{{placeholder}}"
    4. />

    这是一种最基本的使用方式,其中readOnlyplaceholder的值可以在*.js文件中设置。

    • JS
     
     
     
    1. Page({
    2. data: {
    3. readOnly: false,
    4. placeholder: '请输入...'
    5. }
    6. });

    Editor 组件属性列表

    属性 类型 默认值 必填 说明
    read-only Boolean false 设置编辑器为只读
    placeholder String 编辑器提示信息
    show-img-size Boolean false 点击图片时显示图片大小控件
    show-img-resize Boolean false 点击图片时显示图片缩放控件
    show-img-toolbar Boolean false 点击图片时显示图片工具栏控件
    bindready EventHandle 编辑器初始化完成时触发
    bindfocus EventHandle 编辑器聚焦时触发,event.detail = { html, text, delta }
    bindblur EventHandle 编辑器失去焦点时触发,event.detail = { html, text, delta }
    bindinput EventHandle 编辑器内容改变时触发,event.detail = { html, text, delta }
    bindstatuschange EventHandle 编辑器内容或样式通过EditorContext中的方法改变时触发,返回选区已设置的样式

    编辑器内支持部分HTML标签和内联样式,但不支持classid

    支持的标签

    不满足的标签会被忽略,div标签会被转换为p标签存储。

    类型 节点
    行内元素 <span><strong> <b> <em> <i> <u> <a> <s> <sub> <sup> <img>
    块级元素 <br> <hr> <ol> <ul> <li> <h1> <h2> <h3> <h4> <h5> <h6>

    支持的内联样式

    内联样式仅支持设置在行内元素或块级元素上,不能同时设置,如text-align归类为块级样式,在span标签上设置是无效的。

    类型 样式
    块级样式 text-align、direction
    行内样式 color、background-color

    EditorContext 实例

    Editor 富文本编辑器动态库提供了createEditorContext的方法来获取某个editor组件的实例,EditorContext通过id和一个editor组件绑定,操作对应的editor组件。

    使用方法

    • JS
     
     
     
    1. Page({
    2. onEditorReady() {
    3. this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editorId');
    4. }
    5. });

    EditorContext.blur(Object object)

    解释:编辑器失焦。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.clear(Object object)

    解释:清空编辑器内容。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.format(String name, String value)

    解释:修改格式。

    对已经应用样式的选区设置会取消样式。

    参数

    String name:属性

    String value:值

    支持设置的样式列表

    name value
    bold
    italic
    underline
    strike
    ins
    script sub / super
    header H1 / H2 / H3 / H4 / H5 / H6
    align center / right / justify
    direction rtl
    indent -1 / +1
    list ordered / bullet / check
    color hex color
    backgroudColor hex color

    EditorContext.getContents(Object object)

    解释:获取编辑器内容。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    object.success 回调函数

    参数:Object res

    属性 类型 说明
    html String 带标签的html内容
    text String 纯文本内容
    delta Object 描述内容的delta对象

    EditorContext.getSelectionText(Object object)

    解释:获取编辑器内选区的纯文本内容。当编辑器失焦或未选中一段区间时,返回内容为空。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    object.success 回调函数

    参数:Object res

    属性 类型 说明
    text String 纯文本内容

    EditorContext.insertDivider(Object object)

    解释:插入分隔符。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.insertImage(Object object)

    解释:插入图片。

    参数:Object object

    属性 类型 默认值 必填 说明
    src String 图片地址,目前仅支持 http(s)、base64、本地图片
    alt String 图片无法显示时的替代文本
    extClass String 添加到图片 img 标签上的类名
    data Object data 会被序列化为name1=value1&name2=value2的格式挂在属性 data-custom 上
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.insertText(Object object)

    解释:覆盖当前选区,设置一段文本。

    参数:Object object

    属性 类型 默认值 必填 说明
    text String 文本内容
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.removeFormat(Object object)

    解释:清除当前选区的样式。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.setContents(Object object)

    解释:初始化编辑器内容,htmldelta同时存在时仅delta生效。

    需要注意的是,通过setContents设置编辑器内容时,由于支持的html标签和内联样式有限,建议开发者在小程序内通过delta进行插入。

    参数:Object object

    属性 类型 默认值 必填 说明
    html String 带标签的html内容
    delta Object 描述内容的delta对象
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.scrollIntoView()

    解释:将编辑器光标处滚动到窗口可视区域内。

    EditorContext.redo(Object object)

    解释:恢复。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    EditorContext.undo(Object object)

    解释:撤销。

    参数:Object object

    属性 类型 默认值 必填 说明
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    示例

    在开发者工具中打开

    在开发者工具中打开

    在 WEB IDE 中打开

    扫码体验

    代码示例

    后浪云百度小程序教程:Editor 富文本编辑器插图

    请使用百度APP扫码

    图片示例

    后浪云百度小程序教程:Editor 富文本编辑器插图1

    • SWAN
    • JS
    • CSS
     
     
     
    1. <view class="toolbar" catchtouchend="format">
    2. <view class="iconfont icon-image" catchtouchend="insertImage"></view>
    3. <view class="iconfont icon-format-header-1 {{formats.header === 1 ? 'ql-active' : ''}}" data-name="header" data-value={{1}}></view>
    4. <view class="iconfont icon-format-header-2 {{formats.header === 2 ? 'ql-active' : ''}}" data-name="header" data-value={{2}}></view>
    5. <view class="iconfont icon-format-bold {{formats.bold ? 'ql-active' : ''}}" data-name="bold"></view>
    6. <view class="iconfont icon-format-italic {{formats.italic ? 'ql-active' : ''}}" data-name="italic"></view>
    7. <view class="iconfont icon-format-list {{formats.list === 'checked' ? 'ql-active' : ''}}" data-name="list" data-value="checked"></view>
    8. <view class="iconfont icon-divider" catchtouchend="insertDivider"></view>
    9. <view class="iconfont icon-clear" catchtouchend="clear"></view>
    10. </view>
    11. <view class="editor-wrap">
    12. <editor
    13. id="editorId"
    14. class="editor"
    15. placeholder="开始输入..."
    16. bindready="onEditorReady"
    17. bindstatuschange="onStatusChange"
    18. show-img-size
    19. show-img-resize
    20. show-img-toolbar
    21. />
    22. </view>
     
     
     
    1. const INIT_CONTENT_HTML = `
    2. <p>支持插入图片</p>
    3. <br>
    4. <p>
    5. <img src="https://b.bdstatic.com/searchbox/icms/searchbox/img/editor-image-demo.png" data-custom="id=abcd&amp;role=god" alt="image-alt" class="imageCls" width="100%">
    6. </p>
    7. <hr>
    8. <p>支持以下字符样式</p>
    9. <p>
    10. <b>bold粗体</b>
    11. <em>italic斜体</em>
    12. <u>underline下划线</u>
    13. </p>
    14. <p>
    15. <sub>sub下标</sub>
    16. <sup>super上标</sup>
    17. </p>
    18. <hr>
    19. <p>支持以下列表样式</p>
    20. <ol>
    21. <li>有序列表</li>
    22. <li>有序列表</li>
    23. </ol>
    24. <ul>
    25. <li>无序列表</li>
    26. </ul>
    27. <ul>
    28. <li>无序列表</li>
    29. </ul>
    30. <ul data-checked="true">
    31. <li>选框列表</li>
    32. </ul>
    33. <ul data-checked="false">
    34. <li>选框列表</li>
    35. </ul>
    36. <hr>
    37. <p>支持以下字符大小</p>
    38. <h1>H1 一级标题</h1>
    39. <h2>H2 二级标题</h2>
    40. <h3>H3 三级标题</h3>
    41. <h4>H4 四级标题</h4>
    42. <h5>H5 五级标题</h5>
    43. <h6>H6 六级标题</h6>
    44. <hr>
    45. <p>支持以下对齐方式</p>
    46. <p style="text-align:center">center中间对齐</p>
    47. <p style="text-align:right">right 右对齐</p>
    48. <p style="text-align:justify">justify 自动对齐</p>
    49. <hr>
    50. <span style="color:#00bc89;background-color:#333">color 支持设置字体及背景颜色</span>`;
    51. Page({
    52. data: {
    53. formats: {}
    54. },
    55. // 编辑器初始化完成时触发的事件,用于加载编辑器初始内容
    56. onEditorReady() {
    57. this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editorId');
    58. this.initContent();
    59. },
    60. // 设置编辑器初始内容
    61. initContent() {
    62. this.editorCtx.setContents({
    63. html: INIT_CONTENT_HTML
    64. });
    65. },
    66. // 编辑器内插入图片函数
    67. insertImage() {
    68. const editorCtx = this.editorCtx;
    69. swan.chooseImage({
    70. count: 1,
    71. success: res => {
    72. editorCtx.insertImage({
    73. src: res.tempFilePaths[0],
    74. alt: '插入图片',
    75. data: {
    76. id: 'insert-image',
    77. role: 'user'
    78. },
    79. success: () => {
    80. swan.showToast({
    81. title: '插入图片成功'
    82. });
    83. },
    84. fail: err => {
    85. swan.showToast({
    86. title: '插入图片失败',
    87. icon: 'none'
    88. });
    89. }
    90. });
    91. }
    92. });
    93. },
    94. /**
    95. * 更改编辑器选区为不同格式
    96. *
    97. * @param {Object} e.target.dataset 获取 swan 页面的传参:name、value
    98. *
    99. */
    100. format(e) {
    101. const {name, value} = e.target.dataset;
    102. if (!name) {
    103. return;
    104. }
    105. this.editorCtx.format(name, value);
    106. },
    107. /**
    108. * 编辑器内容或样式通过方法改变时触发的事件,返回选区已设置的样式
    109. *
    110. * @param {Object} e.detail 事件对象
    111. *
    112. */
    113. onStatusChange(e) {
    114. const formats = e.detail;
    115. this.setData({
    116. formats
    117. });
    118. },
    119. // 编辑器中插入分隔符
    120. insertDivider() {
    121. this.editorCtx.insertDivider();
    122. },
    123. // 清除编辑器中内容,与工具栏的垃圾桶图标对应
    124. clear() {
    125. const editorCtx = this.editorCtx;
    126. swan.showModal({
    127. title: '清空编辑器',
    128. content: '确定清空编辑器全部内容?',
    129. success: res => {
    130. if (res.confirm) {
    131. editorCtx.clear();
    132. }
    133. }
    134. });
    135. }
    136. });
     
     
     
    1. @font-face {
    2. font-family: "iconfont"; /* project id 2000141 */
    3. src: url(http://at.alicdn.com/t/font_2000141_vma36b09h9.wof) format("woff"),
    4. url(http://at.alicdn.com/t/font_2000141_vma36b09h9.ttf) format("truetype"),
    5. url(http://at.alicdn.com/t/font_2000141_vma36b09h9.svg#iconfont) format("svg");
    6. }
    7. .iconfont {
    8. display: inline-block;
    9. font-size: 22px;
    10. width: 30px;
    11. height: 30px;
    12. font-family: "iconfont" !important;
    13. font-style: normal;
    14. -webkit-font-smoothing: antialiased;
    15. -moz-osx-font-smoothing: grayscale;
    16. }
    17. .icon-image:before {
    18. content: "\e60e";
    19. }
    20. .icon-format-header-1:before {
    21. content: "\e610";
    22. }
    23. .icon-format-header-2:before {
    24. content: "\e60f";
    25. }
    26. .icon-format-bold:before {
    27. content: "\e60a";
    28. }
    29. .icon-format-list:before {
    30. content: "\e60b";
    31. }
    32. .icon-divider:before {
    33. content: "\e609";
    34. }
    35. .icon-clear:before {
    36. content: "\e60c";
    37. }
    38. .icon-format-italic:before {
    39. content: "\e60d";
    40. }
    41. .editor-wrap {
    42. width: 100%;
    43. height: 100vh;
    44. }
    45. .editor {
    46. display: block;
    47. box-sizing: border-box;
    48. width: 100%;
    49. height: 100%;
    50. margin-top: 50px;
    51. padding: 38.043rpx 30.797rpx;
    52. }
    53. swan-editor {
    54. display: block;
    55. }
    56. .ql-editor {
    57. height: 100%;
    58. }
    59. .toolbar {
    60. position: fixed;
    61. box-sizing: border-box;
    62. padding: 17px 17px;
    63. width: 100%;
    64. height: 45px;
    65. top: 30;
    66. left: 0;
    67. border-top: .906rpx solid #e6e6e6;
    68. border-bottom: .906rpx solid #e6e6e6;
    69. display: flex;
    70. align-items: center;
    71. justify-content: space-between;
    72. background-color: #fff;
    73. z-index: 99;
    74. }
    75. .ql-active {
    76. color: #3388ff;
    77. }
    THE END