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圖片加載完成的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 示例詳解react中useState的用法
- 詳解React中共享組件邏輯的三種方式
- React Suspense前後端IO異步操作處理
- React 高階組件HOC用法歸納
- react國際化react-intl的使用