JS 打造仿腾讯影视轮播导航
首页 Banner 不是简单的「几张图轮播」,而是「大图 + 侧边导航 + 自动播放 + 手动介入」的复合组件。本文用 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骨架
<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.初始化:生成大图与导航
const imgs = document.getElementById('imgs')
const sideBar = document.getElementById('side-bar')
let activeImg = null
let activeNav = nullfor (let i = 0; i < data.length; i++) {const item = data[i]// 大图 a 标签const tagA = document.createElement('a')tagA.href = '#'tagA.style.backgroundColor = item.bgtagA.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 = tagAactiveNav = tagNav}
}
一次循环同时生成两张「a」:左侧大图与右侧导航,减少遍历次数。
2.鼠标介入:hover 即切换
tagNav.onmouseenter = function () {clearInterval(t) // 暂停自动播放// 取消旧活跃activeNav.className = 'nav'activeImg.className = ''// 激活当前this.className = 'active'tagA.className = 'active'// 更新指针activeNav = thisactiveImg = tagA
}
使用
onmouseenter
而非onmouseover
,避免子元素冒泡导致频繁触发。
3.自动播放:定时器 + 索引循环
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.鼠标离开继续自动播放
tagNav.onmouseleave = () => {t = setInterval(move, 3000)
}
2.背景色同步切换
大图 a
的 backgroundColor
直接读取 item.bg
,避免额外计算。
3.长文字截断
CSS 设置 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
,hover 时通过 title
属性展示完整标题。
4.无闪烁切换
m.bg`,避免额外计算。
3.长文字截断
CSS 设置 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
,hover 时通过 title
属性展示完整标题。
4.无闪烁切换
display: none ↔ block
瞬间完成,背景图预加载,肉眼无闪屏。