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图片。
请多多转收藏点赞,后续更新