使用 Stimulus 实现悬停视频预览

发布: (2026年3月13日 GMT+8 01:15)
3 分钟阅读
原文: Dev.to

Source: Dev.to

演示文稿索引

录制完演示文稿后,需要一种方式来浏览它们。一个简单的索引页面会列出所有演示文稿及其视频缩略图。当鼠标悬停在缩略图上时,视频会播放预览。将光标移开后,视频会恢复为海报图像。

preview#play mouseleave->preview#pause"
  }
%>

Active Storage 的 representable? 方法会检查是否可以生成预览,而 representation() 会自动创建缩略图。

预览控制器

所有逻辑都在一个 Stimulus 控制器中完成:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static values = {
    segments: { type: Number, default: 3 },
    interval: { type: Number, default: 1000 },
    minDuration: { type: Number, default: 5 }
  }

  connect() {
    this.originalTime = 0
    this.wasPlaying = false
    this.previewTimer = null
    this.currentIndex = 0
    this.isReady = false
    this.timestamps = []

    this.element.addEventListener("loadedmetadata", () => {
      this.#calculateTimestamps()
      this.isReady = true
    })
  }
}

理解 loadedmetadata

loadedmetadata 事件是关键。它在浏览器加载足够的视频数据以获取时长、尺寸以及其他元数据时触发。如果没有这些信息,就无法计算有意义的预览时间戳。

this.element.addEventListener("loadedmetadata", () => {
  this.#calculateTimestamps()
  this.isReady = true
})

只有在 loadedmetadata 触发后,才能可靠地访问 this.element.duration。在此事件之前尝试使用它会得到 NaN0

智能时间戳

控制器不会仅仅从开头播放,而是展示视频的不同片段:

#calculateTimestamps() {
  const duration = this.element.duration

  if (duration  1) {
    this.previewTimer = setInterval(() => {
      this.#showNextTimestamp()
    }, this.intervalValue)
  }
}

当你悬停时,它会保存当前状态、静音并开始循环播放预览片段。离开时,它会把一切恢复到原来的状态。

自动循环预览

预览会自动循环遍历计算出的时间戳:

#showNextTimestamp() {
  this.element.currentTime = this.timestamps[this.currentIndex]
  this.element.play()

  this.currentIndex = (this.currentIndex + 1) % this.timestamps.length
}

取模运算符 (%) 用来实现循环:当到达最后一个片段时,会回到第一个。配合 setInterval,就形成了一个循环预览,让用户真实感受到视频内容。

关键在于等待正确的时机(元数据加载完成),计算智能的预览点,并在交互结束时妥善清理。这个小巧的 Stimulus 控制器展示了几行 JavaScript 如何提供精致的用户体验。 🥳

0 浏览
Back to Blog

相关文章

阅读更多 »

关于 JavaScript 的简介

介绍 在今天的课堂上,我学习了 JavaScript 的简短介绍,所以我将在这篇博客中分享一些关于 JavaScript 的事实。什么是 JavaScript?JavaScr...

Vite 8.0 已发布

文章《Announcing Vite 8.0》 https://vite.dev/blog/announcing-vite8 讨论 Hacker News 线程 https://news.ycombinator.com/item?id=47360730 – 24 点,1 条评论