小程序富文本插件(本文档动态更新,建议加星收藏)
- 支持解析
style
标签中的全局样式
可以把style
标签里的样式匹配到各标签的style
中 - 支持自定义默认的标签样式
可以在tag-style
属性中设置各标签的默认效果 - 支持自动设置标题
若存在title
标签,将自动把title
标签的内容设置到页面的标题上 - 支持添加加载提示
可以在Parser
标签内添加加载提示或动画,将在未加载完成或内容为空时显示,加载完成后自动隐藏 - 支持动画显示效果
通过设置show-with-animation
属性可以实现内容加载完成后渐显的动画效果 - 支持多资源加载
可以在video
和audio
中设置多个source
标签,组件将按顺序进行加载,若前面的链接无法播放,将自动切换下一个链接进行加载和播放,直到最后一个链接;可用于解决平台差异,最大程度避免无法播放 - 支持长按复制内容
通过设置selectable
属性可以实现长按复制任意内容 - 智能压缩
可以智能对解析结果进行压缩,包括减小深度、去除无用的空白符等,可以有效提高性能 - 支持丰富的标签
在rich-text
组件的基础上,增加支持大量标签,基本覆盖所有常用标签 - 图片显示效果
支持自动按原大小显示,点击图片可以预览(预览时通过左右滑动可以查看所有图片);对于一些装饰性的图片,可以对其设置ignore
属性,设置后将无法预览 - 链接点击效果
点击a
标签,若href
为小程序内部页面路径,将直接跳转;若是网页链接,则可以自动复制链接;链接被点击时会触发bindlinkpress
事件,可以在该回调中进行下载附件等更多操作 - 视频效果
支持视频自动懒加载(当视频数量超过3
个时,仅先加载前3
个,避免页面卡死);支持播放一个视频时自动暂停其他视频 - 支持解析各类列表
可以显示各类复杂的列表结构 - 性能指标
容错性强,稳定性高,不需要网络请求,支持无限层级,解析速度快,轻量化
详细可见:功能介绍
名称 | 大小 | 使用 |
---|---|---|
Parser | 39.7KB | 微信小程序插件包 |
Parser.min | 28.3KB | 微信小程序插件包压缩版(功能相同) |
Parser.bd | 36.9KB | 百度小程序插件包 |
Parser.bd.min | 26.7KB | 百度小程序插件包压缩版(功能相同) |
Parser.uni | 48.3KB | uni-app 插件包(可以编译到所有平台) |
- 关于百度版与微信版的差别,可见百度版与微信版的差别
uni-app
版因为各平台rich-text
和自定义组件表现有所不同,有较多条件编译的内容,编译后大小会缩小,关于各平台间的差别和与原生包的差别,可见uni-app
包说明- 可根据需要选用,使用时建议统一更名为
Parser
,以下统称为Parser
- 下载
Parser
文件夹至小程序目录 - 在需要引用的页面的
json
文件中添加(百度小程序中组件名一定要小写){ "usingComponents": { "parser":"/Parser/index" } }
- 在需要引用的页面的
wxml
文件中添加<parser html="{{html}}" />
- 在需要引用的页面的
js
文件中添加data: { html:"<div>Hello World!</div>" }
demo/wx
文件夹下的是微信小程序富文本插件
示例程序的源码,可供参考
- 使用
uni-app
包(可以编译到所有小程序平台)- 下载
Parser.uni
包到components
目录下(更名为Parser
) - 在需要使用页面的
vue
文件中添加<template> <view> <parser :html="html"></parser> </view> </template> <script> import parser from "@/components/Parser/index" export default{ components: { parser }, data() { return { html: '<div>Hello World!</div>' } } </script>
- 可以直接通过插件市场引入:插件市场
demo/uni-app
文件夹下是一个示例程序,可供参考
- 下载
- 使用原生包
参考官网-小程序组件支持
- 下载
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
中使用时组件名必须小写
测试版本:V1.7.3
- 将
Parser
文件夹复制到/src/components
目录下
(也可以直接复制到/dist/components
目录下,这样wepy
不会对插件包进行编译和压缩) - 在需要使用的页面的
wpy
文件中添加<template> <view class="container"> <parser html="{{html}}"></parser> </view> </template> <script> import wepy from 'wepy' export default class Index extends wepy.page { config = { usingComponents: { 'parser': '/components/Parser/index' } } data = { html: '<div>Hello World!</div>', } } </script>
- 通过
wepy build --watch
命令进行编译
- 如果出现
Components not found
错误,则用wepy build --no-cache --watch
命令清理缓存,重新编译
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
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 | 否 | 图片显示模式 |
lazy-load | Boolean | false | 否 | 是否开启图片懒加载 |
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:...} 的结构体(src 是图片链接),可用于阻挡onShow 的调用 |
bindlinkpress | 在链接受到点击时调用 | 返回一个形如{href:...} 的结构体(href 是链接地址),开发者可以在该回调中进行进一步操作,如下载文档和打开等 |
更多信息可见:使用方法
如果需要使用一些固定的样式,可以通过wxss
/ css
文件引入
在/Parser/trees/trees.wxss(css)
中通过@import
引入自定义的样式文件即可
/*
* Parser/trees/trees.wxss(css)
* 在这里引入您的自定义样式
*/
@import "external.wxss(css)";
注意事项:
- 由于只有自定义组件内的样式在组件内能生效且
rich-text
在组件内使用时也只能匹配组件内的样式,所以必须在trees
组件的wxss
/css
文件中引入需要的样式,在页面中写的样式无效 - 组件内只能使用
class
选择器(支持后代选择器),不支持id
选择器、属性选择器、标签名选择器等(更多可见官网说明) - 通过这种方式引入的样式会对所有
parser
标签生效,如果是对单个parser
使用的样式,请使用style
标签
patches
文件夹中准备了一些补丁包,可根据需要选用,可以实现更加丰富的功能
- 功能
将形如[笑脸]
的文本解析为emoji
小表情 - 大小
4.70KB
(min
版本3.61KB
) - 使用方法
将emoji.js
复制到Parser
文件夹下即可(若使用min
版本也要改名为emoji.js
)
默认配置中支持177
个常用的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.66KB
(min
版本3.61KB
) -
使用方法
将document.js
复制到Parser
文件夹下即可(若使用min
版本也要改名为document.js
)-
document
类
获取方式:可通过this.selectComponent("#id").document
获取
Api
列表:名称 输入值 返回值 功能 getElementById id element 按照 id
查找element
getChildren i element 获取根节点的第 i
个子节点的element
实例 -
element
类
属性名:名称 功能 id 该节点的id值 nodes 该节点的结构体,可以直接对这个结构体进行修改(修改后需要调用 update
方法同步到UI
,修改时要注意格式,更建议使用下方的api
方法进行修改)Api
列表:名称 输入值 返回值 功能 getText text 获取文本内容(仅直接包含文本的标签可用) setText text 修改文本内容(仅直接包含文本的标签可用) addChildren nodes, i 在第 i
个位置添加子节点,nodes
为一个结构体,格式同rich-text
removeChildren i 移除第 i
个子节点getChildren i 获取第 i
个子节点的element
示例getAttr key attr 获取某个属性值 setAttr key, value 设置某个属性值 getElementById id element 在子节点中按照 id
查找element
update 若修改了 element.nodes
需要调用此方法同步到UI
-
返回格式
若执行成功,返回{ok:true, data:...}
;若不成功,返回{ok:false, errCode:..., errMsg:...}
错误码错误码 含义 1 对没有直接包含 text
的标签执行getText
或setText
2 输入值类型不正确 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.50KB
- 此补丁包仅能在微信小程序中使用
- 使用方法
- 将
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>
- 在需要使用的页面的
-
功能:支持更多的
css
选择器
原插件包支持的选择器:模式 举例 匹配 按class名匹配 .demo <element class="demo"> 按id名匹配 #demo <element id="demo"> 按标签名匹配 body <body>...</body> 单层多个class .demo1.demo2 <element class="demo1 demo2"> 多个并列 .demo1,.demo2 <element class="demo1">或<element class="demo2"> 使用本补丁包后增加支持的选择器:
模式 匹配的标签 说明 * 所有 通配符 .demo1 .demo2 <element class="demo1">
...
<element class="demo2">后代选择器 .demo1>.demo2 <element class="demo1">
<element class="demo2">子选择器 -
大小(与原大小相比增加)
3.04KB
(min
版本:1.71KB
) -
使用方法
用CssHandler
文件夹下的CssHandler.js
(若使用min
版本也要改名为CssHandler.js
)替换原插件包下的CssHandler.js
即可 -
注意事项
使用该补丁包后会一定程度上减慢解析速度,如非必要不建议使用
更多案例可见(欢迎添加):链接
本插件提供了一个配套的后端node.js
支持包,可以提供更加强大的功能,如匹配多层的style
,代码高亮,直接打开网址,解析markdown
等,其返回值可以直接作为本组件的html
属性的值;且在后端提前完成解析后可以节省解析时间,提高性能。
注意:该包需要node.js v7.6.0以上运行环境,无法直接在小程序前端使用,建议部署在服务器或云函数上
在百度小程序和头条小程序中使用时需要将options
中的setContain
设置为true
安装方法:
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.11.5:
F
修复了uni-app
包编译到APP
时多个连续实体空格失效的问题
- 2019.11.3:
F
修复了uni-app
包编译到H5
时多个行内标签并列会被错误换行的问题 详细
- 2019.11.1:
U
优化了多张相同图片的预览方式
- 2019.10.29:
F
修复了部分行内标签被错误换行的问题
- 2019.10.27:
F
修复了部分情况下多张相同的图片仅第一张可显示的问题
- 2019.10.24:
U
uni-app
包支持在APP
端使用
- 2019.10.17:
A
增加了CssHandler
补丁包(可支持多层的css
选择器)详细U
uni-app
包支持在H5
端使用
- 2019.9.28:
A
增加了lazy-load
属性(可用于图片懒加载)
- 2019.9.25:
A
增加了uni-app
插件包(可以编译到所有小程序平台)详细F
修复了部分情况下样式显示错误的问题
更多可见:更新日志