You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让jQuery手风琴中每个自定义按钮对应控制单个Video.js视频?

Fix: Custom Video.js Buttons Controlling Corresponding Videos in jQuery Accordion

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-player container, create a unique Video.js instance for each video, and store it in the container's data attribute. 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 use videoContainer.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:17:48