写在开头
上期代码主要实现省市区三级联动效果,开发久了很多功能都是通过框架组件库来完成,但是如果组件满足不了开发需求,还需要开发人员手动封装组件,专门出这样一期文章,通过原生js实现一些特定功能,功能也比较简单,也是想借助这样一个简单的功能,然后来帮助大家了解我们JavaScript,在前端中的作用,另外也培养下我们的代码思维,那我们本次就通过由简单到复杂循序渐进,后续专栏中我们会带领大家用前端实现图片放大镜、积分抽奖、拼图、无缝轮播图、图片瀑布流、读心术小游戏等等有趣的小功能,纯前端语言实现,都会陆续带给大家。
功能介绍
实现视频网站中重磅推荐模块,可以参考PC端腾讯视频首页
创建页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>视频推荐</title>
<link rel="stylesheet" href="./demo.css">
</head>
<body>
<div class="container">
<div class="top-nav"></div>
<div class="img" id="imgs">
<a href="#"></a>
</div>
<div class="side-bar" id="side-bar">
<a href="#" class="guess"> <img src="../img/all.png"> 猜你会追</a>
<a href="#" class="recom"> <img src="../img/tj.png"> 重磅推荐</a>
</div>
</div>
</body>
</html>
样式实现
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
}
.content {
height: 500px;
width: 100%;
position: relative;
}
.top-nav {
position: absolute;
z-index: 2;
height: 70px;
width: 100%;
left: 0;
top: 0;
/* background: #fac; */
background-color: rgba(255, 255, 255, .4);
}
.imgs {
width: 100%;
height: 100%;
position: relative;
}
.imgs > a {
display: none;
width: 100%;
height: 100%;
/* background-image: url(https://puui.qpic.cn/media_img/lena/PICgthm4a_580_1680/0); */
background-repeat: no-repeat;
background-position: center 0;
/* background-color: rgb(25,117,180); */
}
.imgs > .active {
display: block;
}
.side-bar {
height: 430px;
width: 350px;
position: absolute;
top: 70px;
right: 0;
/* background: black; */
background: rgba(15, 15, 30, 0.4);
}
.side-bar > a {
display: block;
height: 35px;
line-height: 35px;
margin-left: 45px;
color: rgba(255, 255, 255, 0.7);
}
.cnhz {
font-size: 22px;
margin-top: 10px;
margin-bottom: 20px;
font-weight: 700;
}
.cnhz::after {
position: absolute;
top: 55px;
height: 1px;
left: 10px;
right: 10px;
content: '';
background: rgba(255,255,255, 0.1);
}
.zbtj {
font-size: 22px;
margin-top: 10px;
font-weight: 700;
}
.cnhz > img, .zbtj > img {
margin-left: -24px;
}
.nav {
font-size: 0;
}
.nav span {
font-size: 16px;
}
.side-bar .active {
font-size: 16px;
color: #ff5c38;
width: 300px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.active > span {
font-size: 22px;
font-weight: 700;
}
逻辑功能
// 选择图片容器
var imgs = document.getElementById('imgs');
// 选择侧边导航栏容器
var sideBar = document.getElementById('side-bar');
// 存储我们创建的图片元素(a)
var imgsDom = [];
// 存储我们创建的导航元素(a)
var navDom = [];
// 记录当前活跃的图片和导航(active);
var activeImg = null;
var activeNav = null;
// 根据data数组,生成对应的图片以及侧边栏
for(var i=0; i<data.length; i++) {
// i 数组中的索引
// item代表数组中的一个对象
var item = data[i];
// 创建图片(a)
var tagA = document.createElement('a');
tagA.setAttribute('href', '#');
tagA.style.backgroundColor = item.bg;
tagA.style.backgroundImage = 'url('+ item.img +')';
imgs.appendChild(tagA);
imgsDom.push(tagA);
// 创建导航(a)
var tagNav = document.createElement('a');
tagNav.setAttribute('class', 'nav');
tagNav.setAttribute('href', '#');
tagNav.setAttribute('title',item.title + ':' + item.desc);
tagNav.innerHTML = '<span>'+ item.title +'</span> ' + item.desc;
sideBar.appendChild(tagNav);
navDom.push(tagNav);
// 第一个元素让它展示(图片展示,标题展示)
if (i == 0) {
tagA.setAttribute('class', 'active');
tagNav.setAttribute('class', 'active');
activeImg = tagA;
activeNav = tagNav;
}
tagNav.onmouseenter = (function (tagA, tagNav) {
return function () {
// 鼠标移入清除定时器。
clearInterval(t);
// 1. 把原来活跃的图片和导航取消
activeNav.setAttribute('class', 'nav');
activeImg.setAttribute('class', '');
// 2. 把当前被鼠标选中的导航和图片展示
tagA.setAttribute('class', 'active');
tagNav.setAttribute('class', 'active');
// 3. 记录最新的导航和图片
activeImg = tagA;
activeNav = tagNav;
}
})(tagA, tagNav);
tagNav.onmouseleave = function() {
t = setInterval(move, 3000);
}
}
// 自己动
function move() {
// 1. 把原来活跃的图片和导航取消
activeNav.setAttribute('class', 'nav');
activeImg.setAttribute('class', '');
// 找到当前元素的下一个
// 当前图片在页面中的位置
var index = imgsDom.indexOf(activeImg);
console.log(index);
// 如果是最后一个图片,下一个就是第一个图片
if (index == data.length - 1) {
activeNav = navDom[0];
activeImg = imgsDom[0];
} else {
activeImg = imgsDom[index + 1];
activeNav = navDom[index + 1];
}
// 活跃的图片和导航,激活(具有active类名)
activeImg.setAttribute('class', 'active');
activeNav.setAttribute('class', 'active');
}
var t = setInterval(move, 3000);
结尾
首先初始化的逻辑整理明白
- 页面中需要操作哪些dom
- 根据mock的data数据,展示对应的图片信息
- 让页面动起来