运动函数初级版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box1, .box2, .box3{
width: 200px;
height: 200px;
left: 100px;
background: red;
position: absolute;
}
.box2{
top: 200px;
background: green;
}
.box3{
top: 400px;
background: blue;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<script>
// 获取元素
let box1 = document.querySelector(".box1");
let box2 = document.querySelector(".box2");
let box3 = document.querySelector(".box3");
// 封装运动函数,参数一表示元素,参数二表示运动的最终目的地(位置、距离),参数三表示运动时间
function animate(ele, dest, duration){
// 规定运动频率
let interval = 20;
// 运动次数 = 运动时间 / 运动频率
let stepCount = duration / interval;
// 获取元素起点位置
let start = parseInt(getComputedStyle(ele)["left"]);
// 运动步长 = (目的地 - 起点位置) / 运动次数
let stepDistance = (dest - start) / stepCount;
// 定义一个变量,用于计算运动了几次
let count = 0;
// 开启定时器
let timer = setInterval(() => {
// 每运动一次,count加1
count++;
// 元素运动后的位置 = 起点位置 + 总运动距离
ele.style.left = start + stepDistance * count + "px";
// 判断何时关闭定时器
if(count >= stepCount){
clearInterval(timer);
}
}, interval);
}
// 调用函数
animate(box1, 1000, 1000);
animate(box2, 1000, 2000);
animate(box3, 1000, 3000);
</script>
</body>
</html>
运动函数高级版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box1, .box2, .box3, .box4{
width: 200px;
height: 200px;
left: 100px;
background: red;
position: absolute;
}
.box2{
top: 200px;
background: green;
}
.box3{
top: 400px;
background: blue;
}
.box4{
top: 600px;
background: orange;
}
</style>
</head>
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
<div class="box4">box4</div>
<script>
// 获取元素
let box1 = document.querySelector(".box1");
let box2 = document.querySelector(".box2");
let box3 = document.querySelector(".box3");
let box4 = document.querySelector(".box4");
// 封装运动函数,参数一表示元素,参数二表示一个对象(对象里面可以设置多个属性),参数三表示运动时间,参数四表示回调函数
function animate(ele, endObj, duration, callback){
// 规定运动频率
let interval = 20;
// 运动次数 = 运动时间 / 运动频率
let stepCount = duration / interval;
// 获取元素起点位置
let startObj = {};
// 通过循环参数二对象里面的属性,获取元素开始时与参数二对象里面的属性的初始值
for (let i in endObj){
// 将获取到的初始值放到一个startObj对象
// 因为使用getComputedStyle获取到的计算后样式,返回值是一个带有px的字符串,所以需要将其转为一个数值型
startObj[i] = parseInt(getComputedStyle(ele)[i]);
}
// 定义一个变量,用于计算运动了几次
let count = 0;
// 开启定时器
let timer = setInterval(() => {
// 每运动一次,count加1
count++;
// 通过循环改变元素的属性
for (let i in endObj){
// 开始位置(或者说是开始属性) + (最终位置(或者说是最终属性) - 开始位置(或者说是开始属性)) / 运动总次数 * 当前运动的第几次
let result = startObj[i] + (endObj[i] - startObj[i]) / stepCount * count;
// 假设参数endObj里面函数有一个透明的属性opacity,需要进行判断,因为opacity没有单位px
ele.style[i] = (i.toLowerCase() === "opacity") ? result:(result + "px");
}
// 判断何时运动结束
if(count >= stepCount){
clearInterval(timer);
// 回调函数
callback && callback();
// 上行代码等价于
// if(callback){callback()}
}
}, interval);
}
// 调用函数
animate(box1, {left: 1000}, 1000);
animate(box2, {left: 1000, top: 500}, 1000);
animate(box3, {left: 1000, top: 700, opacity: 0.5}, 1000);
animate(box4, {left: 1000, top: 900}, 1000, function(){console.log("回调函数")});
</script>
</body>
</html>
制作初级一个简单的轮播图
封装一个运动函数animate.js,方便调用
// 封装运动函数,参数一表示元素,参数二表示一个对象(对象里面可以设置多个属性),参数三表示运动时间,参数四表示回调函数
function animate(ele, endObj, duration, callback){
// 规定运动频率
let interval = 20;
// 运动次数 = 运动时间 / 运动频率
let stepCount = duration / interval;
// 获取元素起点位置
let startObj = {};
// 通过循环参数二对象里面的属性,获取元素开始时与参数二对象里面的属性的初始值
for (let i in endObj){
// 将获取到的初始值放到一个startObj对象
// 因为使用getComputedStyle获取到的计算后样式,返回值是一个带有px的字符串,所以需要将其转为一个数值型
startObj[i] = parseInt(getComputedStyle(ele)[i]);
}
// 定义一个变量,用于计算运动了几次
let count = 0;
// 开启定时器
let timer = setInterval(() => {
// 每运动一次,count加1
count++;
// 通过循环改变元素的属性
for (let i in endObj){
// 开始位置(或者说是开始属性) + (最终位置(或者说是最终属性) - 开始位置(或者说是开始属性)) / 运动总次数 * 当前运动的第几次
let result = startObj[i] + (endObj[i] - startObj[i]) / stepCount * count;
// 假设参数endObj里面函数有一个透明的属性opacity,需要进行判断,因为opacity没有单位px
ele.style[i] = (i.toLowerCase() === "opacity") ? result:(result + "px");
}
// 判断何时运动结束
if(count >= stepCount){
clearInterval(timer);
// 回调函数
callback && callback();
// 上行代码等价于
// if(callback){callback()}
}
}, interval);
}
调用运动函数,制作简单的轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul li {
list-style: none;
}
.carousel {
position: relative;
width: 600px;
height: 400px;
margin: 50px auto;
border: 3px solid #ccc;
overflow: hidden;
}
.imgList {
position: absolute;
width: 4200px;
height: 400px;
}
.imgList li {
float: left;
}
.dotList {
position: absolute;
width: 300px;
height: 40px;
bottom: 0;
right: 0;
display: flex;
justify-content: space-around;
}
.dotList li {
width: 20px;
height: 20px;
border-radius: 50%;
background: green;
cursor: pointer;
}
.dotList li.active {
background: red;
}
.btn {
position: absolute;
width: 600px;
height: 80px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
justify-content: space-between;
}
.btn span {
background: rgba(0, 0, 0, 0.2);
width: 50px;
text-align: center;
line-height: 80px;
font-size: 24px;
font-weight: bold;
color: moccasin;
cursor: pointer;
}
</style>
</head>
<body>
<div class="carousel" id="carousel">
<ul class="imgList">
<li><img src="../images/1.jpeg" alt=""></li>
<li><img src="../images/2.jpeg" alt=""></li>
<li><img src="../images/3.jpeg" alt=""></li>
<li><img src="../images/4.jpeg" alt=""></li>
<li><img src="../images/5.jpeg" alt=""></li>
<li><img src="../images/6.jpeg" alt=""></li>
<li><img src="../images/1.jpeg" alt=""></li>
</ul>
<ul class="dotList">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="btn">
<span class="prevBtn"><</span>
<span class="nextBtn">></span>
</div>
</div>
<!-- 引入js文件 -->
<script src="../js/animate.js"></script>
<script>
// 获取元素
let carousel = document.querySelector(".carousel");
let nextBtn = document.querySelector(".nextBtn");
let prevBtn = document.querySelector(".prevBtn");
let imgList = document.querySelector(".imgList");
let imgListLength = imgList.getElementsByTagName("li").length;
let dot = Array.from(document.querySelectorAll(".dotList li"));
// 定义一个变量,用于存放点击次数
let count = 0;
// 定义一个变量,用于设置动画结束之前多次点击无效,设置一把锁,开锁状态
let lock = true;
let nextHandler = () => {
// 如果处于上锁状态
if (!lock) {
return;
}
// 如果处于开锁状态,下面的代码将会被执行,动画结束前多次点击无效
lock = false;
// 点击一次加1
count++;
// 点击一次,图片左移一个图片的距离
animate(imgList, { left: -600 * count }, 1000, () => {
// 判断是否到了最后一张图片
if (count >= imgListLength - 1) {
// 将图片列表位置归零
imgList.style.left = 0;
// 将计数器归零
count = 0;
}
// 开锁
lock = true;
});
// 添加小圆点样式
change();
}
// 添加nextBtn事件监听
nextBtn.addEventListener("click", nextHandler);
// 添加prevBtn监听事件
prevBtn.addEventListener("click", () => {
// 如果处于上锁状态
if (!lock) {
return;
}
// 如果处于开锁状态,下面的代码将会被执行,动画结束前多次点击无效
lock = false;
// 点击一次减1
count--;
// 点击一次,图片右移一个图片的距离
// 判断是否是第一张图片
if (count < 0) {
// 因为小圆点的个数比图片的数量少1
count = imgListLength - 1;
imgList.style.left = -600 * count + "px";
count--;
}
animate(imgList, { left: -600 * count }, 1000, () => {
// 开锁
lock = true;
});
// 添加小圆点样式
change();
});
// 小圆点点击事件
dot.forEach(function (value, index) {
// 添加小圆点监听事件
value.addEventListener("click", () => {
// 如果处于上锁状态
if (!lock) {
return;
}
// 如果处于开锁状态,下面的代码将会被执行,动画结束前多次点击无效
lock = false;
// 切换图片,其实就是让图片运动到对应的图片,就是修改count
count = index;
animate(imgList, { left: -600 * count }, 1000, () => {
// 开锁
lock = true;
});
// 添加小圆点样式
change();
});
})
// 封装一个函数,用于设置小圆点样式
function change() {
// 清空所有小圆点样式
dot.forEach(function (value) {
value.className = "";
})
// 单独给count对应小圆点添加样式
// if(count === imgListLength - 1){
// // 第一个小圆点添加样式
// dot[0].className = "active";
// } else{
// dot[count].className = "active";
// }
// 简化写法
let dotCount = count === imgListLength - 1 ? 0 : count;
dot[dotCount].className = "active";
}
// 自动轮播
let timer = setInterval(() => {
nextHandler();
}, 2000);
// 鼠标移入事件
carousel.addEventListener("mouseenter", () => {
// 清除自动轮播
clearInterval(timer);
});
// 鼠标移出事件
carousel.addEventListener("mouseleave", () => {
// 启动自动轮播
timer = setInterval(() => {
nextHandler();
}, 2000);
});
</script>
</body>
</html>