问题背景
若一个页面下有以下几张图片
[A, A, A, B]
通过 wx.previewImage
预览时,由于 current
只支持 string
类型,点击A
图片时,不管是哪一张,都会被认为是第一张(即右滑时还是 A
图片)
要解决这个问题,必须使得相同 src
的图片能被区分开
方案一
- 主要思想
给图片链接后加一个没有用的参数使得图片链接各不相同
如上题中将链接变为
[A, A?id=1, A?id=2, B]
即可解决这个问题 - 缺陷
加上参数后每个图片都要被请求一次(不能被缓存),增加了请求次数
方案二
- 主要思想
在预览时删除重复的图片
如图片为 [A, B, A, C] ,则在预览第一张A
图片时urls
传入 [A, B, C],在预览第二张A
图片时传入 [B, A, C] - 缺陷
- 无法通过左右滑动看到重复的图片
- 若是开头的例子仍会出现不管点哪一张
A
图片都会是右滑后就是B
图片,无法区分
方案三
-
主要思想
indexOf
是区分大小写的,而链接一般不区分大小写,因此可以把链接的一部分改为大写来区分 -
具体分析
wx.previewImage
只支持网络链接,网络链接的一般结构为[协议]://[域名]/[路径]
,其中协议和域名是不区分大小写的,而路径则可能影响。因此可以将协议和域名的大小写重新组合实现链接的不同,但显示的是同一张图片,例如传入的urls
为
[“http://example.com”, “http://example.com”]
可以修改为
[“http://example.com”, “Http://example.com”]
这样就可以区分开,通过协议+域名的大小写重新组合,一般可以提供足够多不同的src
(有2^n
种) -
优点
- 可以实现同方案一的效果,预览重复的图片不会定位错误
- 不更改图片链接,不会产生多余的请求
-
程序实现
function previewImage(object) { console.log("修改前:", object.urls); var urls = []; for (var i = 0; i < object.urls.length; i++) { var url = object.urls[i]; // 网络链接 if (/:\/\//.test(object.urls[i])) { // 有重复 while (urls.indexOf(url) != -1) { var j; url = ""; for (j = 0; j < object.urls[i].length; j++) { var c = object.urls[i][j]; // 这里直接用了random函数来确定大小写,因为协议+域名通常在10位以上,有大于1000种可能,重复概率低 if (/[a-zA-Z]/.test(c)) url += (Math.random() >= 0.5 ? c.toUpperCase() : c); else url += c; if (c == '/' && object.urls[i][j - 1] != '/' && object.urls[i][j + 1] != '/') break; } url += object.urls[i].substr(j + 1); //路径部分直接添加 } } urls.push(url); } console.log("修改后:", urls); wx.previewImage({ current: urls[object.current], urls, success: object.success, fail: object.fail }) } previewImage({ current: 1, urls: ["https://www.baidu.com/img/bd_logo1.png", "https://www.baidu.com/img/bd_logo1.png"] })
这个函数可以实现current
直接传入索引值,并且存在多张相同图片时,不会定位错误(如这个示例中设置了current
为1
,则预览时只能左滑查看第0
张,无法右滑)
ps: 如果只是在wx.previewImage
中使用,协议和域名都不区分大小写,但是如果在image
组件的src
中使用,协议必须小写(否则无法显示),只能对域名进行修改