react 实现图片正在加载中 加载完成 加载失败三个阶段的原理解析

最近博客写道项目列表中,发现这里比较多图片,一开加载会比较慢,然后就想要用一个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图片加载完成的资料请关注我们其它相关文章!

(0)

相关推荐

  • react-native ListView下拉刷新上拉加载实现代码

    本文介绍了react-native ListView下拉刷新上拉加载实现.分享给大家,具体如下: 先看效果图 下拉刷新 React Native提供了一个组件可以实现下拉刷新方法RefreshControl 使用方法 <ListView refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this._onRefresh.bind(this)} /> } //... </List

  • React 路由懒加载的几种实现方案

    这篇文字简单的介绍了React在路由懒加载方面的几种实现方案. 传统的两种方式 import() 符合ECMAScript提议的import()语法,该提案与普通 import 语句或 require 函数的类似,但返回一个 Promise 对象.这意味着模块时异步加载的 webpack v2+ 使用 使用方式 function component() { return import( /* webpackChunkName: "lodash" */ 'lodash').then(_

  • React Native 自定义下拉刷新上拉加载的列表的示例

    在移动端开发中列表页是非常常见的页面,在React Native中我们一般使用FlatList或SectionList组件实现这些列表视图.通常列表页都会有大量的数据需要加载显示,这时候就用到了分页加载,因此对于列表组件来说,实现下拉刷新和上拉加载在很多情况下是必不可少的. 本篇文章基于FlatList封装一个支持下拉刷新和上拉加载的RefreshListView,对原始的FlatList进行封装之后,再调用上拉和下拉刷新就十分方便了. 下拉刷新的实现十分简单,这里我们沿用FlatList本身的

  • 详解React开发中使用require.ensure()按需加载ES6组件

    首先介绍下动态加载函数: require.ensure([], (require)=>{ let A = require('./a.js').default; }) 如果想要动态加载出es6代码组件,直接require一个es6风格的组件是不行的,因为一般的语言编译工具(如babel),不支持直接require一个es6风格的组件. 那么有种办法可以解决:在es6方式书写的组件底部增加一句:module.exports = YouclassName; import React, {Compone

  • React-router 4 按需加载的实现方式及原理详解

    React-router 4 介绍了在router4以后,如何去实现按需加载Component,在router4以前,我们是使用getComponent的的方式来实现按需加载的,router4中,getComponent方法已经被移除,下面就介绍一下react-router4是入围和来实现按需加载的. 1.router3的按需加载方式 route3中实现按需加载只需要按照下面代码的方式实现就可以了. const about = (location, cb) => { require.ensure

  • react native基于FlatList下拉刷新上拉加载实现代码示例

    react native 的上拉加载一直困扰着自己,一直用的第三方组件,但是可维护性不高,而且也不太好用,最近工作没那么忙,就研究下了官方的FlatList,做出来的成果,比第三方组件流畅度高好多,而且也很好用 官方介绍:https://reactnative.cn/docs/flatlist/ 下面是效果图: ios效果图 android效果图 总体思路就是:就是计算屏幕高度,然后减去导航的头部,根据列表高度计算出每页的个数,然后向上取整.这样做的目的是:防止不满屏状态下的,onEndReac

  • react 实现图片正在加载中 加载完成 加载失败三个阶段的原理解析

    最近博客写道项目列表中,发现这里比较多图片,一开加载会比较慢,然后就想要用一个loading的图片来占位.与此同时,如果图片加载失败那么显示错误的图片,不显示一个原有的错误,那样比较难看. 效果 原理解析 这个就是一个组件,一个图片展示的组件,直接更改img标签的url地址就好,对的,是这样的,在vue中直接更改地址,vue会有响应式的更新数据. 图片的事件 图片是有许多的事件的,例如,onload, onerror等,图片只要一加载就会调用onload的事件,不管是加载成功还是加载失败都会调用

  • Android加载大分辨率图片到手机内存中的实例方法

    还原堆内存溢出的错误首先来还原一下堆内存溢出的错误.首先在SD卡上放一张照片,分辨率为(3776 X 2520),大小为3.88MB,是我自己用相机拍的一张照片.应用的布局很简单,一个Button一个ImageView,然后按照常规的方式,使用BitmapFactory加载一张照片并使用一个ImageView展示. 代码如下: 复制代码 代码如下: btn_loadimage.setOnClickListener(new View.OnClickListener() { @Override   

  • 使用加载图片解决在Ajax数据加载中页面出现短暂空白的问题(推荐)

    在项目中用ajax异步获取数据后有时会因为数据问题或者网络问题,页面一直显示空白,现在用加载图片来过渡这种状态: <script> $(function(){ $.ajax({ url:'',//提供接口的文件地址链接 dataType:'json', type:'POST', beforeSend: function(){ $('#loading').html("<img src=\"images/loading.gif\" width=\"15

  • vue中img src 动态加载本地json的图片路径写法

    目录: 注意:本地json文件和json文件里的图片地址都必须写在static 静态文件夹里:否则json文件里的url地址找不到. major_info.json文件里的图片路径写法 页面通过v-bind的方式加载: PS:vue中图片src路径赋值 vue中引入static文件夹中图片,本以为src中直接写入图片所在路径即可,结果发现图片无法显示,控制台报404错误,图片无法找到.网上找到解决方案,在此mark一下,以便以后查询. 图片src路径动态赋值 <img class="thu

  • 关于JS与jQuery中的文档加载问题

    jquery中的$(document).ready()类似于javascript中的window.onload(),但是其中还是有很大区别的 1.jquery中的可以简化为$().ready(),$(function),   而js却不行必须全部写完. 2.同时js的window.onload()只能有一个,而jquery的$(document).ready()却可以有多个. 3.最重要的一点是window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行.   $(documen

  • JavaScript中的无阻塞加载性能优化方案

    Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理UI和更新Javascript运行等多个任务,而同一时间只能有一个任务被执行.Javascript运行了多长时间,那么在浏览器空闲下来响应用户交互之前的等待时间就有多长. 从基本层面说,这意味着<script>标签的出现使整个页面因脚本解析.运行而出现等待.不论实际的 JavaScript 代码是内

  • AJAX显示加载中并弹出图层遮挡页面的实现示例

    前言 相信每位开发者都应该有所了解,当用户发出AJAX请求时,如果长时间处于请求阶段,而没有给出用户回应,会给用户造成错觉,导致用户以为我们的系统"没反应"了.这从某方面来讲是一种不友好. 甚至有的时候,用户看不到想要的结果,就会不停的请求,这样会发生意想不到的后果. 所以,当发出AJAX请求时,我们给出一定的措施,保证系统的正确运行和良好的用户体验. 在这里,我使用的是:显示加载中图片,并弹出一个图层,使用户不能再次发出请求. 实现方法 HTML部分: <div id=&quo

  • JS+CSS实现网页加载中的动画效果

    本文实例为大家分享了JS实现网页加载中效果的具体代码,供大家参考,具体内容如下 需要材料: 一张loading动画的gif图片 基本逻辑: 模态框遮罩 + loading.gif动图, 默认隐藏模态框 页面开始发送Ajax请求数据时,显示模态框 请求完成,隐藏模态框 下面我们通过Django新建一个web应用,来简单实践下 实践 1.新建一个Django项目,创建应用app01, 配置好路由和static,略.将gif动图放到静态文件夹下,结构如下: 2.视图中定义一个函数,它返回页面test.

  • jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较

    想要添加这个效果,先来弄明白页面的加载和事件执行顺序,看这个简单例子: <html xmlns="http://www.w3.org/1999/xhtml"> <head > <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>验证加载顺序</title> <script src=

  • vue.js整合vux中的上拉加载下拉刷新实例教程

    前言 Vux 是基于 Vue 和 Weui 开发的手机端页面 UI 组件库,开发初衷是满足公司的微信端表单需求,因为第三方的调查问卷表单系统在手机上实在比较丑(还是 PC 那一套样式适配了大小而已).于是用 vue 重构了表单组件,后来一发不可收拾把其他常用组件也一并开发了. 相比于 React 还是更喜欢用 Vue ,除了目前社区组件不多,周边构建工具还是比较完善的(作者也特别勤奋). 下面话不多说了,来一看看详细的介绍吧. 先上图 创建项目 使用vue-cli 创建一个vue项目 安装vux

随机推荐