最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React實現圖片懶加載的常見方式

 更新時間:2024年01月09日 08:23:49   作者:Mh  
圖片懶加載是一種優(yōu)化網頁性能的技術,它允許在用戶滾動到圖片位置之前延遲加載圖片,通過懶加載,可以在用戶需要查看圖片時才加載圖片,避免了不必要的圖片加載,本文給大家介紹了React實現圖片懶加載的常見方式,需要的朋友可以參考下

前言

圖片懶加載是一種優(yōu)化網頁性能的技術,它允許在用戶滾動到圖片位置之前延遲加載圖片。通過懶加載,可以在用戶需要查看圖片時才加載圖片,避免了不必要的圖片加載,從而提高了網頁的加載速度和用戶體驗。

方案一

實現思路

在說明思路之前,先了解幾個常見的視圖屬性。

  • clientHeight:可視區(qū)域的高度,對應的也就是下圖中的滾動區(qū)域。
  • scrollTop:滾動條滾動的高度,它指的是內容區(qū)的頂部到可視區(qū)域頂部的距離。
  • offsetTop:元素到offsetParent頂部的距離。
  • offsetParent:距離元素最近的一個具有定位的祖宗元素(relative,absolute,fixed),若祖宗都不符合條件,offsetParent為body。

圖解:

根據上面的圖解可知,當圖片的滾動條滾動的高度加上可視區(qū)域的高度大于當前的圖片的offsetTop,那么說明圖片正在進入可視區(qū)域。這個時候便可以加載當前圖片。

第一步

模擬后臺返回的圖片url,遍歷產生一個url集合,用于后面的懶加載使用。

const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

第二步

遍歷圖片url集合,渲染100張loading圖片,css部分省略。

    <div className={styles['box-one']} ref={scrollRef}>
      {imgUrls(100).map((item) => {
        return <img data-src={item} key={item} src={loadingUrl} alt="" />;
      })}
    </div>

效果預覽

第三步

監(jiān)聽容器的滾動事件,當容器滾動時計算容器的高度加上滾動條的高度大于當前圖片的offsetTop時加載當前的圖片。完整代碼如下:

import loadingUrl from '@/assets/imgs/loading.jpg';
import { useEffect, useRef } from 'react';
import styles from '../index.less';

// 圖片url
const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

const LazyLoading = () => {
  const scrollRef = useRef({} as any);

  // 滾動事件
  const changeScroll = () => {
    const clientHeight = scrollRef?.current.clientHeight; //可視區(qū)域高度
    const scrollTop = scrollRef?.current.scrollTop; //滾動條滾動高度
    const childNodes = scrollRef?.current.childNodes; // 獲取所有圖片集合

    for (let j = 0; j < childNodes.length; j++) {
      const element = childNodes[j];
      if (scrollTop + clientHeight > element.offsetTop) {
        element.src = element.getAttribute('data-src'); // 替換當前的src
      }
    }
  };

  useEffect(() => {
    changeScroll(); // 第一次渲染的時候替換loading圖片
  }, []);

  return (
    <div className={styles['box-one']} ref={scrollRef} onScroll={changeScroll}>
      {imgUrls(100).map((item) => {
        return <img data-src={item} key={item} src={loadingUrl} alt="" />;
      })}
    </div>
  );
};

export default LazyLoading;

效果預覽

方案二

實現思路

方案二的實現思路利用瀏覽器提供的 IntersectionObserver API實現。IntersectionObserver API提供了一種方便的方式來監(jiān)視目標元素和其祖先元素或視窗之間的交叉狀態(tài)變化。當目標元素進入或離開視口時,可以觸發(fā)回調函數,進行相應的操作。它的原理是通過注冊一個回調函數來觀察特定元素的交叉狀態(tài)變化,并在滿足條件時執(zhí)行相應的操作。

使用 IntersectionObserver API非常簡單,可以通過創(chuàng)建一個 IntersectionObserver 實例,并傳入回調函數和選項對象來實現。回調函數會在目標元素的交叉狀態(tài)發(fā)生變化時被調用,并接收一個參數,包含有關交叉狀態(tài)的信息。

實現完整代碼

import loadingUrl from '@/assets/imgs/loading.jpg';
import styles from '../index.less';
import React, { useRef, useEffect, useState } from 'react';
// 圖片url
const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

const LazyLoadImage = ({ src, alt }) => {
  const [imageSrc, setImageSrc] = useState(loadingUrl);
  const imgRef = useRef(null as any);

  useEffect(() => {
    let observer: IntersectionObserver;
    if (imgRef.current) {
      // 創(chuàng)建IntersectionObserver實例
      observer = new IntersectionObserver(
        ([entry]) => {
          // 當圖片進入可視區(qū)域時,設置圖片地址進行加載
          if (entry.isIntersecting) {
            setImageSrc(src);
            observer.unobserve(imgRef.current);
          }
        },
        {
          rootMargin: '0px 0px 200px 0px', // 可視區(qū)域的上邊距設置為200px
        },
      );
      observer.observe(imgRef.current); //開始觀察目標元素
    }
    return () => {
      if (observer && observer.unobserve) {
        observer.unobserve(imgRef.current);
      }
    };
  }, [src]);

  return <img ref={imgRef} src={imageSrc} alt={alt} />;
};

