定时器作用及语法
💥💥💥💥💥 :定时器的使用与清除定时器,以下 1.1 ~1.3 为验证过程,不推荐使用
推荐使用 🎈🎈🎈 : 1.2缓速动画介绍
1.1-setInterval 定时器
定时器:某一件事(一段代码)并不是马上执行,而是隔一段时间执行
- setInterval:创建定时器
- 特点:一旦创建立即计时,必须要手动停止,否则会无限的每隔一段时间执行代码
- clearInterval(定时器id):清除定时器
- 一个页面可以创建很多个定时器,通过制定定时器id可以清除特定的定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>定时器</title>
<style>
.box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: rgb(235, 12, 49);
}
</style>
</head>
<body>
<div class="box"></div>
</body>
<script>
// 定时器:setInterval(回调函数,间隔时间:ms)
console.log("定时器开始了");
setInterval(function () {
console.log("宝,早安");
}, 1000);
console.log("定时器结束了");
// 非定时器代码:叫主代码
// 主代码一定是先执行(不论时间多长,后草开始定时器的执行(等主代码执行结束后:才开始计时))
setInterval(function () {
console.log("晚安");
}, 1500);
// 一个页面可以有多个定时器:彼此之间独立,互不影响
// 动画效果:效果 结合 定时器
// 点击盒子:盒子每次移动10px,移动到600结束
document.querySelector(".box").onclick = function () {
let box = this;
// 开一个定时器
setInterval(function () {
// 判定是否到600
if (box.offsetLeft < 600) {
box.style.left = box.offsetLeft + 10 + "px";
}
}, 100);
};
</script>
</html>
清除定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>定时器 - 清除定时器</title>
<style>
.box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: rgb(235, 12, 49);
}
</style>
</head>
<body>
<div class="box"></div>
</body>
<script>
// 需求: 移动到600结束
// 清理定时器: clearInterval(句柄: 定时器序号)
// 定时器setInterval()会返回一个句柄: 定时器序号
const box = document.querySelector(".box");
console.log(box);
box.onclick = function () {
// 动画:必须开启定时器
let timeId = setInterval(function () {
console.log("定时器开始了");
// 动画
box.style.left = box.offsetLeft + 10 + "px";
// 判定安全
if (box.offsetLeft >= 600) {
// 清除定时器
clearInterval(timeId);
}
}, 100);
console.log(timeId);
// 清理定时器: clearInterval(句柄: 定时器序号)
// clearInterval(timeId);
};
// 定时器:可以清理(一般是达到条件之后才清理)
</script>
</html>
1.2-setTimeout 延时器
- 定时器setTimeout与setInterval唯一的区别是,setTimeout定时器只会执行一次
- 总结:
- 1.如果你想让这个代码一段时间后只执行一次,使用setTimeout
- 2.如果你想让这个代码每隔一段时间执行一次(执行多次),使用setInterval
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>延时器 - 广告</title>
<style>
.adv {
position: fixed;
left: 10%;
top: 10%;
width: 80%;
height: 80%;
background-color: pink;
display: none;
}
.txt {
position: absolute;
left: 40%;
top: 40%;
}
.close {
position: absolute;
right: 0;
}
</style>
</head>
<body>
<div class="adv">
<div class="txt">这是一则广告</div>
<div class="close">
广告剩余时间<span>5</span>秒
<button>X</button>
</div>
</div>
<script>
// 需求:5秒展开广告, 用户点击关闭, 也可以看20s自动关闭
// 获取元素
const adv = document.querySelector(".adv");
const time = document.querySelector(".close span");
const btn = time.nextElementSibling;
console.log(adv, time, btn);
// 延时器: 5秒钟后开启广告, setTimeout(回调函数,时间间隔)
setTimeout(function () {
adv.style.display = "block";
// 开启定时器:关闭广告
let timeId = setInterval(function () {
time.innerText--;
// 判定:清除定时器
if (time.innerText == 0) {
clearInterval(timeId);
adv.style.display = "none";
}
}, 1000);
// 3.点击关闭
btn.onclick = function () {
// 是会员才行
// 结束广告(主动清理定时器)
clearInterval(timeId);
adv.style.display = "none";
};
}, 5000);
</script>
</body>
</html>
1.2-动画介绍(匀速动画)
- 需求:点击开始按钮,让div向右移动800px ,动画效果
- 动画可以理解为物理中的运动,运动三要素:v = s/t (速度 = 距离/时间)
- 如果没有时间因素,则会造成瞬移效果
- 1.如果直接修改div的left值就会瞬间移动,没有动画效果
- 2.动画效果:让div的left值每隔一段时间向右移动一点,直到移动800为止
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>匀速效果 - 动画</title>
<style>
.box {
position: absolute;
left: 0;
top: 200px;
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<button class="to600">移动到600</button>
<button class="to0">移动到0</button>
<div class="box"></div>
<script>
// 需求1: 点击移动到600,盒子匀速移动到600(10px/100ms)
const box = document.querySelector(".box");
document.querySelector(".to600").onclick = function () {
// 定时器
let timeId = setInterval(function () {
// 移动10px
box.style.left = box.offsetLeft + 10 + "px";
// 结束
if (box.offsetLeft >= 600) {
// 回调: 不能超过600
box.style.left = 600 + "px";
clearInterval(timeId);
}
}, 20);
};
document.querySelector(".to0").onclick = function () {
// 定时器
let timeId = setInterval(function () {
// 移动10px
box.style.left = box.offsetLeft - 10 + "px";
// 结束
if (box.offsetLeft <= 0) {
// 回调: 不能超过0
box.style.left = 0 + "px";
clearInterval(timeId);
}
}, 20);
};
// 总结
// 1. 匀速运动: 要注意移动的步长是否能够支持刚好走到目标(不是刚好,需要回调)
</script>
</body>
</html>
1.3-动画介绍(匀速动画)防抖
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>匀速效果 - 动画防抖</title>
<style>
.box {
position: absolute;
left: 0;
top: 200px;
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<button class="to600">移动到600</button>
<button class="to0">移动到0</button>
<div class="box"></div>
<script>
// 需求1: 点击移动到600,盒子匀速移动到600(10px/100ms)
// 获取相关元素
const to600 = document.querySelector(".to600");
const to0 = document.querySelector(".to0");
const box = document.querySelector(".box");
console.log(to600, to0, box);
// 防抖方案1:把保存的定时器变量 全局化 : 只要这个元素有定时器.都共用一个变量保存
// let timeId; // 不允许页面存在多个动画(否则需要多个变量)
// 💥 防抖方案2:把定时器的变量 私有化 :只有自己能访问到,别的元素永远访问不到
// 元素.tiemId = 定时器 给元素增加一个属性:tiemId 保存定时器
// 点击 to600 移动盒子 到600 停止动画
to600.onclick = function () {
// 清理原来的定时器
clearInterval(box.timeId);
// 定时器动画
box.timeId = setInterval(function () {
// 开始移动,移动5px
box.style.left = box.offsetLeft + 5 + "px";
// 判定
if (box.offsetLeft > 600) {
// 到达终点,清除定时器
clearInterval(box.timeId);
box.style.left = "600px";
}
}, 10);
};
// 点击 to0 移动盒子 到0 停止动画
to0.onclick = function () {
// 清理原来的定时器
clearInterval(box.timeId);
// 定时器动画
box.timeId = setInterval(function () {
// 开始动画,移动5px
box.style.left = box.offsetLeft - 5 + "px";
// 判定
if (box.offsetLeft < 0) {
// 到达终点,清除定时器
clearInterval(box.timeId);
box.style.left = "0px";
}
}, 10);
};
// box.timeId && clearInterval(box.timeId);
// 总结
// 1. 匀速运动: 要注意移动的步长是否能够支持刚好走到目标(不是刚好,需要回调)
</script>
</body>
</html>
01-getComputedStyle()获取元素一切样式属性
元素属性操作 | 特点 | 应用场景 |
---|---|---|
点语法 | 可以修改任意样式,无法获取行外样式 | 修改元素样式 |
attribute | 操作自定义样式 | 操作自定义样式 |
getComputedStyle() | 不可以修改样式,可以获取任意样式(行内+行外) | 获取元素样式 |
element.currentStyle | 与getComputedStyle一致(仅限IE8及以前使用) | 获取元素样式 |
- 语法:
window.getComputedStyle(元素,伪元素)
- 返回值:对象类型(存储元素一切样式属性)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>获取全部样式</title>
<style>
.box {
width: 100px;
height: 200px;
background-color: #6cf;
opacity: 0.5;
}
.box::after {
content: "我是伪类信息";
}
</style>
</head>
<body>
<div class="box"></div>
</body>
<script>
// 获取全局样式:window.getComputedStyle(元素),是window下的一个方法
// 全局样式: 具体样式获取 getComputedStyle(元素).具体样式 || getComputedStyle(元素)[具体样式]
// 如果要拿到伪类样式: getComputedStyle(元素,'伪类') : 此时只能拿到伪类
// 获取元素
const box = document.querySelector(".box");
// 获取元素的全局样式
// const styles = getComputedStyle(box);
// console.log(styles);
// 获取元素的透明度
let op = getComputedStyle(box)["opacity"];
op = parseFloat(op);
// box.style.opacity = op + 0.1;
// console.log(box.style.opacity);
// 点击事件
box.onclick = function () {
let op = getComputedStyle(box)["opacity"];
op = parseFloat(op);
box.style.opacity = op + 0.1;
console.log(box.style.opacity);
};
</script>
</html>
02-缓速动画封装
1.1-缓动动画介绍
- 缓动动画核心计算公式:
本次需要移动距离 = (目标距离 - 当前距离)/10
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>缓速移动</title>
<style>
.box {
position: absolute;
left: 0;
top: 200px;
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<button class="to600">移动到600</button>
<button class="to0">移动到0</button>
<div class="box"></div>
<script>
// 需求1: 点击移动到600,盒子缓速移动到600(先快后慢)
// 主要逻辑:计算移动距离 (目标 - 当前位置) * 0.1
// 获取相关元素
const to600 = document.querySelector(".to600");
const to0 = document.querySelector(".to0");
const box = document.querySelector(".box");
console.log(to600, to0, box);
// 点击 to600 移动盒子 盒子缓速移动到600
to600.onclick = function () {
// // 清理原来的定时器
// clearInterval(box.timeId);
// 💥💥💥 短路运算:清理定时器(如果有box.timeId这个函数,就执行 && 后面的代码:清理定时器;如果没有这个函数,就算了~)
box.timeId && clearInterval(box.timeId);
// 定时器动画
box.timeId = setInterval(function () {
// 1. 找到当前自己的位置: getComputedStyle()
let current = getComputedStyle(box)["left"];
// 2. 字符串转数字
current = parseInt(current);
// console.log(current);
// 3. 计算步长 (目标 - 当前位置) * 0.1
let step = (600 - current) * 0.1;
// 💥 4.让像素一定为整数:不能是小数(往大变化:向上取整)
step = Math.ceil(step);
console.log(step);
// 💥 5. 判定是否达到了目标位置: 达到就清除 不要用目标判定: 用步长
if (step == 0) {
clearInterval(box.timeId);
}
// 6. 移动元素:当前位置 + 步长 + 单位
box.style.left = current + step + "px";
}, 10);
};
// 点击 to0 移动盒子 到0 停止动画
to0.onclick = function () {
// // 清理原来的定时器
// clearInterval(box.timeId);
// 💥💥💥 短路运算:清理定时器(如果有box.timeId这个函数,就执行 && 后面的代码:清理定时器;如果没有这个函数,就算了~)
box.timeId && clearInterval(box.timeId);
// 定时器动画
box.timeId = setInterval(function () {
// 找到元素当前位置,getComputedStyle()
let current = getComputedStyle(box)["left"];
// 字符串转数字,方便计算
current = parseInt(current);
// 计算步长(目标距离 - 当前位置) * 0.1
let step = (0 - current) * 0.1;
// 💥 像素一定为整数,不能是小数(往下变化;向下取整)
step = Math.floor(step);
console.log(step);
// 判定是否到达目标位置.到达就清除.不要用目标判定 用步长
if (step == 0) {
clearInterval(box.timeId);
}
// 移动元素 : 当前位置 + 步长 + 单位
box.style.left = current + step + "px";
}, 10);
};
</script>
</body>
</html>
1.2 缓速动画函数封装
不限元素 - 不限距离 - 不限方向
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>缓速动画 - 函数封装 - 不限元素 - 不限距离 - 不限方向</title>
<style>
div {
width: 100px;
height: 100px;
background-color: red;
}
.box {
position: absolute;
left: 0;
top: 50px;
}
.box1 {
position: absolute;
left: 0;
top: 200px;
background-color: greenyellow;
}
</style>
</head>
<body>
<button class="to600">移动到600</button>
<button class="to0">移动到0</button>
<button class="to400">移动到400</button>
<div class="box"></div>
<div class="box1"></div>
</body>
<script>
// 获取相关元素
const to600 = document.querySelector(".to600");
const to0 = document.querySelector(".to0");
const to400 = document.querySelector(".to400");
const box = document.querySelector(".box");
const box1 = document.querySelector(".box1");
console.log(to600, to0, to400, box, box1);
// to600点击事件
to600.onclick = function () {
// 调用函数(版本1.)
// animation();
// 调用含糊(版本2. : 传入元素)
// animation(box);
// 调用函数(版本3. : 传入目标)
animation(box, 600);
};
// to4oo点击事件
to400.onclick = function () {
// 调用函数(版本3. 传入元素,传入目标)
animation(box1, 400);
};
// to0点击事件
to0.onclick = function () {
// 调用函数(版本3. 传入元素,传入目标)
// 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
animation(box, 0);
animation(box1, 0);
};
// 代码重复率太高: 封装
// 定义函数,调用函数; 实现灵活性: 参数
// 1. 传入参数: 动画元素由外部传入, ele
// 2. 传入参数: 动画元素目标位置由外部传入, target
// 3. 修正取整逻辑: 判定step的正负即可(正向上,负向下)
function animation(ele, target) {
// 短路运算,清除原来存在的定时器
ele.timeId && clearInterval(ele.timeId);
// 定时器动画
ele.timeId = setInterval(function () {
// 1. 获取元素当前的位置,获取样式先
let current = getComputedStyle(ele)["left"];
current = ele.offsetLeft;
// 字符串转数字,方便计算
current = parseInt(current);
// 2. 计算步长(目标距离 - 当前位置) * 0.1
let step = (target - current) * 0.1;
// 像素一定为整数,(往大变化,向上取整)
// 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
if (step > 0) step = Math.ceil(step);
else step = Math.floor(step);
// 3. 判定 是否到达目标位置,到达了就清除 用步长判定
if (step == 0) {
clearInterval(ele.timeId);
}
// 4. 开始移动. 最终位置 = 元素当前位置 + 步长 + 单位
ele.style["left"] = current + step + "px";
}, 10);
}
</script>
</html>
不限属性
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>缓速动画 - 函数封装 - 不限属性</title>
<style>
div {
width: 100px;
height: 100px;
background-color: red;
}
.box {
position: absolute;
left: 0;
top: 50px;
}
.box1 {
position: absolute;
left: 0;
top: 200px;
background-color: greenyellow;
}
</style>
</head>
<body>
<button class="to600">移动到600</button>
<button class="to0">移动到0</button>
<button class="to400">移动到400</button>
<div class="box"></div>
<div class="box1"></div>
</body>
<script src="./js/animat.js"></script>
<script>
// 获取相关元素
const to600 = document.querySelector(".to600");
const to0 = document.querySelector(".to0");
const to400 = document.querySelector(".to400");
const box = document.querySelector(".box");
const box1 = document.querySelector(".box1");
console.log(to600, to0, to400, box, box1);
// to600点击事件
to600.onclick = function () {
animation(box, 1200, "left"); // 传入动画属性: 需要引号
};
// to4oo点击事件
to400.onclick = function () {
// top方向变化
animation(box1, 400, "top");
// 宽度变化
// animation(box1, 400, "width");
};
// to0点击事件
to0.onclick = function () {
animation(box, 0, "left");
};
</script>
</html>
缓速动画函数封装 js文件
// // 代码重复率太高: 封装
// // 定义函数,调用函数; 实现灵活性: 参数
// // 1. 传入参数: 动画元素由外部传入, ele
// // 2. 传入参数: 动画元素目标位置由外部传入, target
// // 3. 修正取整逻辑: 判定step的正负即可(正向上,负向下)
// // 传入参数:动画的属性(left/top/width/height)由外部传入,style:所有以px为单位的都可以使用
// function animation(ele, target,style) {
// // 短路运算,清除原来存在的定时器
// ele.timeId && clearInterval(ele.timeId);
// // 定时器动画
// ele.timeId = setInterval(function () {
// // 1. 获取元素当前的位置
// let current = getComputedStyle(ele)[style];
// // 字符串转数字,方便计算
// current = parseInt(current);
// // 2. 计算步长(目标距离 - 当前位置) * 0.1
// let step = (target - current) * 0.1;
// // 像素一定为整数,(往大变化,向上取整)
// // 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
// if (step > 0) step = Math.ceil(step);
// else step = Math.floor(step);
// // 3. 判定 是否到达目标位置,到达了就清除 用步长判定
// if (step == 0) {
// clearInterval(ele.timeId);
// }
// // 4. 开始移动. 最终位置 = 元素当前位置 + 步长 + 单位
// ele.style[style] = current + step + "px";
// // 但凡不是独立的:一定是属性
// // ele.style : 元素ele的行内样式
// // [style] : 独立一定代表变量
// }, 10);
// }
// 代码重复率太高: 封装
// 定义函数,调用函数; 实现灵活性: 参数
// 1. 传入参数: 动画元素由外部传入, ele
// 2. 传入参数: 动画元素目标位置由外部传入, target
// 3. 修正取整逻辑: 判定step的正负即可(正向上,负向下)
// 传入参数:动画的属性(left/top/width/height)由外部传入,style:所有以px为单位的都可以使用
function animation(ele, target,style,fn) {
// 短路运算,清除原来存在的定时器
ele.timeId && clearInterval(ele.timeId);
// 定时器动画
ele.timeId = setInterval(function () {
// 1. 获取元素当前的位置
let current = getComputedStyle(ele)[style];
// 字符串转数字,方便计算
current = parseInt(current);
// 2. 计算步长(目标距离 - 当前位置) * 0.1
let step = (target - current) * 0.1;
// 像素一定为整数,(往大变化,向上取整)
// 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
if (step > 0) step = Math.ceil(step);
else step = Math.floor(step);
// 3. 判定 是否到达目标位置,到达了就清除 用步长判定
if (step == 0) {
clearInterval(ele.timeId);
// 调用函数即可
// console.log(fn);
// fn()
// 上述方式直接调用:如果用户没有传入回调函数,代码报错
// 安全处理:是函数才调用
console.log(typeof fn); // typeof 可以判定函数:function字符串
if(typeof fn === 'function') fn()
}
// 4. 开始移动. 最终位置 = 元素当前位置 + 步长 + 单位
ele.style[style] = current + step + "px";
// 但凡不是独立的:一定是属性
// ele.style : 元素ele的行内样式
// [style] : 独立一定代表变量
}, 10);
}
连续动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>缓速动画 - 函数封装 - 连续动画</title>
<style>
.box {
position: absolute;
left: 0;
top: 50px;
width: 200px;
height: 200px;
background-color: rgb(0, 255, 255);
}
</style>
</head>
<body>
<button>转个圈</button>
<div class="box"></div>
</body>
<script src="./js/animation.js"></script>
<script>
const box = document.querySelector(".box");
const btn = document.querySelector("button");
btn.onclick = function () {
// 1. 让盒子移动到600 left
animation(box, 600, "left", function () {
// 2. 让盒子移动到400 top
animation(box, 400, "top", function () {
// 3. 让盒子移动到 0 left
animation(box, 0, "left", function () {
// 4. 让盒子移动到 50 top
animation(box, 50, "top"); // 可以无限套娃
});
});
});
};
</script>
</html>
函数封装 - 淡入淡出动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>缓速动画 - 函数封装 - 淡入淡出动画</title>
<style>
img {
opacity: 1;
}
</style>
</head>
<body>
<img src="./images/slidepic2.jpg" alt="" />
</body>
<script>
// 需求:点击一下图片,图片透明度降低到0.3(慢慢降低)
// 然后切换一张图片, 重新透明度变成1
// 需要额外封装一个函数
document.querySelector("img").onclick = function () {
let that = this;
// 透明底降低到0.3
fadeTo(this, 0.3, function () {
that.src = "./images/slidepic3.jpg";
fadeTo(that, 1);
});
};
// 封装函数
// 1.传入参数:ele,要变化的元素
// 2.传入参数:opacity,要变的目标
// 3.传入参数:fn,回到函数
function fadeTo(ele, opacity, fn) {
// 1.清除原来的定时器
ele.timeId && clearInterval(ele.timeId);
// 2.绑定定时器
ele.timeId = setInterval(function () {
// 3.获取元素当前的透明度(转数字)
let current = parseFloat(getComputedStyle(ele).opacity);
// 4.计算步长:放d大一百倍
let step = (opacity * 100 - current * 100) / 100;
if (step > 0) step = Math.ceil(step);
else step = Math.floor(step);
// 5.给元素重新赋值
ele.style.opacity = (current * 100 + step) / 100;
console.log(step);
// 6. 清理定时器
if (step == 0) {
clearInterval(ele.timeId);
if (typeof fn === "function") fn();
}
}, 10);
}
</script>
</html>
js - 淡入淡出动画
// 封装函数
// 1. 传入参数: ele,要变化的元素
// 2. 传入参数: opacity,要变到的目标
// 3. 传入参数: fn, 回调函数
function fadeTo(ele, opacity, fn) {
// 渐变: 定时器
// 1. 清理定时器
ele.timeId && clearInterval(ele.timeId)
// 2. 绑定定时器
ele.timeId = setInterval(function () {
// 2.1 获取原始透明度(转成数字)
let current = parseFloat(getComputedStyle(ele).opacity)
// 2.2 计算步长: 放到一百倍
let step = (opacity * 100 - current * 100) * 0.1
// console.log(current, step)
if (step > 0) step = Math.ceil(step)
else step = Math.floor(step)
// 2.3 给元素重新赋值
ele.style.opacity = (current * 100 + step) / 100
console.log(step)
// 2.4 清理定时器
if (step == 0) {
clearInterval(ele.timeId)
if (typeof fn === 'function') fn()
}
}, 20)
}