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

React+TS+IntersectionObserver實現(xiàn)視頻懶加載和自動播放功能

 更新時間:2023年04月27日 09:35:28   作者:碼上花甲  
通過本文的介紹,我們學(xué)習(xí)了如何使用 React + TypeScript 和 IntersectionObserver API 來實現(xiàn)一個視頻播放控制組件,該組件具有懶加載功能,只有在用戶滾動頁面且視頻進入視口時才開始下載視頻資源,需要的朋友可以參考下

為了提高用戶體驗,網(wǎng)站通常會使用視頻來呈現(xiàn)內(nèi)容。然而,在網(wǎng)站中使用自動播放的視頻通常會導(dǎo)致頁面加載時間變長,因為用戶需要等待更長的時間才能看到內(nèi)容。為了解決這個問題,我們可以使用懶加載技術(shù)來延遲視頻的加載,只有在用戶滾動頁面并且視頻進入視口時才開始下載視頻資源。同時,為了進一步提高用戶體驗,當(dāng)視頻進入用戶的視野范圍時,我們希望視頻能夠自動播放。

本文將介紹如何使用 React + TypeScript 來通過 IntersectionObserver API 實現(xiàn)這一功能。在正式開始之前,我們先來看一下最終實現(xiàn)的效果圖:

實現(xiàn)這一功能的核心在于 IntersectionObserver API。下面我們將簡單介紹一下這個 API 的用法。

IntersectionObserver

IntersectionObserver 是瀏覽器內(nèi)置的 API,用于監(jiān)聽元素是否交叉或超出了視口(viewport)的變化。這個 API 提供了一種異步觀察目標(biāo)元素的機制,在元素進入或離開視口時觸發(fā)回調(diào)函數(shù)。

以下是 IntersectionObserver API 的基本語法:

const observer = new IntersectionObserver(callback, options);

其中 callback 是回調(diào)函數(shù),options 是配置選項,用于指定觀察器的參數(shù),如視口的大小、元素與視口的交叉比例等。

創(chuàng)建 IntersectionObserver 對象后,我們就可以監(jiān)聽目標(biāo)元素:

observer.observe(target); // target 是被觀察的目標(biāo)元素

組件卸載時,應(yīng)取消監(jiān)聽:

observer.unobserve(target);

如果監(jiān)聽了多個元素,可以停止監(jiān)聽所有目標(biāo)元素:

observer.disconnect();

上面的 disconnect() 方法用于停止所有目標(biāo)元素的監(jiān)聽,并銷毀 IntersectionObserver 對象。

現(xiàn)在,你應(yīng)該已經(jīng)了解了 IntersectionObserver API。下面,我們將通過編寫一個可擴展的組件來實現(xiàn)效果圖演示的功能。

視頻播放控制組件

首先,我們定義一個 VideoProps 接口,它包含了我們的 Video 組件的屬性:

interface VideoProps {
  src: string;
  width?: number;
  height?: number;
  className?: string;
}

接下來,我們定義 Video 組件,它接收 src、width、heightclassName 屬性:

const Video: React.FC<VideoProps> = ({
  src,
  width = 400,
  height = 300,
  className,
}) => {
  // ...
};

Video 組件中,我們通過 useRef 鉤子來創(chuàng)建一個 videoRef 引用。我們將通過該引用來判斷視頻狀態(tài)、更新視頻真實地址、控制視頻的播放和暫停功能。

const videoRef = useRef<HTMLVideoElement>(null);

然后,我們使用 useEffect 鉤子來創(chuàng)建一個 IntersectionObserver 實例。我們要實現(xiàn)的功能主要就是通過這個實例來實現(xiàn)的。

useEffect(() => {
  const video = videoRef.current;
  const options = {
    rootMargin: "0px",
    threshold: 0.5, // 指定交叉比例為 50% 時觸發(fā)回調(diào)函數(shù)
  };
  // 創(chuàng)建 IntersectionObserver 實例
  const observer = new IntersectionObserver(([entry]) => {
    // ...
  }, options);
  // 監(jiān)聽 video 元素
  if (video) {
    observer.observe(video);
  }
  // 組件卸載時取消監(jiān)聽
  return () => {
    observer.unobserve(video as Element);
  };
}, []);