const LazyLoading = () => {
  return (
    <div className={styles['box-two']}>
      {imgUrls(100).map((item) => {
        return <LazyLoadImage src={item} alt="lazy load image" />;
      })}
    </div>
  );
};

export default LazyLoading;

實現效果

注意事項

在初始化的時候,需要給imageSrc設置一個初始化的loading地址,如果沒有的話,初始化的時候會加載多張圖片。

方案三

實現思路

利用react的懶加載庫react-lazyload,在使用之前需要先安裝 yarn add react-lazyload,這里介紹幾個它的常見屬性:

  • scrollContainer: 指定的滾動的區(qū)域,默認值是undefined,如果沒有指定默認是窗口的視圖作為滾動區(qū)域。
  • offset: 元素距離視口頂部的距離,當達到這個距離時,元素將被加載。
  • scroll: 是否監(jiān)聽滾動
  • height: 渲染元素的占位符的高度。
  • overflow : 如果溢出容器,延遲加載組件

代碼實現

因為這里實現的圖片懶加載是局部懶加載,所以需要指定 scrollContainer,scrollContainer 的值DOM對象。在實現的過程中,同時需要設置overflow為true,以及height的值。

import react, { useRef, useEffect } from 'react';
import LazyLoad from 'react-lazyload';
import styles from '../index.less';

// 圖片url
const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

const LazyLoading = () => {
  const scrollRef = useRef({} as any);

  return (
    <div className={styles['box-three']} ref={scrollRef}>
      {imgUrls(100).map((item) => {
        return (
          <LazyLoad
            height={200}
            overflow={true}
            offset={0}
            key={item}
            scroll={true}
            scrollContainer={scrollRef.current} // DOM
          >
            <img src={item} alt="" />
          </LazyLoad>
        );
      })}
    </div>
  );
};

export default LazyLoading;

實現效果

以上就是React實現圖片懶加載的常見方式的詳細內容,更多關于React圖片懶加載的資料請關注腳本之家其它相關文章!

相關文章

  • 使用react-native-doc-viewer實現文檔預覽

    使用react-native-doc-viewer實現文檔預覽

    這篇文章主要介紹了使用react-native-doc-viewer實現文檔預覽,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 使用React-Router實現前端路由鑒權的示例代碼

    使用React-Router實現前端路由鑒權的示例代碼

    這篇文章主要介紹了使用React-Router實現前端路由鑒權的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • React中immutable的UI組件渲染性能詳解

    React中immutable的UI組件渲染性能詳解

    這篇文章主要為大家介紹了React中immutable的UI組件渲染性能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • 詳解React?hooks組件通信方法

    詳解React?hooks組件通信方法

    這篇文章主要介紹了React?hooks組件通信,在開發(fā)中組件通信是React中的一個重要的知識點,本文通過實例代碼給大家講解react hooks中常用的父子、跨組件通信的方法,需要的朋友可以參考下
    2022-07-07
  • React更新渲染原理深入分析

    React更新渲染原理深入分析

    什么是re-render(重新渲染)?哪些是必要的re-render?哪些是非必要的re-render?如果你對這些問題還不是很明白,那么可以在這篇文章中找到答案
    2022-12-12
  • React中前端路由的示例代碼

    React中前端路由的示例代碼

    本文主要介紹了React中前端路由的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • react自動化構建路由的實現

    react自動化構建路由的實現

    這篇文章主要介紹了react自動化構建路由的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • React如何實現像Vue一樣將css和js寫在同一文件

    React如何實現像Vue一樣將css和js寫在同一文件

    這篇文章主要介紹了React如何實現像Vue一樣將css和js寫在同一文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • react-native消息推送實現方式

    react-native消息推送實現方式

    這篇文章主要介紹了react-native消息推送實現方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 編寫簡潔React組件的小技巧

    編寫簡潔React組件的小技巧

    這篇文章主要介紹了編寫簡潔React組件的小技巧,幫助大家更好的理解和學習使用React,感興趣的朋友可以了解下
    2021-04-04

最新評論

武汉市| 张掖市| 彭水| 河北省| 江津市| 清水河县| 长岛县| 游戏| 东乡县| 谷城县| 江川县| 白沙| 靖西县| 新营市| 门头沟区| 莱州市| 静海县| 崇州市| 平阳县| 横峰县| 麦盖提县| 涟源市| 马山县| 叙永县| 公主岭市| 双江| 正安县| 云梦县| 来安县| 七台河市| 延安市| 洪江市| 密山市| 龙川县| 宁明县| 富源县| 平顺县| 崇阳县| 麻城市| 白水县| 五河县|