Code Monkey home page Code Monkey logo

wxparse's Introduction

wxParse —— 微信小程序富文本解析

原因

由于原作者仓库 wxParse 不再维护,我们项目中商品信息展示又是以wxParse这个用做富文本解析的;

于是乎,决定采用 递归Component 的方式对其进行重构一番;

原项目使用的 template 模板的方式渲染节点,存在以下问题:

  1. 节点渲染支持到12层,超出会原样输出 html 代码;

  2. 每一层级的循环模板都重复了一遍所有的可解析标签,代码十分臃肿。

  3. li 标签不支持 ol 有序列表渲染(统一采用的是 ul 无序列表),a标签无法实现跳转,也无法获取点击事件回调等等;

  4. 节点渲染没有绑定 key 值,一是在开发工具看到一堆的 warning信息(看着十分难受),二是节点频繁删除添加,无法比较key值,造成 dom 节点频繁操作。

功能标签

目前该项目已经可以支持以下标签的渲染:

  • audio标签(可自行更换组件样式,暂时采用微信公众号文章的audio音乐播放器的样式处理)【扩展组件】
  • code标签 【扩展组件】
  • video标签
  • table标签
  • ul标签
  • ol标签
  • li标签
  • a标签
  • img标签
  • video标签
  • br标签
  • button标签
  • h1, h2, h3, h4标签
  • 文本节点
  • hr标签
  • 其余块级标签
  • 其余行级标签

使用

1. 原生组件使用方法

  • 克隆 项目 代码,把 dist目录下的wxParse目录 拷贝到你的小程序组件目录下面;

  • 在你的 page页面 对应的 json 文件引入 wxParse 组件

{
  "usingComponents": {
    "wxParse": "/components/wxParse/wxParse"
  }
}
  • 组件调用
<wxParse nodes="{{ htmlText }}" />

2. npm组件使用方法

  • 安装组件
npm install --save wx-minicomponent
  • 小程序开发工具的 工具 栏找到 构建npm,点击构建;

  • 在页面的 json 配置文件中添加 wxParse 自定义组件的配置

{
  "usingComponents": {
    "wxParse": "/miniprogram_npm/wx-minicomponent/wxParse"
  }
}
  • wxml 文件中引用 wxParse
<wxParse nodes="{{ htmlText }}" />

组件扩展

基础的富文本组件只支持基础的标签解析,出于小程序包体积考虑,读者可以根据需要按需引入组件,打包构建。

名称 功能 构建命令
wxAudio 音频播放器 npm run pack:wxAudio
highLight 代码块高亮显示 npm run pack:highLight

使用方法:

  1. 需要引入音频播放器组件,执行命令:
npm run pack:wxAudio
  1. 执行构建压缩命令,打包到 dist 目录下:
npm run build
  1. 将dist目录下的wxParse目录wxAudio目录克隆到你的项目组件目录,正常引入wxParse组件即可。

参数文档

wxParse:富文本解析组件

参数 说明 类型 例子
nodes 富文本字符 String "<div>test</div>"
language 语言 String 可选:"html" | "markdown" ("md")

标签使用说明补充:

  1. a 标签的内外链跳转根据的是 http 字符判断;

  2. a 标签的跳转顺序为:

  • 如果page页面有定义 handleTagATap 方法,优先执行该方法

  • 如果page页面没有定义 handleTagATap 方法,将根据 a标签href 字段判断采用内外链跳转方式,外链跳转需要在 app.json 文件中新增 自定义webview 页面配置,如下所示:

webview页面配置:

  1. 原生webview页面配置:
// app.json
{
  "pages" [
    "components/wxParse/webviewPage/webviewPage"
  ]
}
  1. npm 包webview配置:
// app.json
{
  "pages" [
    "miniprogram_npm/wx-minicomponent/wxParse/webviewPage/webviewPage"
  ]
}
  1. code 标签代码高亮:
  • code 标签添加 lang属性,默认值是javascript ;支持 javascript|typescript|css|xml|sql|markdown|c++|c 可选值

  • 支持高亮解析结构如下:

