quill富文本编辑器的粘贴问题
前言:公司后台项目中有富文本功能,我们选取了quill这个插件来使用。在实际过程中,只对上传图片按钮做了上传至服务器的功能,对粘贴的图片并没有做处理,导致前端显示的时候,base64图片数据过大而出错。
解决方法一:对quill中的方法做修改
- 可以看到quill中关于粘贴的源码如下,有图片时执行了
this.quill.uploader.upload(range, files);
- 关于upload方法,在此不细讲,可以在modules中的uploader.js中查看,查看该模块可知,图片转成了base64并插入到文本中
this.quill.root.addEventListener('paste', this.onCapturePaste.bind(this));
onCapturePaste(e) {
if (e.defaultPrevented || !this.quill.isEnabled()) return;
e.preventDefault();
const range = this.quill.getSelection(true);
if (range == null) return;
const html = e.clipboardData.getData('text/html');
const text = e.clipboardData.getData('text/plain');
const files = Array.from(e.clipboardData.files || []);
if (!html && files.length > 0) {
this.quill.uploader.upload(range, files);
} else {
this.onPaste(range, { html, text });
}
}
- 如何解决?那我们让upload方法不执行不就行了。
- 因为引入quill的入口文件是dist/quill.js;所以可以将代码fork到仓库,然后修改相应的地方;
- patch-package方法为包打补丁,网上有教程,不在此赘述;这样做的好处是不需要自己fork一套代码
解决方法二:在自己代码中使用富文本的地方,加上粘贴监听
this.quill.root.addEventListener(
"paste",
evt => {
if (
evt.clipboardData &&
evt.clipboardData.files &&
evt.clipboardData.files.length
) {
evt.preventDefault();
}
},
true
);
- 利用监听事件的第三个参数来处理,为true的话,该事件在捕获阶段执行,优先于quill源码中监听粘贴事件,源码中第三个参数为默认false,则会先执行我们自己自定义方法,并上传图片至服务器,而
evt.preventDefault()
阻止了默认事件发生,使得源码中 (e.defaultPrevented || !this.quill.isEnabled())
为true,因为此刻e.defaultPrevented为true,则源码中的代码不会往下执行。这样非文本粘贴也不会执行,但是我们自己写的监听还是会执行粘贴文本的,因为preventDefault()只对file类型阻止了默认事件。