京东富文本详情图变形的多种处理方式(解决商品详情图片宽高不适应问题)
我前面写过一篇解析京东富文本详情的文章:
https://blog.csdn.net/qq_35610214/article/details/102468150
上面这篇文章是处理小程序无法显示京东商品详情的问题,处理方式有很多弊端,是把富文本详情图https地址正则解析下来后重新拼接image标签渲染新数据;上面方法目前不赞同使用,因为我有更好的解决方法;
问题概述
问题一:京东商品详情图片在移动端显示过大,显示不全,无法自适应(京东样式写死宽高导致)
问题二:京东商品详情图片比例缩放后外层容器整体高度无法缩短
代码适配端
uniapp开发的Android、Ios、H5、微信小程序、支付宝小程序、百度小程序、字节跳动小程序、qq小程序。(如有uniapp开放其它端的应用程序,可自行测试是否通用)
问题产生
需要处理的图片格式分为多种(目前所遇到的)
1、background-image:url('')显示的图片,宽高固定了px;
2、img标签显示的图片,<img width="750" 宽度固定了;
3、table标签内嵌img标签, <table width="640" 宽度固定了;
4、京东返回图片地址协议问题,出现同时使用https和http导致,例如:“https:http://xxxx.img.jpg”;
解决代码(代码不重要,重要的是思路)
html代码片段
1、给富文本的父容器添加类名 class="goods_desc"(方便js查找goods_desc对象);
2、goodsInfo.goods_desc是京东富文本数据;
3、添加动态变量(goodsDescStyle)用于绑定js操作的样式(这里需要记住,我们不需要太过于修改京东富文本详情原有数据,只需要修改外部容器的样式即可解决图片比例缩放问题);
<block v-if="goodsInfo.goods_desc">
<div v-html="goodsInfo.goods_desc" class="goods_desc" :style="goodsDescStyle"></div>
</block>
css代码片段
1、>>> 是样式穿透修饰符
2、修改goods_desc下面的所有img标签样式不包括有属性为usemap的标签;
例子:匹配 <img src="xxx.jpg"/>
不匹配 <img src="xxx.jpg" usemap=“xxx” />
.goods_desc >>> img:not([usemap]){width:100%;height:auto!important;}
javascript代码片段(重点)
// 获取goods_desc容器对象
uni.createSelectorQuery().select('.goods_desc').boundingClientRect((rect)=>{
// rect是goods_desc的返回值(包括宽高)
if(!rect){
//rect不存在则退出
return;
}
// goods_desc容器的宽度
let width = rect.width
// goods_desc容器的高度
let height = rect.height
//默认初始化京东富文本详情图片的宽度等于goods_desc容器的宽度
let goodsDescImgWdith = width
if(this.goodsInfo.goods_desc.indexOf('ssd-module-mobile-wrap') != -1){
// 第一种富文本类型处理方式
goodsDescImgWdith = 750
}else if(this.goodsInfo.goods_desc.indexOf('ssd-module-wrap') != -1){
// 第二种富文本类型处理方式
goodsDescImgWdith = 690
}else if(this.goodsInfo.goods_desc.indexOf('id=\"__01\"') != -1){
// 第三种富文本类型处理方式
goodsDescImgWdith = 690
}else if(this.goodsInfo.goods_desc.indexOf('<table width="640"') != -1){
this.goodsInfo.goods_desc = this.goodsInfo.goods_desc.replace(/usemap="#Map"/g,'usemap="#Map" width="640"')
// 第三种富文本类型处理方式
goodsDescImgWdith = 640
}
// 第四种富文本类型处理方式
this.goodsInfo.goods_desc = this.goodsInfo.goods_desc.replace(/https:http/g,'https')
// 在京东富文本详情图宽度和goods_desc容器宽度中两者取最小的值
let targetWidth = Math.min(goodsDescImgWdith, width);
// goods_desc缩放比例 = 最小的宽度值/京东富文本宽度值
let scaleValue = targetWidth/goodsDescImgWdith;
// 由于图片宽度缩放正常比例后会导致高度有一大片空白区域,所以高度也需要进行比例缩放拿到真实高度
// goods_desc容器的真实高度 = (缩放比例等于1说明比例无需缩放) 否则 (goods_desc容器的伪高度 * 缩放比例)
let parentHeight = scaleValue == 1? 'auto' : (height*scaleValue + 'px')
// 灵活运用css3样式,使用transform将goods_desc进行整体容器缩放,高度也正常缩放 得到最终的正常样式
this.goodsDescStyle = {
transformOrigin:"0px 0px", //初始化默认旋转元素位置点
transform:"scale(" + scaleValue + ")", //宽度比例缩放值
height:parentHeight //商品详情图正常高度
}
}).exec()
tips: this.goodsInfo.goods_desc是京东富文本详情数据。
1、先获取goods_desc容器对象,在网页中获取class可以使用document.getElementsByClassName,其原理一样;
2、然后返回rect结果,我们只取rect中的width(goods_desc容器宽度)和height(goods_desc容器高度)即可,拿到变量width和变量height,这两个值待会需要在下面做公式计算;
3、定义变量goodsDescImgWdith,是为了记录京东富文本详情图的实际宽度,先默认初始化为goods_desc自身的宽度,
如下图:
4、京东富文本详情图的宽度分为好几种类型(宽度值不同),我们只需要在对应的类型上做判断再定义宽度值赋值变量goodsDescImgWdith,目前发现的类型有以下几种
例一:class="ssd-module-mobile-wrap"的情况下,京东商品详情图实际的宽度是750px;
例二:class="ssd-module-wrap"的情况下,京东商品详情图实际的宽度是690px;
例三:id="__01"的情况下,京东商品详情图实际的宽度是690px;
例四:<table width="640"的情况下,京东商品详情图实际的宽度是640px,这里比较特殊的点是下面的img标签附带属性usemap="#Map"需要直接replace全局匹配替换成usemap="#Map" width="640";
5、京东商品详情返回了图片地址不正确,格式是这样的"https:http://xxxx.jpg",将https:http直接replace全局匹配替换成https;
6、我们现在将拿到的京东富文本详情图宽度,进行一个简单的公式
最小的宽度 = Math.min(京东富文本详情图宽度,goods_desc容器宽度);(在京东富文本详情图宽度和goods_desc容器宽度中两者取最小的值)
宽度比例缩放值 = 最小的宽度 / 京东富文本详情图实际宽度 ;
此时正确的宽度比例缩放值已经拿到,然后目前要做的是高度也要缩放,所以公式如下;
商品详情图正常高度 = goods_desc容器高度值 * 宽度比例缩放值 (结果单位为px)
详情图比例缩放值等于1的情况下说明京东富文本详情图宽度和goods_desc容器宽度相同(没有变形,图片正常),无需修改其高度;
这个时候我们通过公式换算已经拿到了宽度比例缩放值和商品详情图正常高度(px),只需要渲染到字段goodsDescStyle即可,其样式如下:
// 灵活运用css3样式,使用transform将goods_desc进行整体容器缩放,高度也正常缩放 得到最终的正常样式
this.goodsDescStyle = {
transformOrigin:"0px 0px", //初始化默认旋转元素位置点
transform:"scale(" + scaleValue + ")", //宽度比例缩放值
height:parentHeight //商品详情图正常高度
}
如果你使用的是uniapp,那么以上的代码你可以直接使用,如果使用的是其他框架,那么实现思路是一样的,京东有其他类型富文本格式错乱问题可以私信小鸿出解决方案哦~
本文地址:https://blog.csdn.net/qq_35610214/article/details/107163743