<pre>
<code lang="javascript">
  const name = 'csonchen'
</code>
</pre>

受信任的节点

节点 例子
audio <audio title="我是标题" desc="我是小标题" src="https://media.lycheer.net/lecture/25840237/5026279_1509614610000.mp3?0.1" />
a <a href="https://www.baidu.com"> 跳转到百度 </a>
<a href="/pages/highLightPage/highLightPage"> 站内跳转 </a>
code <code lang="javascript"> const name = "csonchen"; </code>
p
div
span
li
ul
ol
img
button
hr
h1
h2
h3
h4
table
tr
th
td
....

highLight:代码高亮解析组件

参数 说明 类型 例子
codeText 原始高亮代码字符 String "var num = 10;"
language 代码语言类型 String 可选值:"javascript/typescript/css/xml/sql/markdown/c++/c"

提示:如果是html语言,language的值为xml

wxAudio:仿微信公众号文章音频播放组件

参数 说明 类型 例子
title 标题 String "test"
desc 副标题 String "sub test"
src 音频地址 String

示例展示

  1. 富文本解析
  • html文本解析实例

  • markdown文本解析实例

  1. 代码高亮(highLight组件)

更新历史

  • 2021-5-17:featwxAudio音频播放器highLight代码块高亮组件抽离出来作为扩展组件,可根据需要自行构建打包

  • 2021-3-26: feat 修复图片二次请求加载的bug,优化图片懒加载 + 展示渐变动画

  • 2021-2-6: fix 修复单层元素(如:img标签)渲染时候获取不到组件实例唯一id,导致大图预览失败的bug

  • 2021-1-19:

  1. fix 修复 page页面wxParse组件 实例绑定唯一性的bug

  2. feat 新增 hr标签解析实现

  • 2020-12-10:fix 修复页面跳转之后图片预览大图失效的bug

  • 2020-12-8: feat 新增 code 标签的代码高亮功能,并修复解析语言注册失败的bug

  • 2020-12-7:fix 修复 code 标签解析错误以及换行符被替换成空字符的bug

  • 2020-8-17:feat 增加设置image标签的width,height属性以及内联样式属性设置

  • 2020-8-10: feat 文本节点添加选中复制功能

  • 2020-8-6:fix table,tr,td等相关元素标签去掉style样式内嵌,避免表格样式错乱问题

  • 2020-8-5: feat 新增支持a标签的内外链跳转功能,并支持page页面点击方法回调控制

  • 2020-6-18:fix 修复table渲染错位和image图片在个别情况无法预览的问题

  • 2020-5-31: reflator

  1. 迁移utils目录到wxParse目录下;

  2. 富文本增加markdown文本解析支持;

  • 2020-5-21: reflator 富文本组件image标签添加loading过渡态,优化图片加载体验

  • 2020-5-17: doc 完善组件参数文档,增加wxParse对audio标签标题,副标题的解析功能

  • 2020-5-13: feat 增加css,html,ts,sql,markdown代码高亮提示支持

  • 2020-5-6:feat 增加图片预览功能

TODO

  • 图片占位图优化,优化 image标签加载,避免出现一闪而过,优化加载体验;
  • 编写插件,小程序可以通过插件方式引入;
  • 支持 template 方式渲染(因为递归组件会引入组件生命周期,节点过多可能对性能有影响);
  • 尽可能多的修复原 wxParse 项目中的 issue
  • ....

wxparse's People

Contributors

csonchen avatar dafrok avatar dependabot[bot] avatar vito-97 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

wxparse's Issues

audio 标签可以解析,但无法播放

audio 标签可以解析,但无法播放,且音频文件时间和标题描述均显示不正确。

HTML 富文本内容:

<audio title="标题" desc="描述" src="https://media.lycheer.net/lecture/25840237/5026279_1509614610000.mp3?0.1"></audio>

wxml

<wxAudio class="content" nodes="{{post.content}}" />

模拟器预览:
image

重新设置html后图片一直会显示loading状态

大佬, 代码如下:

