uniapp中v-html图片长按事件不生效

161 阅读1分钟

本意是处理富文本中图片,按需加上长按功能不生效,特此输出

function replaceImgStype(imgstr) {
  let reg = /style="(.*?)"/gm // 匹配行内样式
  let reg2 = /width=/gm // 这个是表情包会自带宽度属性所以要排除掉表情包
  if (reg2.test(imgstr)) {
    return imgstr // 排除表情包
  } else {
  // 按需替换宽度 和 长按显示菜单
    if (reg.test(imgstr)) {
      return imgstr.replace(reg, function(styleHtml) {
        return 'style="width: 100%;" show-menu-by-longpress' //
      })

    } else {
      return imgstr.replace('<img', '<img style="width: 100%;" show-menu-by-longpress')
    }

  }
}

上面给img加上了show-menu-by-longpress后也没生效(把img改成image图片不会显示)

接下来三步带走它!

1.下面直接出方法处理字符串

//2、 将图片中的 img 全部切分出来
// 将 后台的html 字符串分割 为 html 和 图片
export function executeSplitImage(htmlcontent) {
  let reg = /<img(.*?)\/>|<[^>]+>|[^<|>|\w]|\w+\b|\s+/gm
  let regStart = /<(.*?)>/
  let regEnd = /<\/(.*?)>/
  let closure = /<(.*?)\/>/
  let regimg = /<img(.*?)\/>/
  let regex = /<img[^>]+src=['"]([^'"]+)['"]/;
  let nodeList = htmlcontent.match(reg)
  // 合并 html
  let stock = []
  let list = []
  let currentNode = null

  function executeCurrentNode(item) {
    if (!currentNode) {
      let startClosure = ''
      if (stock.length) {
        stock.forEach(item => {
          startClosure += item.tag
        })
      }
      currentNode = {
        type: 'text',
        data: startClosure + item
      }
    } else {
      currentNode.data += item
    }
  }
  // 封闭 html
  function closureNode() {
    if (currentNode) {
      // 需要封闭 node
      let endClosure = ''
      if (stock.length) {
        stock.forEach(item => {
          endClosure += '</' + item.name + '>'
        })
        currentNode.data += endClosure
      }
      list.push(currentNode)
    }
    currentNode = null

  }

  function addTag(item) {
    executeCurrentNode(item)
    const regtag = /<([a-z0-9]+)(\s[^>]*)?>/g;
    let tagmatch = regtag.exec(item)
    if (tagmatch && tagmatch[1]) {
      stock.push({
        name: tagmatch[1],
        tag: tagmatch[0],
        attr: tagmatch[2] || ''
      })
    }
  }

  function removeTag(item) {
    let regtag = /<\/([^>]+)>/
    let tagmatch = item.match(regtag)
    if (tagmatch && tagmatch[1]) {
      let rtag = tagmatch[1]
      let lasttag = stock[stock.length - 1]
      if (lasttag && lasttag.name == rtag) {
        stock.pop()
      }
    }
    executeCurrentNode(item)
  }
  for (let item of nodeList) {
    // 是不是 图片
    if (closure.test(item)) {
      //判断是不是 img 和提交 str
      if (regimg.test(item)) {
        let imgItem = item.match(regex)
        if (imgItem && imgItem[1]) {

          closureNode()
          list.push({
            type: 'image',
            data: imgItem[1]
          })
        }
      } else {
        // console.log('closure',item)
        executeCurrentNode(item)
      }
    } else if (regEnd.test(item)) {
      // 是不是 结束
      // console.log('removeTag',item)
      removeTag(item)
    } else if (regStart.test(item)) {
      // 是不是 开始
      // console.log('regStart',item)
      addTag(item)

    } else {
      // console.log('content',item)
      executeCurrentNode(item)
    }

  }
  closureNode()
  return list
}

2.富文本放进去处理

let List = this.executeSplitImage(html)
// 处理出来是这样的结构
List:{
     type: 'image',
     data: 'xxx.jpg'
}

3.最后这样展示你的富文本

<view v-for="(item,index) in List" :key="index">
    <!-- 用image加上 show-menu-by-longpress 属性 -->
    <image show-menu-by-longpress style="width: 100%;" @click="showCurrentImage(item.data)" v-if="item.type=='image'" :src="item.data" mode="widthFix">
    </image>
    <view style="padding: 20rpx 30rpx;" v-else v-html="item.data"></view>
</view>

拿走点个赞吧!