富文本编辑器 word整体粘贴实现图片自动展示(一)

时间:2024-10-22 10:25:17

QuillEditor实现word粘贴图片正常显示

  • 富文本编辑器word整体粘贴实现图片正常显示
    • 粘贴事件
      • 单张图片粘贴
      • 复制内容整体粘贴
    • 整体粘贴如何实现从剪切板中提取出图片

富文本编辑器word整体粘贴实现图片正常显示

在使用富文本编辑器时,通常word整体粘贴时,图片总是无法正常显示,图片地址会是src="//0"的情况,这主要时因为,我们整体粘贴时,实际上我我们粘贴过去的是一片word的dom字符串,其中编辑器会为我们过滤其他无用标签,保留了主要部分。由于粘贴时候word文档中图片部分实际上引用的是本地地址,由于浏览器和js限制无法读取或者操作本地文件,因此无法正常显示。如果是网络上复制粘贴的文档则可以正常显示。

一下是从word直接粘贴过来的效果
在这里插入图片描述
一下是从网络上粘贴过来的效果
在这里插入图片描述

粘贴事件

通常要解决从word中复制粘贴到富文本编辑器中,都离不开这个paste事件,我们简单分析一下这个事件。
粘贴事件提供了一个clipboardData的属性,如果该属性有items属性,那么就可以查看items中是否有图片类型的数据了。
clipboardData的属性介绍:
属性 类型 说明
dropEffect String 默认是 none
effectAllowed String 默认是 uninitialized
files FileList 粘贴操作为空List
items DataTransferItemList 剪切板中的各项数据
types Array 剪切板中的数据类型

items是一个DataTransferItemList(浏览器基于file对象实现的方法,所以能够转换成file对象)对象,里面都是DataTransferItem类型的数据了。
items的DataTransferItem有两个属性kind和type
kind 一般为string或者file
type 具体的数据类型,例如具体是哪种类型字符串或者哪种类型的文件,即MIME-Type
方法
getAsFile 空 如果kind是file,可以用该方法获取到文件
getAsString 回调函数 如果kind是string,可以用该方法获取到字符串,字符串需要用回调函数得到,回调函数的第一个参数就是剪切板中的字符串

通常我们通过以上提供的属性就能够实现不论是从何处粘贴的内容,从这里我们也可以看到其冲粘贴的内容,这里简单实现一个单张图片粘贴的例子。

单张图片粘贴

let quill = this.$refs.myQuillEditor.quill;
    quill.root.addEventListener(
      "paste",
      (evt) => {
        // 粘贴事件
        if (
          evt.clipboardData &&
          evt.clipboardData.files &&
          evt.clipboardData.files.length
        ) {
          evt.preventDefault();
          [].forEach.call(evt.clipboardData.files, (file) => {
            if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
              return;
            }
            console.log('单个图片粘贴', file);
            // 转base64格式
            const reader = new FileReader()
            reader.readAsDataURL(file)
            reader.onload = (e) => {
              // 插入图片
              quill.insertEmbed(
                quill.getSelection().index,
                "image",
                reader.result
              )
            }
            reader.onerror = (error) =>reject(error)
            // obsUpload(file, this.$);
          });
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

复制内容整体粘贴

复制内容整体粘贴,我们通过上述的方法同样可以拿到其中内容。

let length = evt.clipboardData.items.length;
 for (let i = 0; i < length; i++) {
   var item = evt.clipboardData.items[i];
   if (item.kind === "string") {
     item.getAsString(function (str) {
       // str 是获取到的字符串
       console.log(str);
     })
   } else if (item.kind === "file") {
     var pasteFile = item.getAsFile();
     console.log(pasteFile);
   }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

整体粘贴过来,kind为string,实际上我们拿到的是一个html文档。
在这里插入图片描述
整体粘贴过来,kind为file,实际上我们拿到的是一个file文件对象。
在这里插入图片描述
这里实际上和第一部粘贴单张图片处理方式一样。

整体粘贴如何实现从剪切板中提取出图片

上述内容仅仅是作为了解内容,知道基本原理,下面这里才是重点。如果上面能解决你的单张图片粘贴问题,那么接下来才是实现整体粘贴提取图片的关键。
我们来看看clipboardData提供的其他几个方法。
(sDataFormat) 删除剪贴板中指定格式的数据。
(sDataFormat) 从剪贴板获取指定格式的数据。
(sDataFormat, sData) 给剪贴板赋予指定格式的数据。返回 true 表示操作成功。
这里我们重点讨论getData这个方法,其他方法请自行实践。
getData这个方法是clipboardData提供给我们快速从剪切板中提取内容的方法。
其中常用参数:
1 text/html 获取html内容
2 text/plain 获取文本内容
3 text/rtf 获取富媒体内容 (什么是rtf请自行查询资料,这里面就含有我们需要的图片信息)
我们需要结合 text/html 和 text/rtf 两种两种方法实现,对粘贴内容中图片的提取。
通过 text/html我们提取到图片之后,我们发现图片地址都是file:/// 开始的本地文件,js无法完成对本地文件的处理,无法做base64处理。浏览器会给出警告。
在这里插入图片描述
接下来我们需要,从html文档中提取出是file格式的本地文件的img, 然后讲这些图片替换成loading图片。
然后就是如何把这些图片转换成对应的图片。
在QuillEditor中提供一个clipboard配置项,我们通过这个配置项实现将图片替换成loading图片。
在这里插入图片描述

// 自定义粘贴内容过滤方法
function customMatcherNode(node, delta) {
    if (delta.ops && delta.ops.length > 0) {
      delta.ops = delta.ops.map((item) => {
        if (item.insert) {
          if(item.insert.image) {
            // 判断是否是网络地址
            if (/file:\/\//.test(item.insert.image)) {
              item.insert.image = '/community/'
            }
          }
          return item;
        }
      })
    }
    return delta;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
'
运行

通过以上方法,我们实现讲了整体粘贴过来的内容换成loading图片。
接下来,我们要讲对应的loading图片,替换成对应的真实图片。
这些图片的对应的内容就保存在getData(‘text/rtf’)中,这里面是一种特殊hex格式的内容。
我们需要对其进行转换和提取。才能拿到对应的base64图片。

请多多转收藏点赞,后续更新