我是 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>";
,但是不起作用。
我想到的解决方案是将它们作为视频当前状态的指示器 - 播放或暂停,因此无论视频如何触发,它都会显示正确的图标或使这两个功能互不干扰其他。
您认为最好的解决方案和代码是什么?
考虑将控件管理重构为
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>