Coder Social home page Coder Social logo

mzwf / parser Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jin-yufeng/mp-html

0.0 1.0 0.0 521 KB

小程序富文本插件,支持丰富的标签,无层数限制,容错性强且轻量化,支持在各类框架中使用

License: MIT License

JavaScript 86.64% CSS 0.91% Vue 12.45%

parser's Introduction

Parser

小程序富文本插件(本文档动态更新,建议加星收藏)

目录

功能介绍

  • 支持解析style标签中的全局样式
    可以把style标签里的样式匹配到各标签的style
  • 支持自定义默认的标签样式
    可以在tag-style属性中设置各标签的默认效果
  • 支持自动设置标题
    若存在title标签,将自动把title标签的内容设置到页面的标题上
  • 支持添加加载提示
    可以在Parser标签内添加加载提示或动画,将在未加载完成或内容为空时显示,加载完成后自动隐藏
  • 支持动画显示效果
    通过设置show-with-animation属性可以实现内容加载完成后渐显的动画效果
  • 支持多资源加载
    可以在videoaudio中设置多个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 47.4KB uni-app 插件包(可以编译到所有平台)
  • 关于百度版与微信版的差别,可见百度版与微信版的差别
  • uni-app版因为各平台rich-text和自定义组件表现有所不同,有较多条件编译的内容,编译后大小会缩小,关于各平台间的差别和与原生包的差别,可见uni-app包说明
  • 可根据需要选用,使用时建议统一更名为Parser,以下统称Parser

在原生框架中使用

  1. 下载Parser文件夹至小程序目录
  2. 在需要引用的页面的json文件中添加(百度小程序中组件名一定要小写
    {
      "usingComponents": {
        "parser":"/Parser/index"
      }
    }
  3. 在需要引用的页面的wxml文件中添加
    <parser html="{{html}}" />
  4. 在需要引用的页面的js文件中添加
    data: {
      html:"<div>Hello World!</div>"
    }
  • demo/wx文件夹下的是微信小程序 富文本插件 示例程序的源码,可供参考

在uni-app中使用

  • 使用uni-app包(可以编译到所有小程序平台)
    1. 下载Parser.uni包到components目录下(更名为Parser
    2. 在需要使用页面的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文件夹下是一个示例程序,可供参考
  • 使用原生包
    参考官网-小程序组件支持

在mpVue中使用

  1. 下载Parser文件夹至static目录下
  2. src目录下需要使用本插件的页面文件夹下添加json文件
    {
        "usingComponents": {
            "parser": "../../static/Parser/index"
        }
    }
  3. 在需要使用的页面的vue文件中添加
    <template>
      <div class="container">
        <parser :html="html"></parser>
      </div>
    </template>
    <script>
    export default {
      data: {
        html: '<div>Hello World!</div>'
      }
    }
    </script>
  • 注意:mpvueuni-app中使用时组件名必须小写

在wepy中使用

测试版本:V1.7.3

  1. Parser文件夹复制到/src/components目录下
    (也可以直接复制到/dist/components目录下,这样wepy不会对插件包进行编译和压缩)
  2. 在需要使用的页面的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>
  3. 通过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格式:
    1. string类型:一个html字符串,例如:<div>Hello World!</div>
    2. object类型:一个形如{nodes: [Array], imgList: [Array], title: "String"}的结构体,其中nodes数组的格式基本同rich-text,对于该节点下有imgvideoa标签的,需要将continue属性设置为true,否则将直接使用rich-text组件渲染,可能导致图片无法预览,链接无法点击等问题,imgList为其中所有图片地址的数组,title是页面的标题(不必要,传入将会设置到页面的标题上),回调函数bindparser的返回值就是这样的结构体
    3. array类型:格式要求同上(用此格式传入预览图片时,将不能通过左右滑动查看所有图片)
    4. 使用b, c方法可以节省解析的时间,提高性能
  • 关于img-mode
    默认default,在没有设置宽高时,按图片原大小显示;设置了宽或高时,按比例进行缩放;同时设置了宽高时,按设置的宽高进行缩放。在同时设置了宽高的情况下,宽度可能因为max-width:100%的限制而缩短导致图片变形,此时可将模式设置为widthFix,即保持宽度不变,高度自动变化(会导致设置的高度无效)
  • 关于tag-style
    可以设置标签的默认样式,如{ body:"margin:5px" };仅传入的htmlString类型时有效(在解析过程中设置)

回调函数

名称 功能 说明
bindparser 在解析完成时调用(仅当传入的htmlString时会调用) 返回一个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)";

注意事项:

  1. 由于只有自定义组件内的样式在组件内能生效且rich-text在组件内使用时也只能匹配组件内的样式,所以必须在trees组件的wxss/css文件中引入需要的样式,在页面中写的样式无效
  2. 组件内只能使用class选择器(支持后代选择器),不支持id选择器、属性选择器、标签名选择器等(更多可见官网说明
  3. 通过这种方式引入的样式会对所有parser标签生效,如果是对单个parser使用的样式,请使用style标签

补丁包

patches文件夹中准备了一些补丁包,可根据需要选用,可以实现更加丰富的功能

emoji

  • 功能
    将形如[笑脸]的文本解析为emoji小表情
  • 大小
    4.70KBmin版本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字符或网络图片
    emoji演示

document

  • 功能
    实现类似于web中的document对象,可以动态操作DOM

  • 大小
    4.66KBmin版本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的标签执行getTextsetText
      2 输入值类型不正确
      3 输入值超出范围
      4 无法找到对应id的节点
  • 注意事项
    所有方法必须在htmlsetData完成后才能调用
    每次执行除了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); // 查找失败
      }
    }

