wangEditor5问题 您所在的位置:网站首页 复制粘贴图片显示不出来 wangEditor5问题

wangEditor5问题

2024-02-29 02:09| 来源: 网络整理| 查看: 265

问题

从网页上复制图文,粘贴到wangEditor富文本编辑器,图片丢失

image.png

image.png

分析

粘贴板上的html:

Game: Real Car Crash CompilationGenre: SimulationPackage Link: https://play.google.com/store/apps/details?id=com.crash.car.mgt;hl=en;gl=USVideo Link: -Video Time: -Content Description: Insane Car Crash!Title: Buckle Up and Get Ready to Crash Your Super Car!CoverHighlight

wangEditor富文本编辑器渲染后:

image.png 如上可知,源html b标签内的文本被全部抽取渲染在span内

寻求帮助 1、github issue

wangEditor5 常见问题汇总

image.png 需要调用方自己实现,未查询到有已实现的范例!

作者有对这个问题做说明: 开源编辑器 wangEditor5 发布两个月总结(官网诚接广告,攒钱租服务器)

2、搜索引擎

wangEditor粘贴从word复制的带图片内容的最佳实践

image.png

解决从word复制粘贴图片丢失的问题,但原因和我的不一样,这里是因为图片标签和内容分离,只粘贴了标签。最终还是调用的dangerouslyInsertHtml

查看源码 1、监听粘贴事件

image.png

image.png

2、insertData

image.png

粘贴最终调用的还是dangerouslyInsertHtml

3、dangerouslyInsertHtml

image.png

源html主要的内容都放在了b标签内,我们跟踪dangerouslyInsertHtml,看b标签会走到哪

image.png

b被作为文本标签 image.png

4、parseElemHtml

image.png

5、 parseTextElemHtml

image.png 由上可知,会将b标签内的文本都取出,生成一个text node

从以上分析可知,问题的原因在于,复制的图文是被b标签包裹的,而b被wangEditor视为文本标签,只取其中的文本渲染。

解决 1、重写dangerouslyInsertHtml

wangEditor无法兼容所有的 HTML 格式,这一点官方文档有特别标红说明。也就是说,我们在编辑器输入内容时,wangEdior 会做一些处理(过滤,筛选,转换等)。

作者是因为html格式非常灵活,不可能全部支持!那我们调用方想要支持各种粘贴的场景,实现起来首先得了解wangEditor的dom -> slate node的转换规则和类型,然后扩展。 这需要对wangEditor的实现原理有深入的了解,且听下回分解。