IntersectionObserver 的回調(diào)函數(shù)中,我們檢查視頻是否進入視口,如果進入視口,首先要加載視頻。如果視頻加載完成,就開始播放視頻:

if (entry.isIntersecting) {
  // 當(dāng)視頻進入視口時,開始播放視頻
  if (video?.readyState === 4) {
    // 視頻已經(jīng)加載完畢
    video?.play();
  } else {
    // 監(jiān)聽視頻加載完成事件
    if (video?.dataset.src) {
      // 將 data-src 的值賦給 src 屬性
      video.src = video.dataset.src;
      delete video.dataset.src;
      video?.addEventListener("loadedmetadata", () => {
        video?.play();
      });
    }
  }
} else {
  // 當(dāng)視頻離開視口時,暫停視頻播放
  video?.pause();
}

注意,示例代碼中使用了 video?.readyState === 4 來檢查視頻是否已經(jīng)加載完畢。readyState 屬性表示視頻的加載狀態(tài),如果它的值為 4,表示視頻已經(jīng)加載完畢。

如果視頻還沒有加載完畢,我們就需要等到它加載完成后再開始播放。為了實現(xiàn)這一點,我們在 data-src 屬性中存儲視頻的地址,然后在視頻加載完成后再將它賦值給 src 屬性。當(dāng)視頻加載完成后,記得要刪除 data-src 屬性,避免重復(fù)加載視頻:

if (video?.dataset.src) {
  // 將 data-src 的值賦給 src 屬性
  video.src = video.dataset.src;
  delete video.dataset.src;
  video?.addEventListener("loadedmetadata", () => {
    video?.play();
  });
}

我們看下加載視頻的效果圖:

在效果圖中可以看到,當(dāng)視頻進入視口后,開始下載視頻。視頻下載完成后便開始自動播放。當(dāng)視頻移出視口時,視頻會自動暫停。

至此,這個組件基本就完成了。下面是最終的代碼:

/**
 * @description 視頻組件
 * @param {string} src 視頻地址
 * @param {number} width 視頻寬度
 * @param {number} height 視頻高度
 * @param {string} className 自定義類名
 * @returns {JSX.Element}
 * @example
 *   import Video from '@/components/Video';
 *   <Video src="<https://www.w3schools.com/html/mov_bbb.mp4>" />
 */
import React, { useRef, useEffect } from "react";
interface VideoProps {
  src: string;
  width?: number | string;
  height?: number | string;
  className?: string;
}
const Video: React.FC<VideoProps> = ({
  src,
  width = 400,
  height = 300,
  className,
}) => {
  const videoRef = useRef<HTMLVideoElement>(null);
  useEffect(() => {
    const video = videoRef.current;
    const options = {
      rootMargin: "0px", // 用于指定目標(biāo)元素與根元素(視口)的邊緣間的偏移量,以便確定何時觸發(fā)回調(diào)函數(shù)。
      threshold: 0.5, // 指定交叉比例為 50% 時觸發(fā)回調(diào)函數(shù)
    };
    // 創(chuàng)建 IntersectionObserver 實例
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        // 當(dāng)視頻進入視口時,開始播放視頻
        if (video?.readyState === 4) {
          // 視頻已經(jīng)加載完畢
          video?.play();
        } else {
          // 監(jiān)聽視頻加載完成事件
          if (video?.dataset.src) {
            // 將 data-src 的值賦給 src 屬性
            video.src = video.dataset.src;
            delete video.dataset.src;
            video?.addEventListener("loadedmetadata", () => {
              video?.play();
            });
          }
        }
      } else {
        // 當(dāng)視頻離開視口時,暫停視頻播放
        video?.pause();
      }
    }, options);
    // 監(jiān)聽 video 元素
    if (video) {
      observer.observe(video);
    }
    // 組件卸載時取消監(jiān)聽
    return () => {
      observer.unobserve(video as Element);
    };
  }, []);
  return (
    <video
      loop
      muted
      controls
      playsInline
      width={width}
      ref={videoRef}
      data-src={src} // 添加 data-src 屬性
      height={height}
      className={className}
    />
  );
};
export default Video;

