咸鱼柴也有大厂梦

咸鱼柴也有大厂梦

坑一:回显问题

富文本组件:

    <editor id="editor" name="{{name}}" style="font-size: 28rpx;color: #C9CDD4" read-only="{{true}}" placeholder="{{placeholder}}"  bind:input="onChange11" ></editor>

回显方法:

 _onEditorReady: function (html: any) {
      const that = this as any
      that.createSelectorQuery().select('#editor').context(async function (res: any) {
        that.editorCtx = res.context
        await that.editorCtx.setContents({ //将html回显富文本区域
          html,
          success: function (res: any) {
          },
          fail: function (fail: any) {
          },
          complete: function (bbxx: any) {
          }
        })
      }).exec()
    },

bug复现:

当字符串中包含base64图片,且base64图片超过1024kb就会被微信机制拦截下来(官方文档有说明)导致整个组件无法正常渲染,包括img标签前的文字

解决方案(三种)

1:和后端协调,将base64转为在线url地址(例如oss地址),完美解决

2:对于性能考虑,如果是双端(pc+移动),建议做文件大小判断,文件过大的话建议提示到pc端查看或操作

再数据初始化的时候,先调用如下方法,获得该字符串的实际大小,然后在按需处理,下面做具体举例

 getStringSize(str: string) {
      var myString = str;
      // 使用 TextEncoder 将字符串编码为字节数组
      var textEncoder = new TextEncoder();
      var encodedData = textEncoder.encode(myString);
      // 计算字节数
      var byteSize = encodedData.length;
      // 将字节数转换为 KB
      var kbSize = Math.floor(byteSize / 1024);
      return kbSize
    },
const str = '你要渲染的富文本字符串'

const realSize = this.getStringSize(str)

if(realSize >=1024) {
    提示用户,该文本域内存在较大图片,请到pc端查看
} else {
    this._onEditorReady(str)
}

3:将base64转为本地url以此绕过大小拦截并成功渲染

非得渲,那就渲吧,思路就是base64有实际大小会被检测到,处于项目原因又不能使用线上url,那就将base64转本地url再替换渲染字符串中的base64,就可以完美绕开大小检测,下面做具体举例

 base64ToUrl(base64Data: string, name: string) {
      // 保存的文件名(考虑一个string内可能有多个img标签,使用随机数确保name唯一)
      const FILE_BASE_NAME = 'temp_base64_image' + name + Math.floor(Math.random() * 90);                     
      // 将 base64 数据写入本地文件
      const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.png`;
      fsm.writeFileSync(filePath, base64Data, 'base64');
      // 获取本地图片 URL
      return filePath;
    },

    // 替换字符串中的<img>标签中的base64为本地URL
    replaceBase64WithLocalUrl(inputString: string, name: string) {
      const regex = /<img\s+src="data:image\/[^;]+;base64,([^"]+)"/g; //获取base64数据区间
      // 将base64区间替换为本地图片url绕过setdata1024kb检测
      const replacedString = inputString.replace(regex, (match, base64Data) => { 
        const localImageUrl = this.base64ToUrl(base64Data, name);
        return `<img src="${localImageUrl}"`;
      });
      return replacedString;
    },
const str = '你要渲染的富文本字符串'

str = this.replaceBase64WithLocalUrl(str)

this._onEditorReady(str)

坑二:回显图片样式问题

这下图片能正常回显了,无论图片多大多小,但是偶尔有一些超大图会有宽高比例失调原因,第一种方案是用正则给所有img标签设置style=" width:100%;height:100%;object-fit: cover;"也好,设置style=" width:100%;height:auto;"也罢,总之就是不行,于是翻查文档发现

[微信小程序踩坑]微信小程序editor富文本组件渲染字符串时,内部图片超出大小导致无法正常渲染或回显(数据传输长度为 3458 KB,存在有性能问题!)-LMLPHP

img中如果存在行内style(自带、后台配置),那么自己写的style将会被覆盖,所以正确的方法是给所有img标签设置class ,下面做具体示例

this._onEditorReady(str.replace(/<img/g, '<img class="rich-img" '))

.rich-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

至此,所有坑填完


生命不息,学习不止,键盘敲烂,月薪过万!加油,代码人!

10-28 06:16