最近博客写道项目列表中,发现这里比较多图片,一开加载会比较慢,然后就想要用一个loading
的图片来占位。与此同时,如果图片加载失败那么显示错误的图片,不显示一个原有的错误,那样比较难看。
效果
原理解析
这个就是一个组件,一个图片展示的组件,直接更改img标签的url地址就好,对的,是这样的,在vue中直接更改地址,vue会有响应式的更新数据。
图片的事件
图片是有许多的事件的,例如,onload
, onerror
等,图片只要一加载就会调用onload的事件,不管是加载成功还是加载失败都会调用这个方法。而onerror
方法是图片在没有显示出来就会调用这个方法。从这两个方法对比可以得知,我们需要使用onload来一开始加载图片,并且图片可以成功,可以失败等。
组件代码
import { ImgHTMLAttributes } from "react";
export interface IImagProps<T> extends ImgHTMLAttributes<T> {
loadingImg?: string,
errorImg?: string,
src: string,
}
import React, { useState } from 'react'
// 下面这两个是导入默认的图片
import loadImg from './../../../assets/imgs/loading/load.gif';
import errorImg from './../../../assets/imgs/loading/error.png'
export default function Img(props: IImagProps<any>) {
// 图片地址
const [src, setSrc] = useState(props.loadingImg as string)
// 是否第一次加载,如果不使用这个会加载两次
const [isFlag, setIsFlag] = useState(false)
const handleOnLoad = () => {
// 判断是否第一次加载
if (isFlag) return;
// 创建一个img标签
const imgDom = new Image();
imgDom.src = props.src;
// 图片加载完成使用正常的图片
imgDom.onload = function () {
setIsFlag(true)
setSrc(props.src)
}
// 图片加载失败使用图片占位符
imgDom.onerror = function () {
setIsFlag(true)
setSrc(props.errorImg as string)
}
}
return (
<>
<img src={src}
onLoad={handleOnLoad}
style={{
height: 'inherit',
}}
></img>
</>
)
}
// 设置默认的图片加载中的样式和失败的图片
Img.defaultProps = {
loadingImg: loadImg,
errorImg: errorImg
}
PS:下面看下React中img图片加载完成前的loading效果
- 我在React中有这么一个需求,那就是我希望在图片加载完成前的时候一直显示loading动画效果,等图片加载完成了就实现图片的渲染
- 先讲讲具体的思路,再来说说实际的应用
- 实现思路:
// 假设我要加载这三张网页图片
var imglist = ['http://example.com/demo1.png','http://example.com/demo2.png','http://example.com/demo3.png']
// images 使用用来存储 加载完成的图片的
var images = []
imglist.forEach(el=>{
var image = new Image()
image.src = el
image.onload = function(){
// 说明图片image加载完成了
// 将加载完成的image添加到images中
images.push(image)
}
})
// 在组件渲染的时候进行判断
if(images.length === 3){
// 说明此时三张网页图片已经全部加载完成了,可以进行渲染了
// 渲染加载完成的图片
}else{
// 说明此时网页图片还没有全部加载完成,这时候接着loadding动画效果
// loadding动画效果
}
具体实现的例子
import React from 'react'
import { Carousel, Spin } from 'antd' // 使用antd
// 创建 Home组件
class Home extends React.Component{
constructor(props){
super(props)
this.state = {
imglist: [
{
id: '01',
src: 'http://example.com/demo1.png',
alt: 'demo1'
},
{
id: '02',
src: 'http://example.com/demo2.png',
alt: 'demo2'
},
{
id: '03',
src: 'http://example.com/demo3.png',
alt: 'demo3'
}
],
images: []
}
}
UNSAFE_componentWillMount(){
// 在渲染之前进行操作
var { imglist } = this.state
var images = []
imglist.forEach(el=>{
var image = new Image()
image.src = el.src
image.onload = ()=>{
images.push(image)
this.setState({
images
})
}
})
}
render(){
var { imglist, images } = this.state
if(images.length === 3){
// 说明三张图片已经全部加载完成,这个时候已经可以渲染图片了
return (
<div className='common-body'>
<Carousel autoplay>
{imglist.map(el=>(
<img src={el.src} key={el.id} alt={el.alt} />
))}
</Carousel>
</div>
)
}else{
// 说明图片还没有全部加载完成,这个时候要显示loading动画效果
return (
<div className='common-loading'>
<Spin tip='Loading...' size='large'></Spin>
</div>
)
}
}
}
export default Home
这个方法还是比较好用的
以上就是react 实现图片正在加载中 加载完成 加载失败三个阶段的原理解析的详细内容,更多关于react图片加载完成的资料请关注编程网其它相关文章!