受欢迎的博客标签

wechat-微信小程序Asp .Net Core开发实战记录(31)-微信小程序纯原生富文本图文编辑器的原理及实现

Published

 

主要实现以下功能:

**1. 富文本编辑,图文混排

图片添加原则上可以无限,demo做了限制,最多四张
删除图片,图片上下文字合并**
先分析原理,小程序中需要的并不是复杂的图文编辑器,来编辑负责的文字样式,只需要实现图文混排的编辑和展示即可,所以结构如下图:

黑色的最外框代表编辑区域
黑色的小格子代表文本区域
红色格子代表图片
右边是对左边进行的一个合并,根据规律,每个图片下面都会跟着一个文本编辑区域(当没有文字时为不可见),所以文本编辑器变成了最上面一个文本编辑框,后面动态的跟着图文组合。
这就是整个的结构,下面来进行实现:
richtest.xwml

view class='toWrite' bindtap='addImg'>
  <image src='../image/album.png' style='width:60rpx;height:60rpx;margin-left:15rpx;margin-top:15rpx;' />
</view>
<view>
  <textarea class='input_view' maxlength='-1' auto-height='true' bindinput='inputCon' style='width:{{width-20}}px;' value='{{firstCon}}' placeholder='写点什么...' bindblur="outBlur" id='0'  />
  <view wx:for="{{dataList}}" style='background-color:white;'>
    <view class='img_view' style='width:{{width-28}}px;max-height:{{width-28}}px;'>
      <image style='width:{{width-28}}px;max-height:{{width-28}}px;' src='{{item.pic}}' mode='aspectFill' />
      <view>
        <icon type='cancel' bindtap='deletedImg' data-index='{{index}}' size='25' color='#ef8383' style='width:25px;height:25px;margin-left:-35px;margin-top:10px;'></icon>
      </view>
    </view>
    <textarea class='input_view' maxlength='-1' auto-height='true' bindinput='inputCon' style='width:{{width-20}}px;' value='{{item.value}}' placeholder='写点什么...' bindblur="outBlur" id='{{index+1}}'  />
  </view>
  <view style='height:45px;width:100%;'></view>
</view>

richtext.js

var Utils = require('../../utils/util.js')
var app = getApp()
var list = []
Page({
  data: {
    content: '',
    height: 500,
    width: 320,
    imgIndex: 0,
    imageLength: 0,
    firstCon: '',
    dataList: [],
  },
  onLoad: function (options) {
    let that = this
  },
  onShow: function (e) {
    var that = this;
    //动态获取屏幕尺寸
    wx.getSystemInfo({
      success: function (res) {
        that.setData({
          height: res.windowHeight,
          width: res.windowWidth,
        })
      },
      fail: function (res) { },
      complete: function (res) { },
    })
  },
  /**
   * 输入监听
   */
  inputCon: function (e) {
    let that = this;
    if (0 === e.currentTarget.id - 0) {//第一个文本框的输入监听
      that.data.firstCon = e.detail.value;
    } else {
      that.data.dataList[e.currentTarget.id - 1].value = e.detail.value;
    }
  },
  /**
   * 失去焦点监听
   * 根据失去监听的input的位置来判断图片的插入位置
   */
  outBlur: function (e) {
    let that = this;
    that.data.imgIndex = e.currentTarget.id - 0;
  },
  /**
   * 添加图片
   */
  addImg: function () {
    var that = this;
    //这里考虑到性能,对于图片张数做了限制
    if (that.data.dataList.length >= 4) {//超过四张
      wx.showModal({
        title: '提示',
        content: '最多只能添加四张图片哦',
        confirmText: "我知道了",
        confirmColor: "#ef8383",
        showCancel: false,
        success: function (res) {
          if (res.confirm) {
          } else if (res.cancel) {
          }
        }
      })
    } else {//添加图片
      wx.showActionSheet({
        itemList: ['从相册选择', '拍照'],
        itemColor: '#ef8383',
        success: function (res) {
          var choseType = res.tapIndex == 0 ? "album" : res.tapIndex == 1 ? "camera":"";
          if (choseType != "") {
            wx.chooseImage({
              sizeType: ['original'],//原图
              sourceType: [choseType],
              count: 1,//每次添加一张
              success: function (res) {
                var info = {
                  pic: res.tempFilePaths[0],//存储本地地址
                  temp: true,//标记是否是临时图片
                  value: '',//存储图片下方相邻的输入框的内容
                }
                that.data.dataList.splice(that.data.imgIndex,0,info);//方法自行百度
                that.setData({
                  dataList: that.data.dataList,
                })
              }
            })
          }
        },
        fail: function (res) {
          console.log(res.errMsg)
        }
      })
    }
  },
  /**
   * 删除图片
   */
  deletedImg: function (e) {
    let that = this;
    let index = e.currentTarget.dataset.index;
    wx.showActionSheet({
      itemList: ['删除图片'],
      success: function (res) {
        if (res.tapIndex === 0) {//点击删除图片
          if (index === 0 && that.data.dataList[index].value != null) {//删除第一张,要与最上方的textarea合并
            that.data.firstCon = that.data.firstCon + that.data.dataList[index].value;
          } else if (index > 0 && that.data.dataList[index].value != null) {
            that.data.dataList[index - 1].value = that.data.dataList[index - 1].value + that.data.dataList[index].value;
          }
          that.data.dataList.splice(index, 1);
          that.setData({
            firstCon: that.data.firstCon,
            dataList: that.data.dataList
          })
        }
      },
      fail: function (res) {
        console.log(res.errMsg)
      }
    })
  },
  //失败警告
  do_fail: function (a) {
    wx.showToast({
      title: a,
      icon: 'none',
      duration: 1000
    })
  },
})

https://blog.csdn.net/u012436704/article/details/83426532

源码:

https://github.com/xc1255178487/little_program