List

  • 背景
    在原插件中,由于列表较难通过模拟实现,是直接使用rich-text来显示列表,这导致列表中的图片无法预览,链接无法点击,此补丁包可以解决这个问题
  • 功能
    模拟olulli标签
    ol标签支持starttype属性;ul标签会自动根据层级显示不同的样式
  • 大小
    4.50KB
  • 此补丁包仅能在微信小程序中使用
  • 使用方法
    1. list文件夹复制到Parser文件夹下
    2. trees.li.wxml中的内容复制到Parser/trees/trees.wxmlnameelementtemplate中的任意位置
    3. Parser/trees/handler.wxs中的isContinue函数中进行如下修改
      // else if(item.name=='a')
      else if(item.name=='a'||item.name=='li'||item.name=='ol'||item.name=='ul')
    4. Parser/trees/trees.json中添加
      "usingComponents": {
        "trees": "./trees",
        "ol": "../list/ol",
        "ul": "../list/ul",
        "li": "../list/li"
      }
    5. Parser/DomHandler.jstrustTag结构体的olulli属性值改为1
    • 可参考demo文件夹中的Parser(已装载此补丁包)
  • 在其他页面中使用
    该包将列表封装成自定义组件,可以直接在其他页面上使用
    1. 在需要使用的页面的json文件中添加
      {
        "usingComponents": {
          "ol": "/Parser/list/ol",
          "ul": "/Parser/list/ul",
          "li": "/Parser/list/li"
        }
      }
    2. 可以直接使用olulli标签来显示列表
      <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>
      列表演示

CssHandler

  • 功能:支持更多的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.04KBmin版本: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.10.29:
    1. F 修复了部分行内标签被错误换行的问题
  • 2019.10.27:
    1. F 修复了部分情况下多张相同的图片仅第一张可显示的问题
  • 2019.10.24:
    1. U uni-app包支持在APP端使用
  • 2019.10.17:
    1. A 增加了CssHandler补丁包(可支持多层的css选择器)详细
    2. U uni-app包支持在H5端使用
  • 2019.9.28:
    1. A 增加了lazy-load属性(可用于图片懒加载)
  • 2019.9.25:
    1. A 增加了uni-app插件包(可以编译到所有小程序平台)详细
    2. F 修复了部分情况下样式显示错误的问题
  • 2019.9.22:
    1. U 支持引入wxss / css文件中的外部样式 详细
  • 2019.9.21:
    1. A 增加了百度小程序插件包 详细
    2. U 为与百度小程序包统一,所有事件的返回值改为object类型(影响bindimgtapbindlinkpress详细
    3. U 优化了补丁包的引入方式
    4. F 修复了autopause属性在某些情况下会失效的问题

更多可见:更新日志

parser's People

Contributors

jin-yufeng avatar

Watchers

 avatar

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.