由于从微信复制富文本内容到UEditor时,微信富文本编辑器会将width转换为固定宽度,导致UEditor上传微信的富文本内容到移动端后无法实现自适应宽度,刚开始时以为问题出在UEditor编辑器内,但后来经过测试发现坑是在微信编辑器里:
如图,我将微信富文本内容复制到另一个微信的富文本上,查看html代码,发现一样会将百分比宽度转换为固定宽度,所以问题是出在微信编辑器的copy事件上。也就是说百分比转换为固定宽度是无法避免的,因为我们无法重定义微信富文本的copy事件。
但微信富文本编辑器同时提供了一个data-width属性,它的属性值和width是相等的,只是以百分比的形式保存起来了。
所以问题就是如何把标签的data-width属性值替换width的属性值
这里附上两个正则表达式实现标签的固定宽度转换为百分比宽度,只适用于同时包含data-width属性和width属性的标签。标签的data-width属性值会赋值给width属性:
// 获取富文本内容并传入函数中
function adjustMobileHtml(htmlContent){
// 当data-width属性在width属性前面时匹配
const beforeDataWidth = /((<(section|img|div|p|span|ul|li)[\s\S]*?data-width="([1-9]\d*\.?\d*%)"[\s\S]*?width:\s)([1-9]\d*\.?\d*px)([\s\S]*?>))/mig
// 当data-width属性在width属性后面时匹配
const afterDataWidth = /((<(section|img|div|p|span|ul|li)[\s\S]*?width:\s)([1-9]\d*\.?\d*px)([\s\S]*?data-width="([1-9]\d*\.?\d*%)([\s\S]*?>)))/mig
const adjustHtmlContent = htmlContent.replace(beforeDataWidth,'$2$4$6')
const result = adjustHtmlContent.replace(afterDataWidth,'$2$6$5')
return result
}
第二种更好的解决方法
直接获取dom节点并更改dom节点属性值即可,相比通过正则表达式的方式而言,这种方法在更易于维护
export function adjustHtmlContent(content){
let ctx = $(document.createElement('section')).html(content)[0]
console.log('ctx',ctx.getElementsByTagName('section'));
// document.getElementsByTagName('section')
let SECTION = ctx.querySelectorAll('section')
for(let i=0;i<SECTION.length;i++){
if(SECTION[i].getAttribute('data-width')){
let data_width = SECTION[i].getAttribute('data-width')
SECTION[i].style.width = data_width
}
}
let IMG = ctx.querySelectorAll('img')
for(let i=0;i<IMG.length;i++){
if(IMG[i].getAttribute('data-width')){
let inner_data_width_value = IMG[i].getAttribute('data-width')
// 当img标签的父节点存在data-width属性时,子img标签的width设置为img的data-width属性值
if(IMG[i].parentNode.getAttribute('data-width')){
IMG[i].style["width"] = inner_data_width_value;
}else {
if(/[/s/S]*?%/.test(IMG[i].style["width"])){
return
}
// 当img的父节点不存在data-width属性时,img的width设置为width/574 px
let data_width_value = parseFloat(IMG[i].style["width"])/574;
IMG[i].style["width"] = (data_width_value)*100 + '%';
}
}
}
return $(ctx).html();
}