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

翻转卡片悬停4秒自动播放预告片功能实现问题

解决方案

核心逻辑梳理

要实现通用的6张卡片悬停播放效果,关键要做到:每个卡片独立监听正面悬停事件、4秒延迟触发播放、播放时替换正面内容为适配尺寸的预告片、鼠标离开/播放结束自动恢复正面,同时避免与原有的点击翻转逻辑冲突。

具体代码实现

1. HTML结构(通用适配6张卡片)

每个卡片包含正面层、背面层,正面层预留预告片容器(默认隐藏):

<div class="movie-card">
  <div class="card-inner">
    <div class="card-front">
      <!-- 正面海报 -->
      <img src="movie-poster-1.jpg" alt="电影1海报" class="poster">
      <!-- 预告片容器 -->
      <div class="trailer-container">
        <video class="trailer-video" src="trailer-1.mp4" muted playsinline></video>
      </div>
    </div>
    <div class="card-back">
      <!-- 背面简介内容 -->
      <h3>电影1</h3>
      <p>电影简介...</p>
    </div>
  </div>
</div>

<!-- 重复上述结构生成剩下5张卡片,仅替换海报、视频路径及简介内容 -->

2. CSS样式(保证尺寸匹配与布局)

确保预告片容器完全覆盖正面,视频适配卡片尺寸:

.movie-card {
  width: 300px;
  height: 450px;
  perspective: 1000px;
  position: relative;
  cursor: pointer;
  margin: 10px;
}

.card-inner {
  width: 100%;
  height: 100%;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

.card-front, .card-back {
  width: 100%;
  height: 100%;
  position: absolute;
  backface-visibility: hidden;
}

.card-back {
  transform: rotateY(180deg);
  background: #222;
  color: #fff;
  padding: 20px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* 预告片容器样式:覆盖整个正面 */
.trailer-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  display: none;
  z-index: 1;
}

.trailer-video {
  width: 100%;
  height: 100%;
  object-fit: cover; /* 视频适配卡片尺寸,保持比例 */
}

/* 点击翻转的触发类 */
.flipped .card-inner {
  transform: rotateY(180deg);
}

3. JavaScript逻辑(通用处理所有卡片)

为每个卡片绑定独立的悬停、播放、恢复事件,避免全局变量冲突:

// 获取所有电影卡片
const movieCards = document.querySelectorAll('.movie-card');

// 遍历每个卡片,绑定事件
movieCards.forEach(card => {
  const cardFront = card.querySelector('.card-front');
  const trailerContainer = card.querySelector('.trailer-container');
  const trailerVideo = card.querySelector('.trailer-video');
  let hoverTimer = null;

  // 鼠标进入正面:启动4秒延迟播放
  cardFront.addEventListener('mouseenter', () => {
    // 如果当前卡片是翻转状态(显示背面),不处理
    if (card.classList.contains('flipped')) return;
    // 清除之前的延迟(防止多次悬停叠加)
    if (hoverTimer) clearTimeout(hoverTimer);
    
    hoverTimer = setTimeout(() => {
      // 显示预告片并播放
      trailerContainer.style.display = 'block';
      trailerVideo.play().catch(err => console.error('预告片播放失败:', err));
      // 播放时禁用点击翻转,避免误操作
      card.style.pointerEvents = 'none';
    }, 4000);
  });

  // 鼠标离开:取消延迟、停止播放并恢复正面
  card.addEventListener('mouseleave', () => {
    clearTimeout(hoverTimer);
    trailerContainer.style.display = 'none';
    trailerVideo.pause();
    trailerVideo.currentTime = 0; // 重置视频到开头
    card.style.pointerEvents = 'auto'; // 恢复点击功能
  });

  // 预告片播放结束:自动恢复正面
  trailerVideo.addEventListener('ended', () => {
    trailerContainer.style.display = 'none';
    card.style.pointerEvents = 'auto';
  });

  // 保留原有的点击翻转逻辑(播放时不触发)
  card.addEventListener('click', () => {
    if (trailerContainer.style.display === 'block') return;
    card.classList.toggle('flipped');
  });
});

关键修正点说明

  • 通用适配:通过querySelectorAll遍历所有卡片,每个卡片独立维护自己的延迟计时器,避免全局变量冲突。
  • 悬停逻辑修正:直接监听卡片正面的mouseenter事件,同时判断卡片是否处于翻转状态,避免背面显示时误触发预告片。
  • 尺寸匹配:用CSS绝对定位让预告片容器完全覆盖正面,object-fit: cover保证视频填充卡片且比例正常。
  • 状态恢复:鼠标离开立即取消延迟、重置视频;播放结束自动隐藏预告片,恢复点击功能。
  • 冲突避免:播放预告片时禁用卡片点击,防止误触发翻转;点击翻转时如果预告片正在播放,不执行操作。

内容的提问来源于stack exchange,提问作者user14178341

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:53:10