微信小程序富文本解析插件-towxml(扩展富文本图片预览功能)

微信小程序富文本解析插件-towxml(扩展富文本图片预览功能)

  • 其实单纯渲染富文本直接用微信小程序的 rich-text 属性就够了
  • 用 towxml 是为了扩展富文本图片的预览功能,微信自带的 rich-text 只能针对富文本整体监听事件,无法实现用户点哪张图片预览哪张,用户体验非常差

富文本图片预览效果图

在这里插入图片描述

基本配置

关键步骤复述
当然,贴心的我还是准备了简短的复现歩鄹
在这里插入图片描述

1.按文档描述配置并构建 towxml

  • 文档步骤摘抄
1.克隆项目到本地
git clone https://github.com/sbfkcel/towxml.git

2.安装构建依赖
npm install 或 yarn

3.编辑配置文件towxml/config.js
根据自行要求,仅保留你需要的功能即可(配置中有详细注释)

4.运行 npm run build 或 yarn run build即可

5.新构建出来的文件会保存在你的桌面上towxml目录,将此目录复制到你的小程序项目中即可

2.将构建生成的 towxml 文件夹放到小程序根目录

├─images
├─miniprogram_npm
├─node_modules
├─pages
├─towxml
│  ├─audio-player
│  ├─img
│  ├─parse
│  │  ├─highlight
│  │  │  ├─languages
│  │  │  └─style
│  │  ├─markdown
│  │  │  └─plugins
│  │  └─parse2
│  │      ├─domhandler
│  │      └─entities
│  │          └─maps
│  ├─style
│  │  └─theme
│  ├─table
│  └─todogroup
└─utils

3.在 app.js 文件中引入

//app.js

App({
	// 引入`towxml3.0`解析方法
  towxml: require('/towxml/index'),
  // ...
}

4.在需要用到富文本解析器的页面中(xxx.json)引入 towxml 组件

  • 由于项目多处用到了富文本,我就直接写到了 app.json
{
  // ...
  "usingComponents": {
    "towxml": "/towxml/towxml"
  }
}
towxml 使用与图片预览扩展

5.定义图片预览工具方法,预处理数据(后面要用到)

  • 给图片添加点击事件,支持预览图片

/utils/util.js

// ... 其他方法

// 富文本预处理(外部只调用这一个方法就行了)
const dealWithRichText = originHtml => {
  let [html, imgUrls] = addRandomAndGetPreviewImageUrlsFromRichText(originHtml)
  const app = getApp()
  return app.towxml(html, 'html', {
    events: {
      // 给富文本绑定点击事件
      tap: event => {
        // console.log(event, "towxml event")
        // 只处理图片的点击事件
        if (event.currentTarget.dataset.data && event.currentTarget.dataset.data.attr && (event.currentTarget.dataset.data.attr.class == "h2w__img")) {
          // 传入图片地址,调用微信图片预览 API
          wx.previewImage({
            current: event.currentTarget.dataset.data.attr.src, // 当前显示图片的http链接
            urls: imgUrls
          })
        }
      }
    }
  })
}

/**
 * 从富文本中给图片链接添加 random 并且返回图片数组(加 random 防止重复图片预览打乱顺序)
 * @example let [html, imgUrls] = addRandomAndGetPreviewImageUrlsFromRichText(html)
 * @param {string} html 
 */
const addRandomAndGetPreviewImageUrlsFromRichText = html => {
  // 如果没有值的话,直接返回
  if (!html) {
    return html
  }

  let randomIndex = 0
  let imgUrls = []
  // 先匹配到 img 标签,放到 match 里
  html = html.replace(/<img[^>]*>/gim, function (match) {
    randomIndex++
    match = match.replace(/src="[^"]+"/gim, function (match) {
      // 再匹配到 src 标签 '"'
      let src = match.slice(5, -1) + "?random=" + randomIndex // 取到 src 里面的 url
      imgUrls.push(src)
      return 'src="' + src + '"'
    }).replace(/src='[^']+'/gim, function (match) {
      // 再匹配到 src 标签 "'"
      let src = match.slice(5, -1) + "?random=" + randomIndex
      return "src='" + src + "'"
    })

    return match
  })
  return [html, imgUrls]
}

/* 加载动画相关 */
const showLoading = () => {
  wx.showNavigationBarLoading()
  wx.showLoading({
    title: '加载中...',
  })
}
const hideLoading = () => {
  wx.hideLoading()
  wx.hideNavigationBarLoading()
}
const hideLoadingWithErrorTips = () => {
  hideLoading()
  wx.showToast({
    title: '加载失败...',
    icon: 'error',
    duration: 2000
  })
}

