视频播放选项

问题描述 投票:0回答:1

我是 javascript 的初学者,我设法合并了两个控制视频播放的函数,但是,它们有点互相干扰。

此功能应该提供自定义暂停和播放视频控件

// VIDEO CONTROLS START
const video = document.getElementById("heroVideo"),
  pauseControl = document.getElementById("pauseControl"),
  playControl = document.getElementById("playControl"),
  playPauseButton = document.getElementById("playPauseButton");

playPauseButton.addEventListener("click", function () {
  if (video.paused) {
    video.play();
    playPauseButton.classList.remove("play");
    playPauseButton.classList.add("pause");
    pauseControl.style.display = "unset";
    playControl.style.display = "none";
  } else {
    video.pause();
    playPauseButton.classList.remove("pause");
    playPauseButton.classList.add("play");
    pauseControl.style.display = "none";
    playControl.style.display = "unset";
    video.removeAttribute("controls");
  }
});
// VIDEO CONTROLS END

当超出用户视野时,此视频会自动暂停并播放视频(因此不会在后台播放)

// VIDEO OFFLOAD START
function videoOffload() {
  // Get all video elements with the "video-offload" class
  const videos = document.querySelectorAll(".video-offload");

  // Function to handle the Intersection Observer for a single video
  function handleVideoIntersection(video) {
    // Define the options for the Intersection Observer
    const options = {
      root: null, // Use the viewport as the root
      rootMargin: "0px", // No margin
      threshold: 0.1, // 10% of the target element must be visible to trigger
    };

    // Callback function when the video enters or exits the viewport
    const callback = (entries, observer) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // The video is in the viewport, so play it and show controls
          video.play();
          video.removeAttribute("controls");
        } else {
          // The video is out of the viewport, so pause it and hide controls
          video.pause();
        }
      });
    };

    // Create an Intersection Observer with the specified options and callback for the current video
    const observer = new IntersectionObserver(callback, options);

    // Start observing the current video element
    observer.observe(video);
  }

  // Iterate over all video elements and apply the Intersection Observer
  videos.forEach((video) => {
    video.setAttribute("autoplay", "false"); // Disable autoplay initially

    // Apply Intersection Observer to the current video
    handleVideoIntersection(video);
  });
}

// Call the videoOffload function to initialize
videoOffload();

// VIDEO OFFLOAD END

视频控制按钮

  <button id="playPauseButton" class="play">
              <i id="playControl" class="fa-regular fa-circle-play fa-xl"></i>
              <i id="pauseControl" class="fa-regular fa-circle-pause fa-xl"></i>
            </button>

问题是,一旦我手动暂停视频(使用第一个函数),滚动出视频视野,然后再次滚动回视频,它就会恢复播放(第二个函数覆盖第一个函数)。这很好,但是,视频控制图标是反向的,您需要单击两次 - 暂停,然后根据暂停和播放功能逻辑播放(因为它们在单击时发生变化,并且视频是由另一个功能触发的)。

它们都在同一个js文件中。我尝试将它们分开,但问题仍然存在。

我还尝试根据 IF 语句将图标注入 HTML -

   playPauseButton.innerHTML = "<i id='pauseControl' class='fa-regular fa-circle-pause fa-xl'></i>";
,但是不起作用。

我想到的解决方案是将它们作为视频当前状态的指示器 - 播放或暂停,因此无论视频如何触发,它都会显示正确的图标或使这两个功能互不干扰其他。

您认为最好的解决方案和代码是什么?

javascript html dom dom-events
1个回答
0
投票

考虑将控件管理重构为

video
元素上的事件侦听器。这将是判断视频是否正在播放的最准确的事实来源:

function updateControls() {
  if (video.paused) {
    playPauseButton.classList.remove("pause");
    playPauseButton.classList.add("play");
    pauseControl.style.display = "none";
    playControl.style.display = "unset";
    video.removeAttribute("controls");
  } else {
    playPauseButton.classList.remove("play");
    playPauseButton.classList.add("pause");
    pauseControl.style.display = "unset";
    playControl.style.display = "none";
  }
} 
    
video.addEventListener('pause', updateControls);
video.addEventListener('play', updateControls);

playPauseButton.addEventListener("click", function() {
  if (video.paused) {
    video.play();
  } else {
    video.pause();
  }
});

// VIDEO CONTROLS START
const video = document.getElementById("heroVideo"),
  pauseControl = document.getElementById("pauseControl"),
  playControl = document.getElementById("playControl"),
  playPauseButton = document.getElementById("playPauseButton");
  
function updateControls() {
  if (video.paused) {
    playPauseButton.classList.remove("pause");
    playPauseButton.classList.add("play");
    pauseControl.style.display = "none";
    playControl.style.display = "unset";
    video.removeAttribute("controls");
  } else {
    playPauseButton.classList.remove("play");
    playPauseButton.classList.add("pause");
    pauseControl.style.display = "unset";
    playControl.style.display = "none";
  }
} 
    
video.addEventListener('pause', updateControls);
video.addEventListener('play', updateControls);

playPauseButton.addEventListener("click", function() {
  if (video.paused) {
    video.play();
  } else {
    video.pause();
  }
});
// VIDEO CONTROLS END

// VIDEO OFFLOAD START
function videoOffload() {
  // Get all video elements with the "video-offload" class
  const videos = document.querySelectorAll(".video-offload");

  // Function to handle the Intersection Observer for a single video
  function handleVideoIntersection(video) {
    // Define the options for the Intersection Observer
    const options = {
      root: null, // Use the viewport as the root
      rootMargin: "0px", // No margin
      threshold: 0.1, // 10% of the target element must be visible to trigger
    };

    // Callback function when the video enters or exits the viewport
    const callback = (entries, observer) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // The video is in the viewport, so play it and show controls
          video.play();
          video.removeAttribute("controls");
        } else {
          // The video is out of the viewport, so pause it and hide controls
          video.pause();
        }
      });
    };

    // Create an Intersection Observer with the specified options and callback for the current video
    const observer = new IntersectionObserver(callback, options);

    // Start observing the current video element
    observer.observe(video);
  }

  // Iterate over all video elements and apply the Intersection Observer
  videos.forEach((video) => {
    video.setAttribute("autoplay", "false"); // Disable autoplay initially

    // Apply Intersection Observer to the current video
    handleVideoIntersection(video);
  });
}

// Call the videoOffload function to initialize
videoOffload();

// VIDEO OFFLOAD END
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<video id="heroVideo" class="video-offload" loop controls>
  <source src="https://v3.cdnpk.net/videvo_files/video/free/2013-08/large_preview/hd0992.mp4" type="video/mp4">
  <source src="https://v3.cdnpk.net/videvo_files/video/free/2013-08/large_watermarked/hd0992_preview.mp4" type="video/mp4">
</video>

<button id="playPauseButton" class="play">
  <i id="playControl" class="fa-regular fa-circle-play fa-xl"></i>
  <i id="pauseControl" class="fa-regular fa-circle-pause fa-xl"></i>
</button>

<div style="height: 150vh"></div>

© www.soinside.com 2019 - 2024. All rights reserved.