tinymce 实现 粘贴图片自动上传
tinymce 实现 粘贴图片自动上传
关于图片上传的踩坑记录,基本就是如下几个
文章目录
不能复制本地图片然后粘贴
图片的复制粘贴,依赖于 paste 插件 文档:插件 \ paste 粘贴插件
简单的配置如下:
tinymce.init({
selector: '#tinydemo',
plugins: 'paste',
toolbar: 'paste',
paste_data_images: true // 默认是false的,记得要改为true才能粘贴
})

是一个二进制流链接的文件,这种保存到到后端在回显也显示不了了,所以要配置上传。还是看官方文档 上传图片和文件 | TinyMCE 中文文档中文手册 (ax-z.cn) 由于我都是用的自己的上传,这一块就没去深究
粘贴进来的图片上传问题
如何获取粘贴的图片内容: 上传图片和文件 | TinyMCE 中文文档中文手册 (ax-z.cn)
找到 images_upload_handler 函数一栏,在 init 方法中使用这个函数
tinymce.init({
images_upload_handler: function(blobInfo, success, failure, progress) {}
})
blodInfo 对象包含了几个方法:


方法名 执行后返回值
base64 图片对应的 base64 编码
blob 二进制流 File 对象
blobUri 二进制流的显示 URL(临时 URL,页面关闭后就消失了)
filename 文件名称(这里是被转换过的文件名称,并非原名)如: “mceclip0.jpg”
id 文件 ID 如: “mceclip0”
name 文件名称,不带后缀的 如:“mceclip0”
uri 最后一个我也不知道是啥
如果要获取文件原名,要在 blod 对象中拿
上传图片,自然是拿 blod 对象,然后结合自己的业务逻辑去上传给后端就行
上传图片后回显
success, failure, progress 几个回调的作用
名称 作用
success success('http://www.xxxx.com/xxx.png') 要插入的图片
failure failure() 印象中这个方法也很鸡肋,甚至最后我都用 success 了
progress progress(50) 显示图片上传的进度(全局显示,没啥作用)
图片点开大图后复制进来 2 张的问题
你以为坑到这里就结束了吗?no no no,这是各大平台都会出现的问题。
问题是这样的:window 平台下,图片在缩略图/没点开大图的时候,复制粘贴,没问题。
如果双击,打开了图片的大图在进行复制,粘贴到编辑器后,会显示 2 张一样的图片。包括微信点开大图,等等都会
我粘贴进去的图片名称是 :img.jpg。很明显在打印信息的 blodInfo.blod().name 中,多了一张 image.png 的图片。所以这并不属于
编辑器的 bug,而是 window 平台下的机制

无论粘贴什么图片,只要点开大图都会多一张叫 image.png 的图片。可是不排除用户的确会上传 image.png 的图片,所以不能简单粗暴
的过滤 image.png 的图片。
利用防抖函数的思想,过滤掉多余的 image.png
由于 bug 修复的比较紧急,代码并没有做过多的优化/封装成方法,稍微的看看逻辑就好
通常来说,image.png 都会比原图要先复制进来
- 遇到名为 image.png 的图片,延迟 30 毫秒在上传(这里用到了定时器 setTimeout)
2、如果是触发了上面说的 bug,30 毫秒内原图应该就会被复制进来了,那就是说如果第二次触发 images_upload_handler 函数时,
2.1. 如果还有定时器在等待,那就说明定时器里面的图是多余的
2.2. 如果超过 30 毫秒后还没有另外的图片触发images_upload_handler 函数,说明用户上传的就是叫 image.png 的图片,让定时器执行上传完成即可。
30 毫秒内触发了删除,定时器肯定要清除,可是图片还在编辑器内没删除,这时候就要执行 removeFn。在下面备注也有写了,记得
要用闭包,把image.png图片对应的success函数存起来。因为如果图片上传成功了,还得靠这个函数设置成对应的图片
// 定义2个全局变量 let uploadTimeOut = null let removeFn = null tinymce.init({ // 上传函数 images_upload_handler: (blobInfo, success, failure, progress) => { if (uploadTimeOut) { removeFn && removeFn() clearTimeout(uploadTimeOut) } let fileInfo = blobInfo.blob() // 定义一个上传方法 var upload = () => { // this.myUpload 是 上传文件的逻辑了,用promise包了一下 this.myUpload(fileInfo) .then(res => { // 上传成功后 success(res.data.url) }) .catch(res => { // 上传失败后,把src标记为 uploadFail ,然后在删除 // failure 函数有什么坑了,所以不想用它了 success('uploadFail') // setTimeOut 是为了然success函数执行到位后在删除,否则可能查不到对应的图片 setTimeout(() => { let errorImg = document.querySelectorAll('img[src="uploadFail"]') errorImg.forEach(item => { item.parentNode.removeChild(item) }) }, 100) }) } if (fileInfo.name == 'image.png') { uploadTimeOut = setTimeout(() => upload(), 30) // 这里要用一下闭包把当前的success函数保存起来,具体为啥一下子说不清,存起来就是了 // 图片复制进来后唯一的标识就是 blobUri 了,到时候删除还得靠他 // removeFn 与第9行代码呼应 removeFn = (function(url, cb) { return function() { cb && cb(url) let imgNode = document.querySelector('img[src="' + url + '"]') imgNode && imgNode.parentNode && imgNode.parentNode.removeChild(imgNode) removeFn = null } })(blobInfo.blobUri(), success) } else { upload() } } })
转自:(5条消息) tinymce 实现 粘贴图片自动上传_tinymce粘贴上传图片_Jioho_的博客-CSDN博客

浙公网安备 33010602011771号