結(jié)語

通過本文的介紹,我們學(xué)習(xí)了如何使用 React + TypeScript 和 IntersectionObserver API 來實現(xiàn)一個視頻播放控制組件。該組件具有懶加載功能,只有在用戶滾動頁面且視頻進入視口時才開始下載視頻資源。同時,當(dāng)視頻進入用戶的視野范圍時,視頻能夠自動播放,提高了用戶的使用體驗。

IntersectionObserver API 提供了一種異步觀察目標(biāo)元素的機制,即在元素進入或離開視口時觸發(fā)回調(diào)函數(shù)。這為我們的視頻播放控制組件提供了關(guān)鍵的功能。

通過編寫這個可擴展的組件,你可以為網(wǎng)站的視頻播放功能提供更好的用戶體驗。同時,我們也了解了如何使用 React + TypeScript 和 IntersectionObserver API 來實現(xiàn)類似的功能,這將為我們今后的開發(fā)工作提供更多的思路和幫助。

到此這篇關(guān)于React+TS+IntersectionObserver實現(xiàn)視頻懶加載和自動播放!的文章就介紹到這了,更多相關(guān)React懶加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ReactNative實現(xiàn)弧形拖動條的代碼案例

    ReactNative實現(xiàn)弧形拖動條的代碼案例

    本文介紹了ReactNative實現(xiàn)弧形拖動條,本組件使用到了react-native-svg和PanResponder,結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • 詳解在create-react-app使用less與antd按需加載

    詳解在create-react-app使用less與antd按需加載

    這篇文章主要介紹了詳解在create-react-app使用less與antd按需加載,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • react18中react-redux狀態(tài)管理的實現(xiàn)

    react18中react-redux狀態(tài)管理的實現(xiàn)

    本文主要介紹了react18中react-redux狀態(tài)管理的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Redux?Toolkit的基本使用示例詳解(Redux工具包)

    Redux?Toolkit的基本使用示例詳解(Redux工具包)

    這篇文章主要介紹了Redux?Toolkit的基本使用,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • windows下create-react-app 升級至3.3.1版本踩坑記

    windows下create-react-app 升級至3.3.1版本踩坑記

    這篇文章主要介紹了windows下create-react-app 升級至3.3.1版本踩坑記,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • react用Redux中央倉庫實現(xiàn)一個todolist

    react用Redux中央倉庫實現(xiàn)一個todolist

    這篇文章主要為大家詳細(xì)介紹了react用Redux中央倉庫實現(xiàn)一個todolist,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • React Router v4 入坑指南(小結(jié))

    React Router v4 入坑指南(小結(jié))

    這篇文章主要介紹了React Router v4 入坑指南(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • 如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器

    如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器

    這篇文章主要介紹了如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器,在vue及react中經(jīng)常會遇到,今天通過實例代碼給大家講解,需要的朋友可以參考下
    2018-11-11
  • React實現(xiàn)輪播圖效果

    React實現(xiàn)輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了React實現(xiàn)輪播圖效果,使用react-slick組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 每天一個hooks學(xué)習(xí)之useUpdateEffect

    每天一個hooks學(xué)習(xí)之useUpdateEffect

    這篇文章主要為大家介紹了每天一個hooks學(xué)習(xí)之useUpdateEffect使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05

最新評論

天峨县| 崇文区| 乌拉特前旗| 高州市| 和平区| 新民市| 明水县| 义马市| 公安县| 若尔盖县| 苏尼特右旗| 历史| 新源县| 广平县| 怀来县| 花莲县| 若尔盖县| 景泰县| 观塘区| 木里| 尼勒克县| 中宁县| 社会| 贡嘎县| 剑川县| 黎川县| 华安县| 辽宁省| 金阳县| 芦溪县| 万荣县| 和田市| 繁昌县| 涞水县| 巫山县| 乌兰察布市| 永宁县| 太湖县| 尖扎县| 桐城市| 沐川县|