如何让jQuery手风琴中每个自定义按钮对应控制单个Video.js视频?
Hey there, I see exactly what's going on here—all your custom play/pause/forward/rewind buttons are targeting the first video because you're using a single global player instance. To fix this, we need to tie each button group directly to the video in its own container, and jQuery's .each() is perfect for this job. Let's break down the solution step by step.
Why Your Current Code Isn't Working
Right now, when you click any .play-toggle, it's referencing a single player variable (which I assume is initialized as the first video). That's why every button triggers the first video instead of its own. We need to create a unique Video.js instance for each video, then link each button set to that specific instance.
Updated Code & Explanation
First, let's clean up a tiny HTML issue: your .play-toggle links have duplicate class attributes—we'll merge those into one. Then we'll rewrite the JavaScript to properly pair each button with its video.
Revised HTML (keep your full structure, just fix this small detail)
<!-- Inside each .video-player, merge the duplicate class attributes --> <a class="play-toggle video-play"> <img class="pause" src="img/play-btn.svg" alt="pause button"> <img class="play" src="img/play-btn2.svg" alt="play button"> </a>
Full JavaScript Solution
// 1. Initialize every Video.js player and store it with its container $('.video-player').each(function() { // Grab the video element inside this specific container const videoEl = $(this).find('.video-js')[0]; // Initialize Video.js for this individual video const player = videojs(videoEl); // Store the player instance in the container's data for quick access later $(this).data('videoPlayer', player); // Set initial button state: show play icon, hide pause icon $(this).find('.play').css('visibility', 'visible'); $(this).find('.pause').css('visibility', 'hidden'); }); // 2. Play/Pause Toggle Handler $('.play-toggle').click(function () { // Get the closest video container to the clicked button const videoContainer = $(this).closest('.video-player'); // Retrieve the stored Video.js instance for this container const player = videoContainer.data('videoPlayer'); // Only act if the accordion panel for this video is active if (videoContainer.closest('#accordion div').prev('.acc-wrap').hasClass("ui-state-active")) { if (player.paused()) { player.play(); // Update ONLY this button set's icons videoContainer.find('.play').css('visibility', 'hidden'); videoContainer.find('.pause').css('visibility', 'visible'); } else { player.pause(); videoContainer.find('.play').css('visibility', 'visible'); videoContainer.find('.pause').css('visibility', 'hidden'); } } }); // 3. Fast Forward Button Handler $('.forward-btn').click(function() { const videoContainer = $(this).closest('.video-player'); const player = videoContainer.data('videoPlayer'); if (videoContainer.closest('#accordion div').prev('.acc-wrap').hasClass("ui-state-active")) { // Skip ahead 10 seconds (adjust this number to your preference) player.currentTime(player.currentTime() + 10); } }); // 4. Rewind Button Handler $('.rewind-btn').click(function() { const videoContainer = $(this).closest('.video-player'); const player = videoContainer.data('videoPlayer'); if (videoContainer.closest('#accordion div').prev('.acc-wrap').hasClass("ui-state-active")) { // Rewind 10 seconds (make sure we don't go below 0) player.currentTime(Math.max(0, player.currentTime() - 10)); } });
Key Changes That Fix the Issue
.each()for Player Initialization: We loop through every.video-playercontainer, create a unique Video.js instance for each video, and store it in the container'sdataattribute. This eliminates reliance on a single global player.- Relative DOM Traversal: Using
$(this).closest('.video-player')ensures we only interact with the video that's in the same container as the clicked button—no more cross-video interference. - Targeted Style Updates: Instead of using
$('.play')which selects all play icons across the page, we usevideoContainer.find('.play')to only update the icons in the current button set.
This setup will make each button group control its own video perfectly within the jQuery accordion.
内容的提问来源于stack exchange,提问作者Marc Bacher

