这是我参与「第五届青训营 」伴学笔记创作活动的第3天
前言
轮播图是指在一个模块或者窗口,通过鼠标点击或手指滑动后,可以看到多张图片。此模块常用于各网站或APP的页面。今天听《字节内部课》的JavaScript讲解颇有启发,参考了一些模板,打算自己试试如何实现它。
大致思路
1.首先所有的图片都是放在一个div中让它叠加起来的,设置层级让当前图片出现在最上面
2.为每个底部圆点按钮添加点击事件
3.用时间间隔函数让轮播图每隔一段时间自动更新
4.鼠标移入事件和鼠标移除事件
5.添加左右点击事件
6.下方动态按钮事件
搭建HTML
首先搭建HTML框架,把需要的图片放进去。
其中name="viewport"使网页同时匹配PC端和移动端。 content="width=device-width,initial-scale=1.0">定义了可视宽度为屏幕的物理宽度,且无缩放。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>轮番</title>
<link href="./轮番.css" rel="stylesheet" type="text/css">
<script src="./轮番.js"></script>
</head>
<body>
<div class="view">
<!--定义左右两个翻页的按钮-->
<a href="#" class="prev">< </a>
<a href="#" class="next">> </a>
<ul>
<li>
<img src="./img/鼠.jpg" alt="鼠">
</li>
<li>
<img src="./img/牛.jpg" alt="牛">
</li>
<li>
<img src="./img/羊.jpg" alt="羊">
</li>
</ul>
<!--定义下方随模块变化的标志-->
<ol class="circle">
<li></li>
<li></li>
<li></li>
</ol>
</div>
</body>
</html>
搭建CSS
搭建好HTML框架后,接下来利用CSS设置样式、完成布局和美化。
大致分为以下几个步骤:
1.处理整体样式和图片
*{
/*重置浏览器默认样式,统一标准*/
padding: 0;
margin: 0;
box-sizing: border-box;
}
li{
list-style: none;
}
img{
border:0;
vertical-align: middle; /*使图片垂直对齐*/
}
/*重点:利用相对定位和overflow将图片放在同一位置*/
.view{
position: relative; /*子绝父相,懂得都懂*/
margin:150px auto;
width: 500px;
height: 400px;
overflow: hidden; /*只展现出一个图片,其他隐藏*/
}
.view ul{
position: absolute; /*依据父元素view进行定位*/
top:0;
left: 0;
width: 500%;
}
/*重点:利用float将图片排成一行*/
.view ul li{
float: left;
transform: translateZ(0); /*提升性能,加快动画和转换*/
}
.view ul li img{
width: 500px;
height: 400px;
}
2.处理翻页按钮
a{
text-decoration: none;
color:blanchedalmond;
}
.prev,.next{
position: absolute;
width: 20px;
height: 40px;
background-color: rgba(0,0,0,0.3);
top: 50%;
margin-top: -15;
color: #fff;
text-align: center;
line-height: 40px;
font-size: 14px;
z-index: 2; /*z-index表示元素层级,层级高的在上面*/
}
.prev{
left: 0;
}
.next{
right: 0;
}
3.处理下方对应图片的标志
.view ol{
position: absolute;
width: 150px;
height: 15px;
bottom: 12px;
left: 40%;
}
ol li{
float: left; /*设置为浮动型,使得他们出现在一排*/
width: 20px;
height: 5px;
margin: 3px;
background-color: #666565;
padding-right: 5px;
}
ol .current {
background-color: #fff;
}
.nav .selected {
background-color: #f50;
}
这样页面样式就做好啦:
封装js代码
接下来需要写一个使画面动起来的函数action。
其中利用setInterval函数实现定时调用。它第一个参数是回调函数,每隔一定时间执行一次;
第二个参数是间隔时间,单位是毫秒
function action(obj,target,callback){
//清除定时器
clearInterval(obj.timer);
/*setInterval第一个参数是回调函数,每隔一定时间执行一次;
第二个参数是间隔时间,单位是毫秒*/
obj.timer = setInterval(function(){
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetleft==target){
clearInterval(obj.timer);
callback && callback();
}
obj.style.left = obj.offsetLeft + step + 'px';
},15);
}
之后先实现左右按钮的功能。
首先需要获取css选择器的元素,这里使用getElementById函数反而更复杂,所以可以通过querySelector获取左右按钮,从而改变样式。
window.addEventListener('load',function(){
//获取左右按钮
var prev = this.document.querySelector('.prev');
var next = this.document.querySelector('.next');
//获取轮番图
var view = this.document.querySelector('.view');
var viewWidth = view.offsetWidth;
//鼠标经过轮番图显示左右按钮
view.addEventListener('mouseenter',function(){
prev.style.display = 'block';
next.style.display = 'block';
clearInterval(timer);
timer = null;
});
//鼠标离开时不显示左右按钮
view.addEventListener('mouseleave',function(){
prev.style.display = 'none';
next.style.display = 'none';
timer = setInterval(function(){
next.click();
},2000);
});
再实现下部动态按钮的功能。
这时遇到一个困难:如何一直保持它的“动态”?-- 用for循环不断遍历。
//获取动态按钮
var ul = view.querySelector('ul');
var ol = view.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
// 创建一个li 节点
var li = document.createElement('li');
// 记录小圆圈的索引号
li.setAttribute('index', i);
// 把li插入ol里面 节点
ol.appendChild(li);
// 点击小圆圈 添加类 其余移除
li.addEventListener('click', function() {
// 把所有的小li 清除类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 当前小li 设置类名
this.className = 'current';
// 点击小圆圈移动图片 ul移动
// 点击某个小li就拿到那个小li的索引号
var index = this.getAttribute('index');
// 点击某个小li 就拿到当前li的索引号给circle num
num = circle = index;
console.log(viewWidth);
console.log(index);
action(ul, -index * viewWidth);
});
}
// 把ol里面的类名设为current
ol.children[0].className = 'current';
// 克隆第一张图片li 放到ul后面
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
重头戏来了,实现图片的滑动。
想实现不断循环,需要在图片走到最后时复原left为0即可。
这时可以用if (num == ul.children.length - 1) { ul.style.left = 0; num = 0; }解决。左侧按钮同理。
// 点击右侧按钮图片滑动一张
var num = 0;
var circle = 0;
//右侧按钮
next.addEventListener('click', function() {
// 无缝滑动
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
action(ul, -num * viewWidth);
// 点击右侧按钮 小圆圈一起变换
circle++;
if (circle == ol.children.length) {
circle = 0;
}
circleChange();
});
// 左侧按钮
prev.addEventListener('click', function() {
// 无缝滑动
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * viewWidth + 'px';
}
num--;
action(ul, -num * viewWidth);
// 点击右侧按钮 小圆圈一起变换
circle--;
// 先清除其余小圆圈的类名
// if (circle < 0) {
// circle = ol.children.length - 1
// }
circle = circle < 0 ? ol.children.length - 1 : circle;
// 调用函数
circleChange();
})
// 封装函数
function circleChange() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
// 自动播放轮播图
var timer = this.setInterval(function() {
// 手动点击事件
next.click();
}, 2000);
})
这样就大功告成啦!
结束语
本以为自己学会了JavaScript基础语法已经能做一些小项目了,出手敲代码之后才知道自己是多么无助。js代码远远比自己想的复杂,参考了博客blog.csdn.net/m0_56712012…
源码为我的思路提供了很大的帮助。也清楚认识到自己所学的远远不够。
前端学习还在继续!