2、 改造源html的dom结构,使其适配wangEditor的转换规则 /** * 遍历html节点,将TEXT_TAGS节点且包含图片子节点的替换成p * @param html */ const replaceTextNodeToBlock = (html: string) => { if(!html) { return ''; } const div = document.createElement('div'); div.innerHTML = html; div.setAttribute('hidden', 'true'); document.body.appendChild(div); const imgs = div.querySelectorAll('img'); if(!imgs || !imgs.length) { document.body.removeChild(div); return html; } [...imgs].forEach(img => { let parentN = img.parentNode; while(parentN && parentN !== div) { if(TEXT_TAGS.includes(parentN.nodeName.toLowerCase())) { const p = document.createElement('p'); const { innerHTML, attributes } = (parentN); p.innerHTML = innerHTML; if(attributes && attributes.length) { console.log('attributes: ', attributes); // eslint-disable-next-line no-restricted-syntax for(const attribute of attributes) { p.setAttribute(attribute.nodeName, attribute.nodeValue as string); } } parentN.parentNode?.replaceChild(p, parentN); parentN = p.parentNode; } else { parentN = parentN.parentNode; } } }); const returnHtml = div.innerHTML; document.body.removeChild(div); return returnHtml; }; /** * 自定义粘贴。可阻止编辑器的默认粘贴,实现自己的粘贴逻辑。 * @param editor * @param event * @returns */ export const handleCustomPaste = (editor: IDomEditor, event: ClipboardEvent): boolean => { console.log('handleCustomPaste: ', editor); // 获取粘贴的html部分(??没错粘贴word时候,一部分内容就是html),该部分包含了图片img标签 let html = (event.clipboardData as DataTransfer).getData('text/html'); console.log('text/html: ', html); if(!html) { return true; } // 获取rtf数据(从word、wps复制粘贴时有),复制粘贴过程中图片的数据就保存在rtf中 const rtf = (event.clipboardData as DataTransfer).getData('text/rtf'); console.log('text/rtf: ', rtf); // 从html内容中查找粘贴内容中是否有图片元素,并返回img标签的属性src值的集合 const imgSrcs = findAllImgSrcsFromHtml(html); // 没有图片 if(!imgSrcs || !Array.isArray(imgSrcs) || !imgSrcs.length) { return true; } if(rtf) { // 该条件分支即表示要自定义word粘贴 // 列表缩进会超出边框,直接过滤掉 html = html.replace(/text-indent:-(.*?)pt/gi, ''); // 从rtf内容中查找图片数据 const rtfImageData = extractImageDataFromRtf(rtf); // 如果找到 if (rtfImageData.length) { // TODO:此处可以将图片上传到自己的服务器上 // 执行替换:将html内容中的img标签的src替换成ref中的图片数据,如果上面上传了则为图片路径 html = replaceImagesFileSourceWithInlineRepresentation(html, imgSrcs, rtfImageData) console.log('result: ', html); editor.dangerouslyInsertHtml(html); // 阻止默认的粘贴行为 event.preventDefault(); return false; } } else { const newHtml = replaceTextNodeToBlock(html); console.log('处理深层次嵌套图片: ', newHtml); editor.dangerouslyInsertHtml(newHtml); // 阻止默认的粘贴行为 event.preventDefault(); return false; } return true; }; 引申其他问题 - office复制的图片还是会丢失,wps不会

对比两者复制出的html内容 image.png 左侧为office,右侧为wps

经调试发现问题出在没识别出office的html中包含img标签,原来是正则的问题,office的html会包含换行 于是将源html去掉换行再进行正则匹配:

/** * 从html代码中匹配返回图片标签img的属性src的值的集合 * @param htmlData * @return Array */ const findAllImgSrcsFromHtml = (htmlData: string) => { const imgReg = /|\/>)/gi; // 匹配图片中的img标签 const arr = htmlData.replace(/[\r\n]/g, ' ').match(imgReg); // 筛选出所有的img if (!arr || (Array.isArray(arr) && !arr.length)) { return false; } const srcArr = []; const srcReg = /src=['"]?([^'"]*)['"]?/i; // 匹配图片中的src for (let i = 0; i < arr.length; i++) { const src = arr[i].match(srcReg); // 获取图片地址 src && src.length && srcArr.push(src[1]); } return srcArr; }

但是,图片还是没出现!原因是替换src后的图片还是嵌套在文本标签内,需要做replaceTextNodeToBlock处理:

/** * 自定义粘贴。可阻止编辑器的默认粘贴,实现自己的粘贴逻辑。 * @param editor * @param event * @returns */ export const handleCustomPaste = (editor: IDomEditor, event: ClipboardEvent): boolean => { console.log('handleCustomPaste: ', editor); // 获取粘贴的html部分(??没错粘贴word时候,一部分内容就是html),该部分包含了图片img标签 let html = (event.clipboardData as DataTransfer).getData('text/html'); console.log('text/html: ', html); if(!html) { return true; } // 获取rtf数据(从word、wps复制粘贴时有),复制粘贴过程中图片的数据就保存在rtf中 const rtf = (event.clipboardData as DataTransfer).getData('text/rtf'); console.log('text/rtf: ', rtf); // 从html内容中查找粘贴内容中是否有图片元素,并返回img标签的属性src值的集合 const imgSrcs = findAllImgSrcsFromHtml(html); // 没有图片 if(!imgSrcs || !Array.isArray(imgSrcs) || !imgSrcs.length) { return true; } if(rtf) { // 该条件分支即表示要自定义word粘贴 // 列表缩进会超出边框,直接过滤掉 html = html.replace(/text-indent:-(.*?)pt/gi, ''); // 从rtf内容中查找图片数据 const rtfImageData = extractImageDataFromRtf(rtf); // 如果找到 if (rtfImageData.length) { // TODO:此处可以将图片上传到自己的服务器上 // 执行替换:将html内容中的img标签的src替换成ref中的图片数据,如果上面上传了则为图片路径 html = replaceImagesFileSourceWithInlineRepresentation(html, imgSrcs, rtfImageData) console.log('result: ', html); editor.dangerouslyInsertHtml(html); // 阻止默认的粘贴行为 event.preventDefault(); return false; } } else { const newHtml = replaceTextNodeToBlock(html); console.log('处理深层次嵌套图片: ', newHtml); editor.dangerouslyInsertHtml(newHtml); // 阻止默认的粘贴行为 event.preventDefault(); return false; } return true; };


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有