const Page: FC = () => {
    const html = `
        <h2 style="color: red;">文章标题</h2>
        <main>
            <article>文章内容</article>
            <img src="https://storage.360buyimg.com/cjj-pub-images/taro-daily.jpeg" alt="图片" width="100%" height="auto" />
            <p>这是很长一段文字</p>
        </main>
    `
    const [htmlText, setHtmlText] = useState(html)
    const handleClick = () => {
        setHtmlText(html + `<footer>这里是页脚</footer>`)
    }
return (
        <View>
            <View>我的</View>
            <View>
                <wxParse nodes={htmlText} />
            </View>
            <Button type='primary' onClick={handleClick}>改变html</Button>
        </View>
    )
}
export default Page

当我点击按钮改变html的时候,图片一直会显示loading状态而不显示出图片来,麻烦看下这个bug呢?开源不易 ,万分感谢!

楼主:项目正在维护中,请各位提issue的时候可以发一下有问题的html富文本代码片段

由于原项目不再维护了,我这边重新对原来项目进行自定义Component重构,因为子组件标签外层会预先套上一层wxParse的父标签,造成个别css样式出现错乱,希望大家可以共同努力,一起维护下去。

这里我大概列举一下提issue流程:

  1. 粘贴出现问题的html富文本
  2. 提供最小范例的代码片段链接,我这边可以直接打开去复现

以上二者材料最好可以一起提供,这样我可以快速定位到问题,及时帮助到大家。谢谢了

audio标签渲染不出来

html代码如下:

<audio title="我是标题" src="https://media.lycheer.net/lecture/25840237/5026279_1509614610000.mp3?0.1" /> <audio poster="https://blog-1258875084.cos.ap-guangzhou.myqcloud.com/uTools_1628491972234_1628492318488.png" name="Cheap Dream" author="EnMoon1" src="https://blog-1258875084.cos.ap-guangzhou.myqcloud.com/EnMoon1%E5%B0%B9%E6%85%95%E6%81%A9-Cheap%20Dream_1628696767455.mp3" id="myAudio" controls loop> </audio> 这场名利游戏压了多少赌注

audio标签依然用不了

已经把diat目录下的三个包拷贝到了项目coments目录下,引入了,audio标签不行,解析不出来

图片加载的问题

小程序在图片加载时候一直转圈无法加载出来。后台监控的报错代码如下:

undefined is not an object (evaluating 'o.templateInfo.templateId')
at (WASubContext.js:2:811970)
at E (WASubContext.js:2:67251)
at f (WASubContext.js:2:811802)
at (WASubContext.js:2:491432)
at E (WASubContext.js:2:67251)
at (WASubContext.js:2:491368)
at (WASubContext.js:2:785733)
at (WASubContext.js:2:524041)
at (WASubContext.js:2:1765190)
at (WASubContext.js:2:1765320)
at s (WASubContext.js:2:110706)
at (WASubContext.js:2:111168)
at (app-service.js:7325:1573)
at success (app-service.js:7103:1412)
at (WASubContext.js:2:1764555)
at w (WASubContext.js:2:783889)
at success (WASubContext.js:2:786045)
at h (WASubContext.js:2:111445)
at (WASubContext.js:2:112266)
at A (WASubContext.js:2:459731)
at (WASubContext.js:2:662668)
at h (WASubContext.js:2:111445)
at (WASubContext.js:2:112266)
at (WASubContext.js:2:625145)
at forEach (native code)
at value (WASubContext.js:2:625118)
at R (WASubContext.js:2:663650)
at (WASubContext.js:2:664996)
at (WASubContext.js:2:490212)
at (WAServiceMainContext.js:2:254859)
at _ (WAServiceMainContext.js:2:78159)
global code

000

能解析多大的富文本?

我原生写的小程序,现在后台上传五花八门编辑好的页面,有的4-6M,要么解析不处理,要么卡半天,,我用的richtext,不知道这个目前可以解析多大的文件(很多背景动画解析不出来,这个问题不知道会是否存在)

bindData函数的问题

