描述:
在使用wxParse(version 0.3)微信小程序插件过程中,当原文内容包含图片时,wxParse对图片的转换将通过wxml中image标签的bindload事件获取图片的存储本身的宽高尺寸,进而判断该宽度与屏幕(窗口)宽度的大小,将较小者设置为图片转换后的宽度,高度则根据该宽度按图片原宽高比例进行缩小或不变。
这样的处理方式存在一个弊端,就是当原文图片设置了width、height等样式时,插件将会忽略该设置,只依据图片存储本身的宽高(如图1)来做设置。
(图1)
那么如何将富文本中对图片所做的宽高设置通过wxParse转换到微信小程序中呢?本篇文章将介绍本人对该弊端的一个优化处理。
思路:
插件对富文本的每一张图片的相关信息都记录到了一个 images 数组当中(该数组包含了图片的width、height等style信息)。在图片触发load事件时,在load的处理方法内将会调用图片尺寸自适应计算的方法,而在做自适应计算时,就可以根据当前图片load出的数据与该图片在images中的数组元素的数据进行处理。此时判断富文本原文是否有width、height设置,有的话就进入到新的宽高处理方式中计算百分比、固定像素等样式;无的话则按原插件逻辑对图片进行宽高计算。
使用前提:
对于图片元素的style样式,这里有个局限性。样式属性的键和值之间需要有一个“空格”来分隔、不同样式属性之间需要有一个“空格”来分隔。
例如:style="width: 100px; height: 100px;"
在html2json.js文件的第124行对style属性值进行了处理,用空格来把属性字符串分隔成数组。如果style属性值未按上述格式分隔开,将导致样式处理无法生效。
在小程序使用wxParse的情景中,html元素数据大都由富文本编辑器生成。建议使用UEditor、summernote富文本编辑器,其生成的style样式将可以完美兼容此版本的功能优化。
具体实现:
wxParse.js文件的wxAutoImageCal方法为图片宽高定义的主方法,在wxAutoImageCal方法增加一个传参temImage,用于传递富文本原文img图片标签的数据,如style。wxAutoImageCal方法内部提取出temImage参数中附带的width、height等数据,再依据宽高值的类型(px还是%)去做判断,从而针对性设置符合需求的宽高。
// 计算视觉优先的图片宽高(对比原插件,加入了图片原文style的宽高设置,包含以%、px结尾的匹配设置)
function wxAutoImageCal(originalWidth, originalHeight,that,bindName,temImage) {
console.log(temImage);
var arr = temImage.attr.style;
var widthIndex = arr.indexOf("width:");
var widthValue = '';
if (widthIndex != -1) {
widthValue = arr[widthIndex+1];
}
var percentageIndex = widthValue.search("%;");
var pixelIndex = widthValue.search("px;");
var percentageWidthValue = '';
var pixelWidthValue = '';
var pixelHeightValue = '';
/**
* 获取width的百分比数值
* 因为widthValue是带有%和;的,例如宽度为50%,那么widthValue的数据格式为widthValue == "50%;",
* 因此多出来后面两个字符'%;',所以要去除后面两位
*/
if ((percentageIndex > 0) && (widthValue.length == percentageIndex+2)) {
percentageWidthValue = widthValue.slice(0,-2);
}
/**
* 获取width的px数值
* 因为widthValue是带有px和;的,例如宽度为50px,那么widthValue的数据格式为widthValue == "50px;",
* 因此多出来后面三个字符'px;',所以要去除后面三位,
* 而当width为px显示时,height和width是成对出现的
*/
if ((pixelIndex > 0) && (widthValue.length == pixelIndex+3)) {
pixelWidthValue = widthValue.slice(0,-3);
var heightIndex = arr.indexOf("height:");
var heightValue = '';
if (heightIndex != -1) {
heightValue = arr[heightIndex+1];
}
var pixelHeightIndex = heightValue.search("px;");
if ((pixelHeightIndex > 0) && (heightValue.length == pixelHeightIndex+3)) {
pixelHeightValue = heightValue.slice(0,-3);
}
}
//获取图片的原始长宽
var windowWidth = 0, windowHeight = 0;
var autoWidth = 0, autoHeight = 0;
var results = {};
var padding = that.data[bindName].view.imagePadding;
windowWidth = realWindowWidth-2*padding;
windowHeight = realWindowHeight;
/**
* 1、如果图片的宽度style是百分比的参数形式,那么图片在微信中展示的宽度就定义为 手机屏幕宽度*宽度百分比;
* 2、如果图片的宽度style是px的参数形式,并且该宽度小于屏幕宽度,那么图片在微信中展示的宽、高就定义为 style所设置的宽、高;
* 3、此外,则按原插件逻辑进行图片大小定义,在图片width大于手机屏幕width时等比例缩放至屏幕大小,
* 未大于手机屏幕width时则按图片原尺寸显示
*/
if (percentageWidthValue) {
autoWidth = (windowWidth * percentageWidthValue) / 100;
autoHeight = (autoWidth * originalHeight) / originalWidth;
results.imageWidth = autoWidth;
results.imageheight = autoHeight;
} else if (pixelWidthValue && pixelHeightValue && (pixelWidthValue <= windowWidth)) {
results.imageWidth = pixelWidthValue;
results.imageheight = pixelHeightValue;
} else {
//判断按照那种方式进行缩放
// console.log("windowWidth" + windowWidth);
if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
autoWidth = windowWidth;
// console.log("autoWidth" + autoWidth);
autoHeight = (autoWidth * originalHeight) / originalWidth;
// console.log("autoHeight" + autoHeight);
results.imageWidth = autoWidth;
results.imageheight = autoHeight;
} else {//否则展示原来的数据
results.imageWidth = originalWidth;
results.imageheight = originalHeight;
}
}
return results;
}
,temImage) {
console.log(temImage);
var arr = temImage.attr.style;
var widthIndex = arr.indexOf("width:");
var widthValue = '';
if (widthIndex != -1) {
widthValue = arr[widthIndex+1];
}
var percentageIndex = widthValue.search("%;");
var pixelIndex = widthValue.search("px;");
var percentageWidthValue = '';
var pixelWidthValue = '';
var pixelHeightValue = '';
/**
* 获取width的百分比数值
* 因为widthValue是带有%和;的,例如宽度为50%,那么widthValue的数据格式为widthValue == "50%;",
* 因此多出来后面两个字符'%;',所以要去除后面两位
*/
if ((percentageIndex > 0) && (widthValue.length == percentageIndex+2)) {
percentageWidthValue = widthValue.slice(0,-2);
}
/**
* 获取width的px数值
* 因为widthValue是带有px和;的,例如宽度为50px,那么widthValue的数据格式为widthValue == "50px;",
* 因此多出来后面三个字符'px;',所以要去除后面三位,
* 而当width为px显示时,height和width是成对出现的
*/
if ((pixelIndex > 0) && (widthValue.length == pixelIndex+3)) {
pixelWidthValue = widthValue.slice(0,-3);
var heightIndex = arr.indexOf("height:");
var heightValue = '';
if (heightIndex != -1) {
heightValue = arr[heightIndex+1];
}
var pixelHeightIndex = heightValue.search("px;");
if ((pixelHeightIndex > 0) && (heightValue.length == pixelHeightIndex+3)) {
pixelHeightValue = heightValue.slice(0,-3);
}
}
//获取图片的原始长宽
var windowWidth = 0, windowHeight = 0;
var autoWidth = 0, autoHeight = 0;
var results = {};
var padding = that.data[bindName].view.imagePadding;
windowWidth = realWindowWidth-2*padding;
windowHeight = realWindowHeight;
/**
* 1、如果图片的宽度style是百分比的参数形式,那么图片在微信中展示的宽度就定义为 手机屏幕宽度*宽度百分比;
* 2、如果图片的宽度style是px的参数形式,并且该宽度小于屏幕宽度,那么图片在微信中展示的宽、高就定义为 style所设置的宽、高;
* 3、此外,则按原插件逻辑进行图片大小定义,在图片width大于手机屏幕width时等比例缩放至屏幕大小,
* 未大于手机屏幕width时则按图片原尺寸显示
*/
if (percentageWidthValue) {
autoWidth = (windowWidth * percentageWidthValue) / 100;
autoHeight = (autoWidth * originalHeight) / originalWidth;
results.imageWidth = autoWidth;
results.imageheight = autoHeight;
} else if (pixelWidthValue && pixelHeightValue && (pixelWidthValue <= windowWidth)) {
results.imageWidth = pixelWidthValue;
results.imageheight = pixelHeightValue;
} else {
//判断按照那种方式进行缩放
// console.log("windowWidth" + windowWidth);
if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
autoWidth = windowWidth;
// console.log("autoWidth" + autoWidth);
autoHeight = (autoWidth * originalHeight) / originalWidth;
// console.log("autoHeight" + autoHeight);
results.imageWidth = autoWidth;
results.imageheight = autoHeight;
} else {//否则展示原来的数据
results.imageWidth = originalWidth;
results.imageheight = originalHeight;
}
}
return results;
}
在wxAutoImageCal方法的调用处加入图片数据(temImage变量)
// 假循环获取计算图片视觉最佳宽高
function calMoreImageInfo(e, idx, that, bindName) {
var temData = that.data[bindName];
if (!temData || temData.images.length == 0) {
return;
}
var temImages = temData.images;
//因为无法获取view宽度 需要自定义padding进行计算,稍后处理
var recal = wxAutoImageCal(e.detail.width, e.detail.height,that,bindName,temImages[idx]);
// temImages[idx].width = recal.imageWidth;
// temImages[idx].height = recal.imageheight;
// temData.images = temImages;
// var bindData = {};
// bindData[bindName] = temData;
// that.setData(bindData);
var index = temImages[idx].index
var key = `${bindName}`
for (var i of index.split('.')) key+=`.nodes[${i}]`
var keyW = key + '.width'
var keyH = key + '.height'
that.setData({
[keyW]: recal.imageWidth,
[keyH]: recal.imageheight,
})
}
,temImages[idx]);
// temImages[idx].width = recal.imageWidth;
// temImages[idx].height = recal.imageheight;
// temData.images = temImages;
// var bindData = {};
// bindData[bindName] = temData;
// that.setData(bindData);
var index = temImages[idx].index
var key = `${bindName}`
for (var i of index.split('.')) key+=`.nodes[${i}]`
var keyW = key + '.width'
var keyH = key + '.height'
that.setData({
[keyW]: recal.imageWidth,
[keyH]: recal.imageheight,
})
}
补充说明:
wxParse非本人原创,本人充分尊重原著作者的程序编码,如对原著版权造成不良影响,请联系本人删除优化内容。
感谢使用!希望本文能够对广大微信小程序开发者带来帮助。如有更好的优化方案,欢迎各开发者发文交流。
如需优化源码,可以在评论中加以说明。
-------------------------------------
作者:TGY——一个IT男的画意诗情
来源:CSDN