小程序的图片组件本身有个加载失败的绑定事件为 binderror
,所以本方案就是要在该绑定的事件中做文章。
首先,给图片绑定加载失败事件,wxml 及 js 代码分别如下:
<!-- 普通图片 -->
<image class="full-width" src="{{imgUrl}}" mode="widthFix" binderror="bindImgErr" data-resrc="{{imgUrl}}" data-name="imgUrl" lazy-load="false"></image>
page({
bindImgErr(e) {
const { name, resrc } = e.currentTarget.dataset;
this.setData({
[name]: resrc
})
}
})
以上代码看起来是没问题的,然后实际情况却并不如此。下面简单说下具体碰到的问题:
图片失败后并不会自动重试一次
由于 data-resrc
中的图片地址与 src
的图片地址一致,所以图片并不会自动重试加载。所以要对 resrc
的地址进行加工,如加个参数 t=1
page({
bindImgErr(e) {
const { name, resrc } = e.currentTarget.dataset;
// 只重试一次
if (!resrc.includes('t=1')) {
let url = '';
if (resrc.includes('?')) {
url = `${resrc}&t=1`;
} else {
url = `${resrc}?t=1`;
}
this.setData({
name: url,
});
}
}
})
图片地址
上面示例的图片地址仅仅是我们常见的一种形式,实际情况中,我们可能会遇到图片地址出现在数组,对象等复杂场景,如下:
page({
data: {
imgUrl: 'https://xxx.xxx.com',
imgUrls: ['https://xxx.xxx.com', 'https://xxx.xxx.com', 'https://xxx.xxx.com'],
product: {
imgUrl: 'https://xxx.xxx.com',
}
}
})
所以还需要对 name
进行进一步处理:
<!-- 普通图片 -->
<image class="full-width" src="{{imgUrl}}" mode="widthFix" binderror="bindImgErr" data-resrc="{{imgUrl}}" data-name="imgUrl" lazy-load="false"></image>
<!-- 数组 -->
<view wx:for="{{imgUrls}}">
<image class="full-width" src="{{item}}" mode="widthFix" binderror="bindImgErr" data-resrc="{{item}}" data-name="imgUrl[{{index}}]" lazy-load="false"></image>
</view>
<!-- 对象 -->
<image class="full-width" src="{{product.imgUrl}}" mode="widthFix" binderror="bindImgErr" data-resrc="{{product.imgUrl}}" data-name="product.imgUrl" lazy-load="false"></image>
page({
bindImgErr(e) {
const { name, resrc } = e.currentTarget.dataset;
// 只重试一次
if (!resrc.includes('t=1')) {
let url = '';
if (resrc.includes('?')) {
url = `${resrc}&t=1`;
} else {
url = `${resrc}?t=1`;
}
this.setData({
[`${name}`]: url,
});
}
}
})