1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > tinymce 实现 粘贴图片自动上传

tinymce 实现 粘贴图片自动上传

时间:2020-01-16 08:00:57

相关推荐

tinymce 实现 粘贴图片自动上传

tinymce 实现 粘贴图片自动上传

tinymce 中文文档:上传图片和文件

关于图片上传的踩坑记录,基本就是如下几个

文章目录

tinymce 实现 粘贴图片自动上传不能复制本地图片然后粘贴粘贴进来的图片上传问题上传图片后回显图片点开大图后复制进来 2 张的问题

不能复制本地图片然后粘贴

图片的复制粘贴,依赖于paste插件 文档:插件 \ paste 粘贴插件

简单的配置如下:

tinymce.init({selector: '#tinydemo',plugins: 'paste',toolbar: 'paste',paste_data_images: true // 默认是false的,记得要改为true才能粘贴})

粘贴后的图片在显示上是这样的:

是一个二进制流链接的文件,这种保存到到后端在回显也显示不了了,所以要配置上传。还是看官方文档 上传图片和文件 | TinyMCE 中文文档中文手册 (ax-) 由于我都是用的自己的上传,这一块就没去深究

粘贴进来的图片上传问题

如何获取粘贴的图片内容: 上传图片和文件 | TinyMCE 中文文档中文手册 (ax-)

找到 images_upload_handler 函数一栏,在 init 方法中使用这个函数

tinymce.init({images_upload_handler: function(blobInfo, success, failure, progress) {}})

blodInfo对象包含了几个方法:

如果要获取文件原名,要在 blod 对象中拿

上传图片,自然是拿 blod 对象,然后结合自己的业务逻辑去上传给后端就行

上传图片后回显

success, failure, progress 几个回调的作用

图片点开大图后复制进来 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)如果是触发了上面说的 bug,30 毫秒内原图应该就会被复制进来了,那就是说如果第二次触发images_upload_handler函数时,

2.1.如果还有定时器在等待,那就说明定时器里面的图是多余的

2.2.如果超过 30 毫秒后还没有另外的图片触发images_upload_handler函数,说明用户上传的就是叫image.png的图片,让定时器执行上传完成即可。30 毫秒内触发了删除,定时器肯定要清除,可是图片还在编辑器内没删除,这时候就要执行removeFn。在下面备注也有写了,记得要用闭包,把image.png图片对应的success函数存起来。因为如果图片上传成功了,还得靠这个函数设置成对应的图片

// 定义2个全局变量let uploadTimeOut = nulllet removeFn = nulltinymce.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()}}})

大功告成~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。