module.exports = {
  // ...
  // addRandomAndGetPreviewImageUrlsFromRichText: addRandomAndGetPreviewImageUrlsFromRichText,
  dealWithRichText: dealWithRichText,
  
  showLoading: showLoading,
  hideLoading: hideLoading,
  hideLoadingWithErrorTips: hideLoadingWithErrorTips,
}

6.调用工具方法提取图片地址, towxml 解析处理富文本

/pages/aa/bb/xxx.js(案例相对完整写法)

const urlList = require('../../../utils/api') // 统一配置管理接口地址
const util = require('../../../utils/util')

Page({

  /**
   * 页面的初始数据
   */   
  data: {
    // ... 其他变量
    listdata: {},
  },
   
  // ... 其他方法
  
  // 获取数据的方法
  getData(id) {
    util.showLoading()
    let that = this
    wx.request({
      url: urlList.getData + `?id=${id}`, // 等价于 www.xxx.com/xxx/search?id=1
      method: "GET",
      // header: {
      //   'content-type': 'application/x-www-form-urlencoded'
      // },
      success(res) {
        if (res.data.msg == 'success') {
          let data = res.data.list[0]
          
          // 1.关键步骤:调用方法处理富文本
          data.des = util.dealWithRichText(data.des)
          
          // ... 其他处理
          that.setData({
            listdata: data,
            // ...
          })
          util.hideLoading()
        }
        else {
          util.hideLoadingWithErrorTips()
        }
      },
      fail(err) {
        console.log(err, 'index onLoad err')
        util.hideLoadingWithErrorTips()
      }
    })
  }
})

7.在页面上(/pages/aa/bb/xxx.wxml)渲染

<!-- ...其他页面内容... -->

<view class="detailDescription">
  <towxml nodes="{{listdata.des || '暂无简介'}}"/>
</view>

定制样式

8.定制富文本展现样式(框架自带样式的优先级不高,我们可以很轻易的重置样式)

  • 默认的渲染样式与我的预期效果有些差别,我们自定义样式来修改
  • 由于项目多处用到了富文本,故样式我直接写到了 app.wxss
/* 其他样式... */

view .h2w__main {
  margin: 0;
  padding-top: 0;
}


/* 重置部分框架自带的样式,更加方便在页面里做定制化 */
view .h2w-light {
  color: unset;
  background-color: unset;
}
view .h2w {
  font-weight: unset;
  font-size: unset;
  line-height: unset;
}

/* 框架自带样式的优先级不高,我们可以很轻易用父级统一控制样式,下面的样式在页面里写可以直接生效 */
/* 结构如下,可以直接控制内部富文本的样式
<view class="detailDescription">
  <towxml nodes="{{listdata.des || '暂无简介'}}"/>
</view> 
*/
/*
.detailDescription {
  color: red;
}
*/

补充说明

微信小程序自带 rich-text 图片宽度控制

我的构建配置文件(CSDN下载)

不想把 towxml 放在小程序根目录?

想要将 towxml 放到指定目录其实也很简单,只需要自己处理一下报错即可…

1.直接在项目根目录创建一个 components 目录,将生成好的 towxml 放进去

  • 会报错:[ components/towxml/decode.json 文件内容错误] components/towxml/decode.json: ["usingComponents"]["decode"] 未找到

2.更改 components\towxml\decode.json 的路径即可(绝对路径都改为相对路径)

{
  "component": true,
  "usingComponents": {
    "decode": "./decode",
    "audio-player": "./audio-player/audio-player",
    "table": "./table/table",
    "todogroup": "./todogroup/todogroup",
    "img": "./img/img"
  }
}

3.将在配置时引用到 towxml 的地方都把路径更正一遍

app.js

//app.js

App({
	// 引入`towxml3.0`解析方法
  towxml: require('/components/towxml/index'),
  // ...
}

所有引用到的页面/pages/aa/bb/xxx.json 亦或是全局配置的 app.json

{
  // ...
  "usingComponents": {
    "towxml": "/components/towxml/towxml"
  }
}

更多

  • 超级定制化…(请自行探索)
  • 把富文本自带的一些样式删掉,无用的东西删掉…

常驻小尾巴

如果你觉得写的不错或者帮到你了,记得给我点个赞哟~ 😁在这里插入图片描述

  • 31
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 43
    评论
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RealizeInnerSelf丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值