返回

图像加载异常时怎么处理?教你优雅解决图片加载出错问题

前端

不同浏览器对加载失败图片的图标展示不统一,所以给定一个默认的失败图片就尤为重要。最近刚处理了一下公司首页图片 error 默认图片的问题,就趁着记忆没有消失分享一下这篇文章。

上述方法没有问题,不过需要我们手动管理图片,这样写的话维护成本可能很高,有可能你只是想为图片失败时展示一个loading图片或者一些比较友好的信息提示,例如:“图片正在加载中”。

.class{
  background-image: url(图片路径);
  background-size: cover; /*要么cover,要么contain*/
  background-position: center center;
}
.class:after{
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: #ddd; /*颜色根据图片容器或者图片本身自行选择*/
}

上面是一个图片加载时,图片加载失败提供一张默认图片,图片加载成功后,默认图片消失的代码。

优点:

1、兼容性好,支持各种浏览器。
2、代码简单,维护方便。
3、可以根据需要自定义默认图片。

缺点:

1、需要在 CSS 中添加额外的代码。
2、如果默认图片较大,可能会影响网页的加载速度。

如果在页面里面还有涉及到单张图片的话,需要单独给它们加上这种样式,不太方便,而且容易遗漏,容易造成一些图片没有默认样式的问题。再一个这种样式不方便在项目的组件化,样式混乱,别人不好维护。

我们可以用Vue指令来优化,我们可以将图片的url封装成一个组件,采用钩子函数检测图片的加载情况,如果加载成功,就移除loading的class,这样既能减少模板里的代码量也能使代码的维护更方便。

export default {
    name: 'ImgErrorLoad',
    props: {
        src: {
            type: String,
            required: true,
        },
    },
    data() {
        return {
            isError: false,
        }
    },
    mounted() {
        const img = new Image()
        img.src = this.src
        img.addEventListener('error', () => {
            this.isError = true
        })
    },
    render(h) {
        const attrs = {
            class: {
                error: this.isError,
            },
        }
        if (this.isError) {
            return <span class="no-img">图片加载失败</span>
        } else {
            return <img src={this.src} {...attrs}/>
        }
    },
}

上面我们封装了一个图片加载失败组件,我们只需要在模板里引用这个组件即可,而且可以在组件里给 图片加上 loading 的 class,这样就可以在加载图片时出现一个loading的样式,等图片加载成功后再把loading的class去掉。

使用组件的模板:

<div>
  <ImgErrorLoad src="https://img.alicdn.com/simba/img/TB1XYslp_1YBuNjy1zbXXXpepXa_!!0-item_pic.jpg_q50.jpg" />
</div>

使用上面组件的优点是代码维护更加方便,样式不再需要自己维护了,可以在组件里封装一个统一的loading样式。缺点是需要引入额外的组件库,并且封装的组件库依赖项目本身,很难再其他项目上使用。

如果只需要一些很简单的功能,例如:加载失败时,显示一张默认图片,可以采用CSS伪类选择器after来实现。如下:

.error-img{
  background-image: url(https://img.alicdn.com/simba/img/TB1XYslp_1YBuNjy1zbXXXpepXa_!!0-item_pic.jpg_q50.jpg);
  background-size: cover;
  background-position: center center;
}
.error-img:after{
  content: '';
  display: block;
  padding-top: 100%;
}
.error-img img{
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  object-fit: contain;
}

上面只是提供了一种解决方法,实际开发中,可能还会有其他更好的解决方法,希望本文能够对您有所帮助。