JS 打造仿腾讯影视轮播导航

首页 Banner 不是简单的「几张图轮播」,而是「大图 + 侧边导航 + 自动播放 + 手动介入」的复合组件。本文用 JS原生代码实现一条无依赖、可复用、可扩展的影视轮播链路,涵盖数据驱动、事件委托、状态管理三大核心技能。

效果预览

一、数据约定

把后端返回的列表抽象成统一结构:

js 复制代码
// data.js
const data = [
  {
    title: "三十而已",
    desc: "话题爽剧!姐姐飒气挑战",
    img: "https://puui.qpic.cn/media_img/lena/PICgthm4a_580_1680/0",
    bg: "rgb(25,117,180)"
  },
  // ... 更多对象
]
  • title:导航主标题
  • desc:副标题,用于 hover 提示
  • img:大图地址
  • bg:背景色,与大图同步切换

二、html骨架

html 复制代码
<div class="content">
  <div class="top-nav"></div>
  <div class="imgs" id="imgs">
  </div>
  <div class="side-bar" id="side-bar">
    <a href="#" class="cnhz"> <img src="./img/all.png"> 猜你会追</a>
    <a href="#" class="zbtj"> <img src="./img/tj.png"> 重磅推荐</a>
  </div>
</div>

三、js链式渲染三步走

1.初始化:生成大图与导航

js 复制代码
const imgs = document.getElementById('imgs')
const sideBar = document.getElementById('side-bar')
let activeImg = null
let activeNav = null

for (let i = 0; i < data.length; i++) {
  const item = data[i]

  // 大图 a 标签
  const tagA = document.createElement('a')
  tagA.href = '#'
  tagA.style.backgroundColor = item.bg
  tagA.style.backgroundImage = `url(${item.img})`
  imgs.appendChild(tagA)

  // 导航 a 标签
  const tagNav = document.createElement('a')
  tagNav.href = '#'
  tagNav.className = 'nav'
  tagNav.title = `${item.title}: ${item.desc}`
  tagNav.innerHTML = `<span>${item.title}</span> ${item.desc}`
  sideBar.appendChild(tagNav)

  // 第一个元素默认激活
  if (i === 0) {
    tagA.className = 'active'
    tagNav.className = 'active'
    activeImg = tagA
    activeNav = tagNav
  }
}

一次循环同时生成两张「a」:左侧大图与右侧导航,减少遍历次数。

2.鼠标介入:hover 即切换

js 复制代码
tagNav.onmouseenter = function () {
  clearInterval(t) // 暂停自动播放

  // 取消旧活跃
  activeNav.className = 'nav'
  activeImg.className = ''

  // 激活当前
  this.className = 'active'
  tagA.className = 'active'

  // 更新指针
  activeNav = this
  activeImg = tagA
}

使用 onmouseenter 而非 onmouseover,避免子元素冒泡导致频繁触发。

3.自动播放:定时器 + 索引循环

js 复制代码
function move() {
  // 取消旧活跃
  activeNav.className = 'nav'
  activeImg.className = ''

  // 找到下一个
  const index = Array.from(imgs.children).indexOf(activeImg)
  const nextIndex = (index + 1) % data.length

  // 激活下一个
  activeImg = imgs.children[nextIndex]
  activeNav = sideBar.children[nextIndex + 2] // 跳过两个标题
  activeImg.className = 'active'
  activeNav.className = 'active'
}

let t = setInterval(move, 3000)

nextIndex = (index + 1) % data.length 实现首尾循环;nextIndex + 2 跳过「猜你会追」和「重磅推荐」两个标题节点。

四、边界与优化细节

1.鼠标离开继续自动播放

js 复制代码
tagNav.onmouseleave = () => {
  t = setInterval(move, 3000)
}

2.背景色同步切换

大图 abackgroundColor 直接读取 item.bg,避免额外计算。

3.长文字截断

CSS 设置 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;,hover 时通过 title 属性展示完整标题。

4.无闪烁切换

display: none ↔ block 瞬间完成,背景图预加载,肉眼无闪屏。

相关推荐
亿元程序员15 小时前
一个人,4个岗位,20天:我用Cursor+Codex上线了一款微信小游戏
前端
LabVIEW开发16 小时前
将自定义 DLL 与 INI 文件部署到 LabVIEW 实时目标
前端·labview·labview知识·labview功能·labview程序
不要打扰75616 小时前
2027国网提前批宣讲、面试、预报名、内部笔试时间一览
面试·职场和发展
IT_陈寒16 小时前
Redis Pipeline用错竟比不用还慢,这个坑我帮你踩过了
前端·人工智能·后端
YHHLAI16 小时前
TypeScript 高级工具类型面试指南
ubuntu·面试·typescript
ynchyong16 小时前
JavaScript Promise 实战:.then() 与 .catch() 的区别及回调函数封装指南
开发语言·javascript·ecmascript·promise·then
大模型码小白16 小时前
数据可视化:AI处理多维数据的HTML5可视化方案
大数据·前端·javascript·人工智能·机器学习·信息可视化·html5
LabVIEW开发17 小时前
LabVIEW 前面板装饰图形的格式选择与自定义选板添加
前端·labview·labview知识·labview功能·labview程序
掘金者阿豪17 小时前
GPT-6 Astra 来了,GPT-5.6 Sol 还值得用吗?聊聊 Coding、百万上下文、价格和 Plus/Pro
前端·后端
code 小楊17 小时前
腾讯开源 WeKnora 深度解析:RAG 问答 + ReAct Agent 推理 + 自动 Wiki 图谱,三位一体的企业级知识中台
前端·人工智能·开源·知识图谱