微信小程序富文本插件(本文档动态更新,建议加星收藏)
- 支持解析
style标签中的全局样式
可以把style标签里的样式匹配到各标签的style中 - 支持自定义默认的标签样式
可以在tag-style属性中设置各标签的默认效果 - 支持自动设置标题
若存在title标签,将自动把title标签的内容设置到页面的标题上 - 支持添加加载提示
可以在Parser标签内添加加载提示或动画,将在未加载完成或内容为空时显示,加载完成后自动隐藏 - 支持动画显示效果
通过设置show-with-animation属性可以实现内容加载完成后渐显的动画效果 - 支持多资源加载
可以在video和audio中设置多个source标签,组件将按顺序进行加载,若前面的链接无法播放,将自动切换下一个链接进行加载和播放,直到最后一个链接;可用于解决平台差异,最大程度避免无法播放 - 支持长按复制内容
通过设置selectable属性可以实现长按复制任意内容 - 智能压缩
可以智能对解析结果进行压缩,包括减小深度、去除无用的空白符等,可以有效提高性能 - 支持丰富的标签
在rich-text组件的基础上,增加支持大量标签,基本覆盖所有常用标签 - 图片显示效果
支持自动按原大小显示,点击图片可以预览(预览时通过左右滑动可以查看所有图片);对于一些装饰性的图片,可以对其设置ignore属性,设置后将无法预览 - 链接点击效果
点击a标签,若href为小程序内部页面路径,将直接跳转;若是网页链接,则可以自动复制链接;链接被点击时会触发bindlinkpress事件,可以在该回调中进行下载附件等更多操作 - 支持解析各类列表
可以显示各类复杂的列表结构 - 支持解析
emoji小表情和动态操作DOM
具体见下方补丁包 - 性能指标
容错性强,稳定性高,不需要网络请求,支持无限层级,解析速度快,包大小仅约37.9KB(min版本27.5KB)
详细可见:功能介绍
-
在需要引用的页面的
json文件中添加{ "usingComponents": { "Parser":"/Parser/index" } } -
在需要引用的页面的
wxml文件中添加<Parser html="{{html}}" />
-
在需要引用的页面的
js文件中添加onLoad:function(){ this.setData({ html:'your html' }) }
demo文件夹下的是示例小程序的源码,可供参考
- 下载
Parser文件夹至static目录下 - 在
src目录下需要使用本插件的页面文件夹下添加json文件{ "usingComponents": { "parser": "../../static/Parser/index" } } - 在需要使用的页面的
vue文件中添加<template> <div class="container"> <parser :html="html"></parser> </div> </template> <script> export default { data: { html: '<div>Hello World!</div>' } } </script>
- 注意: 在
mpvue和uni-app中使用时组件名必须小写
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| html | String/Object/Array | 是 | 要显示的富文本数据,具体格式见下方说明 | |
| tag-style | Object | 否 | 设置标签的默认样式 | |
| autocopy | Boolean | true | 否 | 是否允许链接受到点击时自动复制链接(仅限http开头的网络链接) |
| autopause | Boolean | true | 否 | 是否允许播放视频时自动暂停其他视频 |
| autopreview | Boolean | true | 否 | 是否允许点击图片时自动预览 |
| autosetTitle | Boolean | true | 否 | 是否自动将title标签的内容设置到页面标题上 |
| img-mode | String | default | 否 | 图片显示模式 |
| selectable | Boolean | false | 否 | 是否允许长按复制内容 |
| show-with-animation | Boolean | false | 否 | 是否使用渐显动画 |
| animation-duration | Number | 400 | 否 | 动画持续时间 |
- html格式:
string类型:一个html字符串,例如:<div>Hello World!</div>object类型:一个形如{nodes: [Array], imgList: [Array], title: "String"}的结构体,其中nodes数组的格式基本同rich-text,对于该节点下有img,video,a标签的,需要将continue属性设置为true,否则将直接使用rich-text组件渲染,可能导致图片无法预览,链接无法点击等问题,imgList为其中所有图片地址的数组,title是页面的标题(不必要,传入将会设置到页面的标题上),回调函数bindparser的返回值就是这样的结构体array类型:格式要求同上(用此格式传入预览图片时,将不能通过左右滑动查看所有图片)- 使用b, c方法可以节省解析的时间,提高性能
- 关于img-mode
默认default,在没有设置宽高时,按图片原大小显示;设置了宽或高时,按比例进行缩放;同时设置了宽高时,按设置的宽高进行缩放。在同时设置了宽高的情况下,宽度可能因为max-width:100%的限制而缩短导致图片变形,此时可将模式设置为widthFix,即保持宽度不变,高度自动变化(会导致设置的高度无效) - 关于tag-style
可以设置标签的默认样式,如{ body:"margin:5px" };仅传入的html为String类型时有效(在解析过程中设置)
| 名称 | 功能 | 说明 |
|---|---|---|
| bindparser | 在解析完成时调用(仅当传入的html为String时会调用) |
返回一个object,其中nodes为解析后的节点数组,imgList为图片列表,title是页面标题,该object可以在下次调用直接作为html属性的值,节省解析的时间 |
| bindready | 渲染完成时调用 | 返回整个组件的NodesRef结构体,包含宽度、高度、位置等信息(每次html修改后都会触发) |
| binderror | 出错时调用 | 返回一个object,其中source是错误来源(ad广告出错、video视频加载出错、audio音频加载出错、parse解析过程中出错),errMsg为错误信息,errCode是错误代码(仅ad),target包含出错标签的具体信息 |
| bindimgtap | 在图片受到点击时调用 | 返回该图片的src值,可用于阻挡onShow的调用 |
| bindlinkpress | 在链接受到点击时调用 | 返回该链接的href值,开发者可以在该回调中进行进一步操作,如下载文档和打开等 |
更多信息可见:使用方法
patches文件夹中准备了一些补丁包,可根据需要选用,可以实现更加丰富的功能
- 功能
将形如[笑脸]的文本解析为emoji小表情 - 大小
4.66KB(min版本3.59KB) - 使用方法
将emoji.js复制到Parser文件夹下即可(若使用min版本也要改名为emoji.js)
默认配置中支持176个常用的emoji小表情
支持两种形式的emoji,一是emoji字符(不同设备上显示的样子可能不同),或者是网络图片(将按照16px×16px的大小显示,且不可放大预览),默认配置中都是emoji字符,可使用以下api获取或修改:const parserEmoji = require("path/Parser/emoji.js"); console.log(parserEmoji.getEmoji("笑脸")); //笑脸的emoji字符 parserEmoji.removeEmoji("笑脸"); //移除笑脸emoji parserEmoji.setEmoji("哈哈","https://example.png"); //设置emoji,支持emoji字符或网络图片
-
功能
实现类似于web中的document对象,可以动态操作DOM -
大小
4.75KB(min版本3.69KB) -
使用方法
将document.js复制到Parser文件夹下即可(若使用min版本也要改名为document.js)-
document类
获取方式:可通过this.selectComponent("#id").document获取
Api列表:名称 输入值 返回值 功能 getElementById id element 按照 id查找elementgetChildren i element 获取根节点的第 i个子节点的element实例 -
element类
属性名:名称 功能 id 该节点的id值 nodes 该节点的结构体,可以直接对这个结构体进行修改(修改后需要调用 update方法同步到UI,修改时要注意格式,更建议使用下方的api方法进行修改)Api列表:名称 输入值 返回值 功能 getText text 获取文本内容(仅直接包含文本的标签可用) setText text 修改文本内容(仅直接包含文本的标签可用) addChildren nodes, i 在第 i个位置添加子节点,nodes为一个结构体,格式同rich-textremoveChildren i 移除第 i个子节点getChildren i 获取第 i个子节点的element示例getAttr key attr 获取某个属性值 setAttr key, value 设置某个属性值 getElementById id element 在子节点中按照 id查找elementupdate 若修改了 element.nodes需要调用此方法同步到UI -
返回格式
若执行成功,返回{ok:true, data:...};若不成功,返回{ok:false, errCode:..., errMsg:...}
错误码错误码 含义 1 对没有直接包含 text的标签执行getText或setText2 输入值类型不正确 3 输入值超出范围 4 无法找到对应 id的节点
-
-
注意事项
所有方法必须在html被setData完成后才能调用
每次执行除了get以外的方法都需要进行一次局部的setData更新,请不要过于频繁的调用,否则可能影响性能。 -
综合示例
<Parser id="article" html="{{html}}" binderror="error" />
data:{ html:'...<div id="adContainer"><ad unit-id="..."></ad></div>...' } error(e){ // 广告组件加载出错 if(e.detail.source == "ad"){ // 获取document var document = this.selectComponent("#article").document; // 查找广告框容器 var res = document.getElementById("adContainer"); if (res.ok) res.data.setAttr("style","display:none"); // 隐藏广告容器 else console.error(res.errMsg); // 查找失败 } }
- 背景
在原插件中,由于列表较难通过模拟实现,是直接使用rich-text来显示列表,这导致列表中的图片无法预览,链接无法点击,此补丁包可以解决这个问题 - 功能
模拟ol、ul、li标签
ol标签支持start和type属性;ul标签会自动根据层级显示不同的样式 - 大小
4.22KB - 使用方法
- 将
list文件夹复制到Parser文件夹下 - 将
trees.li.wxml中的内容复制到Parser/trees/trees.wxml中name为element的template中的任意位置 - 在
Parser/trees/handler.wxs中的isContinue函数中进行如下修改// else if(item.name=='a') else if(item.name=='a'||item.name=='li'||item.name=='ol'||item.name=='ul')
- 在
Parser/trees/trees.json中添加"usingComponents": { "trees": "./trees", "ol": "../list/ol", "ul": "../list/ul", "li": "../list/li" }
- 将
Parser/DomHandler.js中trustTag结构体的ol、ul、li属性值改为1
- 可参考
demo文件夹中的Parser(已装载此补丁包)
- 将
- 在其他页面中使用
该包将列表封装成自定义组件,可以直接在其他页面上使用- 在需要使用的页面的
json文件中添加{ "usingComponents": { "ol": "/Parser/list/ol", "ul": "/Parser/list/ul", "li": "/Parser/list/li" } } - 可以直接使用
ol、ul、li标签来显示列表<ol> <li>类型1-1</li> <li>类型1-2</li> </ol> <ol type="A" start="3" style="margin-top:5px;"> <li>类型2-3</li> <li>类型2-4</li> </ol> <ol type="I" start="5" style="margin-top:5px;"> <li>类型3-5</li> <li>类型3-6</li> </ol> <ul style="margin-top:10px"> <li>层级1 <ul> <li>层级2 <ul><li>层级3</li></ul> </li> </ul> </li> </ul>
- 在需要使用的页面的
本插件提供了一个配套的后端node.js支持包,可以提供更加强大的功能,如匹配多层的style,代码高亮,直接打开网址,解析markdown等,其返回值可以直接作为本组件的html属性的值;且在后端提前完成解析后可以节省解析时间,提高性能。
注意:该包需要node.js v7.6.0以上运行环境,无法直接在小程序前端使用,建议部署在服务器或云函数上
安装方法:
npm install parser-wxapp
使用方法:
const parser=require('parser-wxapp');
var html="<div>Hello World!</div>";
parser(html).then(function(res){
console.log(res);
})详细文档参考: npm链接
该插件对rich-text组件进行了二次封装,对于节点下有img, video, a标签的,使用自定义组件递归的方式显示,否则直接通过rich-text组件显示,这样既解决了WxParse中过多的标签数(rich-text可以节省大量的标签),层数容易不够(自定义组件递归可以显示无限层级),无法解析表格,一些组件显示格式不正确(rich-text可以解析出更好的效果)等缺点;也弥补了rich-text图片无法预览,无法显示视频,无法复制链接,部分标签不支持(在解析过程中进行替换)等缺点,另外该解析脚本还减小了包的大小,提高了解析效率,通过包装成一个自定义组件,简单易用且功能强大。
更多可见:《小程序富文本能力的深入研究与应用》
- 2019.9.17:
A增加了list补丁包(可用于模拟列表)Avideo组件增加支持unit-id属性(前插视频广告)F修复了部分情况下图片会被text-indent错误缩进的问题
- 2019.9.15:
A增加了document补丁包(可用于动态操作DOM)A增加支持小程序广告ad组件(可显示文中广告)
- 2019.9.13:
A增加了emoji补丁包(可用于解析小表情)A增加了autopreview属性(可用于控制点击图片时是否自动预览,默认true)和imgtap事件(图片被点击时触发)A提供了一个min版本(27.3KB,功能上无差别)U缩小了节点深度(约15%~35%,主要是通过合并一些只有一个子节点的标签以及优化排版方式),优化了性能U缩小了解析结果的大小(约3%~5%)F修复了解析完成后传入的tagStyle会被修改的问题F修复了存在多张相同url图片时,进行预览会出现定位错误的问题F修复了部分情况下html中的换行符会被显示的问题
- 2019.8.22:
U支持了font标签的size属性
- 2019.8.21:
F修复了部分情况下实体编码内容无法显示的问题
更多可见:更新日志