const bindData = (() => { let instance = null return function(bindName, data) { if (!instance) { instance = { [bindName]: data } }else if(data){ instance[bindName] = data; } return instance[bindName] } })();
解决了该函数不会进行数据更新,导致图片预览失败

微信公众号文章无法识别

你好,我们获得了微信公众号的html富文本,但是在检查了标签确实是闭合的情况下,依然无法解析显示
d8c120c3f76d6d625c84967e42b790e

下面是html的代码
[https://paste.ubuntu.com/p/7jNnc7hfDd/]

谢谢大佬!!

关于图片

你好,我看到图片默认是先加载一次,然后占位,这个过程不是已经占用资源了吗,能否优化一下

无法获取到图片标签上的宽高,而使用了图片源的宽高

例如一张图片解析前是<img src="xxxxx" alt="" width="200" height="100">这样,但在实际解析的时候是直接去获取图片源的宽高,然后使用那个宽高,无视了标签上的宽高,导致在富文本编辑器中修改图片大小没反应,这个问题是否能改善

汉字与字符串连接时换行问题

如果汉字与字母相连如:测试文字XXXXXXXXXXXXXXXXXXXXXX,在需要换行时会发生字母整体换行
image

需要自行增加css wxParse text{ word-break: break-all; }解决

图片加载2次的问题

第一次加载进入页面的时候, 所有图片会加载一次
当下滑的时候, 图片又会重新再加载一次
有办法设置为懒加载吗

表格渲染出多边框和显示不全的问题 附html源码

源码放在了Ubuntu Paste上(只放了表格片段,其他片段效果很好:D ):

直接渲染效果如图,太长了无法显示完全
image

起初以为是宽度过大导致的,然后修改了总宽度为260之后如图(是不是因为居中的问题?):
image

上面放的源码是修改了宽度为260之后的。

因为是直接爬取的学校网站的页面,所以样式设置的会比较复杂。
如果是源码的问题的话可以指导一下怎么处理源码比较好吗?谢谢大佬。

祝好。

请问富文本和代码高亮如何同时实现.

大佬是这么回事.

我自己做了一个自己博客的小程序.
源是HTML,内部有多个代码示例.(能实现高亮最好).

pc页面如下
QQ截图20201120205438

小程序用了解析之后,一般标签没问题.
主要是标签这块 .

问题1, \r\n不解析,丢失.

QQ截图20201120205542

HTML代码片段, 实际渲染的时候,好像所有的标签内的 \r\n都没有渲染.(其他标签的没注意)
而实际上页面有\r\n

\/\/C++11\r\n\r\ntemplate....

问题2,

也就是我HTML中有多个code标签.
数量是不固定的.
好像按你代码高亮DEMO只能一个一个添加....
请问有没有自动安排的套路?

问题3,

内链替换问题.

本身我博文就有一些内链互相引用.
比如html
<a href="../../show/73.html" target="_blank" rel="noopener">链接</a>
这种链接没办法解析.即使带自己域名全链接,也没办法打开,因为个人小程序没有打开web页面的权限.

小程序博文显示页路径 pages/detail/detail?id=128
web链接 www.abc.com/show/128.html
实际就是一个ID替换.
这个我自己先研究下,应该可以api返回的时候替换处理掉.


下面是api返回完整的json.

{"code":1,"msg":"ok","data":{"info":{"id":128,"type":"","title":"C\/C++ 获取std::string [] 可变数组元素个数","cate_id":16,"keyword":null,"intro":"百度了一圈啥玩意都没找到,还是谷歌靠谱.","avatar":"","content":"<p>像std::string数组用sizeof并不太准确.百度找了一大圈,没有好办法.还是靠谷歌.<\/p>\r\n<p>&nbsp;<\/p>\r\n<blockquote>\r\n<p>std::string&nbsp; abc [] = {\"test\",\"test2\",\"test3\",\"test4\"};<\/p>\r\n<\/blockquote>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<h2>用宏求<\/h2>\r\n<p>&nbsp;<\/p>\r\n<pre class=\"language-c\"><code>\/\/C++11\r\n\r\ntemplate &lt; typename T, std::size_t N &gt;\r\nconstexpr std::size_t size( T(&amp;)[N] ) { return N ; }\r\n\r\n\r\nstd::cout &lt;&lt; \"array 'abc' size: \" &lt;&lt; size(abc) &lt;&lt; ' ' ;<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<h2>用std::end求<\/h2>\r\n<p>&nbsp;<\/p>\r\n<pre class=\"language-c\"><code>\/\/C++11\r\n\r\n\r\nstd::cout &lt;&lt; std::end(abc) - std::begin(abc) &lt;&lt; ' ' ;<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<h2>通过维度计算<\/h2>\r\n<p>&nbsp;<\/p>\r\n<pre class=\"language-c\"><code>\/\/C++11\r\n\r\n\r\nstd::cout &lt;&lt; std::extent&lt; decltype(abc) &gt;::value &lt;&lt; ' ' ;\r\n<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<h2>向量类型计算<\/h2>\r\n<p>&nbsp;<\/p>\r\n<p>这个我也没搞懂.先贴出来.<\/p>\r\n<p>&nbsp;<\/p>\r\n<pre class=\"language-c\"><code>\/\/ C++11 \r\n\r\n\r\n#include &lt;vector&gt;\r\n#include &lt;string&gt;\r\n\r\nstd::vector vs {\"a\", \"be\", \"see\"}; \r\nstd::size_t length = vs.size();<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<h2>for枚举<\/h2>\r\n<p>&nbsp;<\/p>\r\n<p>当然,效率不高.<\/p>\r\n<p>这个可以在for内直接枚举.<\/p>\r\n<p>&nbsp;<\/p>\r\n<pre class=\"language-c\"><code>\/\/c++ 11\r\n\r\nint count = 0;\r\n\r\nfor (auto v : abc)\r\n{\r\n        \r\n        \/\/直接用 v 参与计算,这里 v等价于 abc[count];\r\n\r\n        \/\/先干其他的.再累加.\r\n        count++;\r\n         \r\n}<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n<h2>参考<\/h2>\r\n<p>&nbsp;<\/p>\r\n<p><a href=\"http:\/\/www.cplusplus.com\/forum\/general\/110091\/\" target=\"_blank\" rel=\"noopener\">http:\/\/www.cplusplus.com\/forum\/general\/110091\/#<\/a><\/p>\r\n<p><a href=\"https:\/\/blog.csdn.net\/u010196624\/article\/details\/90085547\" target=\"_blank\" rel=\"noopener\">https:\/\/blog.csdn.net\/u010196624\/article\/details\/90085547<\/a><\/p>\r\n<p><a href=\"https:\/\/www.cnblogs.com\/developing\/articles\/10890903.html\" target=\"_blank\" rel=\"noopener\">https:\/\/www.cnblogs.com\/developing\/articles\/10890903.html<\/a><\/p>\r\n<p>&nbsp;<\/p>","updatetime":1604955411,"createtime":1604264702,"sort":128,"view_count":136,"jump_url":null,"author":null,"status":"normal","is_top":0,"ctitle":"博文","c_url":"https:\/\/www.yge.me\/show\/128.html","c_domain":"https:\/\/test.yge.me","after":{"id":126,"type":"","title":"C\/C++语言几种字符串类型互相转换","cate_id":16,"keyword":null,"intro":"const char * , char *  , char[] , string  互相转换.","avatar":"","updatetime":1604264937,"createtime":1604080264,"sort":126,"view_count":141,"jump_url":null,"author":null,"status":"normal","is_top":0},"front":{"id":130,"type":"","title":"AJAX 跨域请求 cookie问题","cate_id":16,"keyword":null,"intro":"js跨域请求的时候遇到的问题.","avatar":"","updatetime":1605609786,"createtime":1604375566,"sort":130,"view_count":133,"jump_url":null,"author":null,"status":"normal","is_top":0}}}}

列表解析存在异常

富文本源码
image
渲染的结果
image
多出来了两条数据,不知道是不是我的使用方法存在问题 /掩面

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.