溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發技術 > 
  • 怎么使用React+TS+IntersectionObserver實現視頻懶加載和自動播放功能

怎么使用React+TS+IntersectionObserver實現視頻懶加載和自動播放功能

發布時間:2023-04-27 17:15:27 來源:億速云 閱讀:201 作者:iii 欄目:開發技術

這篇“怎么使用React+TS+IntersectionObserver實現視頻懶加載和自動播放功能”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么使用React+TS+IntersectionObserver實現視頻懶加載和自動播放功能”文章吧。

IntersectionObserver

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

以下是 IntersectionObserver API 的基本語法:

const observer = new IntersectionObserver(callback, options);

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

創建 IntersectionObserver 對象后,我們就可以監聽目標元素:

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

組件卸載時,應取消監聽:

observer.unobserve(target);

如果監聽了多個元素,可以停止監聽所有目標元素:

observer.disconnect();

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

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

視頻播放控制組件

首先,我們定義一個 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 鉤子來創建一個 videoRef 引用。我們將通過該引用來判斷視頻狀態、更新視頻真實地址、控制視頻的播放和暫停功能。

const videoRef = useRef<HTMLVideoElement>(null);

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

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

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

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

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

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

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

下面是最終的代碼:

/**
 * @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", // 用于指定目標元素與根元素(視口)的邊緣間的偏移量,以便確定何時觸發回調函數。
      threshold: 0.5, // 指定交叉比例為 50% 時觸發回調函數
    };
    // 創建 IntersectionObserver 實例
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        // 當視頻進入視口時,開始播放視頻
        if (video?.readyState === 4) {
          // 視頻已經加載完畢
          video?.play();
        } else {
          // 監聽視頻加載完成事件
          if (video?.dataset.src) {
            // 將 data-src 的值賦給 src 屬性
            video.src = video.dataset.src;
            delete video.dataset.src;
            video?.addEventListener("loadedmetadata", () => {
              video?.play();
            });
          }
        }
      } else {
        // 當視頻離開視口時,暫停視頻播放
        video?.pause();
      }
    }, options);
    // 監聽 video 元素
    if (video) {
      observer.observe(video);
    }
    // 組件卸載時取消監聽
    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;

以上就是關于“怎么使用React+TS+IntersectionObserver實現視頻懶加載和自動播放功能”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女