原生轮播图
1、封装一个简单的动画函数
animate.js文件
// 主要进行简单动画函数的封装
/*
业务实现:封装的animate动画主要实现obj对象简单的左右移动的功能
其中,obj为目标对象;target为对象需要移动的目标;
callback为回调函数,可以在动画结束后实现相关的操作
*/
function animate(obj, target, callback) {
// 清除在此之前的定时器,保证一次只开一个定时器
clearInterval(obj.timer);
//使用定时器实现左右移动,其中,给每一个对象设置一个定时器
obj.timer = setInterval(() => {
//这里让动画减速运行,每次运行时,步长按规律减小,但是这样的话,步长值可能有小数,需要取整
var step = (target - obj.offsetLeft) / 10;
//对步长值取整。向右移动时,向上取整(Math.ceil);向左移动时,向下取整(Math.floor)
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target) {
// 如果到达目的地之后,清除动画
clearInterval(obj.timer);
if(callback) {
// 如果传入的参数有回调函数,则调用回调函数
callback();
}
}
// obj.style.left获取的是具有定位属性的父元素的左边距。
// 并且obj.style.left是可读写的;而obj.offsetLeft是只读的属性,返回值为数值
obj.style.left = obj.offsetLeft + step + 'px'; // 每调用一次,就会计算一下left值
}, 15);
}
使用animation.js中的动画效果
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<title>animate动画实现</title>
</head>
<style>
span {
display: block;
position: relative;
top: 50px;
left: 0;
width: 200px;
height: 200px;
background-color: #42b983;
}
</style>
<script src="animate.js"></script>
<body>
<button class="btn400">移动到400的位置</button>
<button class="btn800">移动到800的位置</button>
<span>YiBo</span>
<script>
window.addEventListener('load', function (){
// var btn400 = document.getElementById('btn400');
// var Box1 = document.getElementById('Box1');
var btn400 = document.querySelector('.btn400');
var btn800 = document.querySelector('.btn800');
var span = document.querySelector('span');
btn400.addEventListener('click', function () {
animate(span, 400);
// alert("1");
});
btn800.addEventListener('click', function() {
animate(span, 800);
})
})
</script>
</body>
</html>
2、轮播图的实现
实现思路及满足的效果
网页轮播图需要满足的功能需求为:
- 鼠标经过轮播图模块时,左右按钮显示,鼠标离开,左右按钮隐藏
- 点击右侧按钮一次,图片向左播放一张。以此类推,左侧按钮同理,点击左侧按钮,图片向右播放一张。
- 图片播放的同时,下面的小圆圈模块跟随其一起变换
- 点击小圆圈,可以播放相应的图片
- 鼠标不经过轮播图,轮播图也会自动播放图片
- 鼠标经过轮播图模块,自动播放停止
实现的步骤、过程:
1)鼠标经过时:进行相应的显示隐藏左右箭头
通过设置元素.style.display = ‘block’ / ‘none’ 来实现
2)动态生成小圆圈
小圆圈的个数要跟图片的张数保持一致,所以我们可以根据图片的张数,动态的生成 li 的个数
思路:循环动态生成小圆点
创建节点:createElement(‘li’)
插入节点:ol.appendChild(li)
给第一个小圆点,默认添加current类
3)小圆圈的排他思想
点击当前小圆圈,就添加current类;其余的小圆圈就移除这个current类
注意:在生成小圆圈时,就绑定点击事件
4)点击小圆圈滚动图片
此时可以用到我们封装过的animate动画函数。需要将js文件引入,注意:animate.js文件引入在前,因为index.js文件需要用到animate.js文件
注意:
使用动画前,该元素必须有定位
是ul移动,不是li移动
计算滚动图片的距离:点击某个小圆圈,就让图片滚动,移动距离为:小圆圈的索引号乘以图片的宽度
5)右侧按钮无缝滚动
需求:点击右侧按钮一次,就让图片滚动一张
实现思路:
声明一个变量num,点击右侧按钮(箭头)一次,让这个变量乘以图片宽度,就是ul滚动的距离
图片要做到无缝滚动的原理
把ul第一个li复制一份,放到ul的最后面
当图片滚动到克隆的最后一张图片时,让ul快速地、不做动画的跳到最左侧:left为0,同时将num赋值为0,然后就可以从新开始滚动了。
6)克隆第一张图片
克隆ul的第一个li,cloneNode(),传入的参数为true,为深克隆,可复制里面的节点
将克隆的li,使用appendChild(),添加到ul的后面
7)小圆圈跟随右侧按钮变化
点击右侧按钮(箭头),小圆圈跟随其变化
最简单的做法是再声明一个变量circle,每次点击自增1。需要注意的是:左侧按钮也需要这个变量,所以可以声明为全局变量
但是图片比我们生成的小圆圈多一个,所以,必须加一个判断条件
如果circle == 4 (ul.length - 1),就重新复原为0
添加一个定时器
自动播放轮播图,实际上就类似于点击了右侧按钮
使用手动调用右侧按钮点击事件 arrow_r.click()即可
鼠标经过focus就停止定时器
鼠标离开时就开启定时器
节流阀:
作用:防止轮播图按钮连续点击造成播放过快
节流阀的目的:当上一个函数动画内容执行完毕,再执行下一个函数动画,让事件无法连续触发
核心实现思路:利用回调函数,添加一个变量来控制,锁住和解锁函数
文件的目录结构:
index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<title>原生轮播图</title>
<link rel="stylesheet" href="css/index.css">
<script src="js/animate.js"></script>
<script src="js/index.js"></script>
</head>
<body>
<div class="focus">
<!--左箭头-->
<a href="javascript:;" class="arrow-l"><</a>
<!--右箭头-->
<a href="javascript:;" class="arrow-r">></a>
<!--轮播图的图片展示-->
<ul>
<li>
<a href="#"><img src="./images/11.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="./images/12.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="./images/14.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="./images/15.jpg" alt=""></a>
</li>
</ul>
<!--小圆点显示-->
<ol class="circle">
</ol>
</div>
</body>
</html>
index.css文件
/* 1. 配置基础的css样式*/
* {
margin: 0;
padding: 0;
}
/*去除li前面的点点*/
li {
list-style: none;
}
/*去除链接的下划线*/
a {
color: #666;
text-decoration: none;
}
/* 2.配置项目中的样式 */
.focus {
position: relative;
width: 320px;
height: 320px;
margin: 20px auto;
overflow: hidden;
background-color: #42b983;
}
.focus ul {
position: absolute;
top: 0;
left: 0;
width: 600%;
}
.focus ul li {
float: left;
}
.arrow-l,
.arrow-r{
display: none;
position: absolute;
top: 50%;
margin-top: -20px; /* 和top:50%搭配,使其在父元素中垂直居中*/
width: 24px;
height: 40px;
line-height: 40px; /* 让箭头垂直居中*/
text-align: center; /* 让箭头水平居中 */
background-color: rgba(0, 0, 0, .3);
color: #fff;
z-index: 1; /*提高元素的层级,不然显示不出来*/
}
.arrow-r {
right: 0;
}
.circle {
position: absolute;
bottom: 10px;
left: 50px
}
.circle li {
float: left;
width: 8px;
height: 8px;
/*background-color: #fff;*/
border: 2px solid rgba(255, 255, 255, 0.5);
margin: 0 3px;
border-radius: 50%;
}
.current {
background-color: #fff;
}
index.js文件
window.addEventListener('load', function () {
//获取元素
var arrow_l = document.querySelector('.arrow-l');
var arrow_r = document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
var focusWidth = focus.offsetWidth; //获取轮播图区域的大小,也就是图片的大小,它们是相等的
// 1.鼠标经过时,显示隐藏的箭头
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
// 鼠标经过时,停止定时器
clearInterval(timer);
timer = null;
})
//2.鼠标离开时,隐藏箭头
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
// 鼠标离开时,开启定时器
timer = setInterval(() => {
arrow_r.click()
}, 2500)
})
// 3.动态生成小圆点:有几张图片,就生成几个
var ul = focus.querySelector('ul');
var ol = focus.querySelector('.circle');
for(var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
// 记录小圆圈创建的索引号,使用setAttribute(),设置自定义属性
li.setAttribute('index', i);
ol.appendChild(li);
// 4.小圆圈的排他思想,添加current类
li.addEventListener('click', function() {
// 干掉其他人
for(var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// this指的是当前事件监听的li 留下我自己
this.className = 'current';
// 5.点击小圆圈,滚动图片,滚动距离:小圆圈的索引值*图片的宽度
// 获取当前li的索引值
var index = this.getAttribute('index');
num = index;
circle = index;
animate(ul, -index * focusWidth)
})
}
// 将ol中的第一个孩子的类名设置为current
ol.children[0].className = "current";
// 6.克隆第一个li,放在ul的最后 这里是深克隆呀
var first = ul.children[0].cloneNode(true);
ul.appendChild(first); //这个不会影响之前设置index的li,因为克隆没有在循环中克隆
// 7.点击右侧按钮(箭头),图片滚动一张
var num = 0; //用来标记当前的图片索引,作用与index相似
var circle = 0; //circle,用来控制小圆圈的播放
var flag = true; // 设置节流阀,否则使用定时器点击左右轮播的按钮时,它会越来越快
arrow_r.addEventListener('click', function () {
if(flag) {
flag = false; //关闭节流阀
// 如果走到了最后克隆的这张图片,此时,ul要快速复原
if(num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function () {
flag = true; // 打开节流阀
});
// 8.点击右侧按钮时,小圆圈也跟着改变
circle++;
if(circle == ol.children.length) {
circle = 0; //遍历完了之后,重置为0
}
circleChange(); //因为后面需要用到小圆圈的变化,所以,我们可以将其抽取为一个函数
}
})
// 左侧按钮的功能实现
arrow_l.addEventListener('click', function () {
if(flag) {
flag = false; // 关闭节流阀
// 如果走到了最后克隆的这张图片,此时,ul要快速复原
if(num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth, function () {
flag = true; // 打开节流阀
});
// 8.点击右侧按钮时,小圆圈也跟着改变
circle--;
if(circle < 0) {
circle = ol.children.length - 1; //遍历完了之后,重置为0
}
circleChange(); //因为后面需要用到小圆圈的变化,所以,我们可以将其抽取为一个函数
}
})
// 清除小圆点函数
function circleChange() {
// 清除其他小圆圈的current类名
for(var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
// 10.自动播放轮播图
var timer = setInterval(() => {
// 手动调用点击事件
arrow_r.click();
}, 2500)
})
实现效果:
原文地址:https://www.jb51.cc/wenti/3285415.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。