一、setInterval()与clearInterval()
<body>
<button class="btn">暂停</button>
<script>
let timer = setInterval(function () {
console.log("hello world");
}, 1000)
let btn = document.querySelector(".btn");
btn.onclick = function () {
clearInterval(timer);
}
</script>
</body>
效果如下:
分析:
可以给setInterval设置一个返回值timer。
那么就可以使用clearInterval(timer),来终止计时器。
二、案例一——显示当前时间
<body>
<h1></h1>
<script>
let h1 = document.querySelector("h1");
setInterval(function () {
let time = new Date();
let hours = time.getHours();
let minutes = time.getMinutes();
let seconds = time.getSeconds();
h1.innerHTML = `${hours}:${minutes}:${seconds}`;
}, 1000)
</script>
</body>
效果如下:
分析:
每隔1秒,自动获取当前时间,并在浏览器中显示。
三、案例二——秒表
<!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>Demo27</title>
</head>
<body>
<button class="start">开始</button>
<button class="pause">暂停</button>
<button class="stop">重置</button>
<h1></h1>
<script>
let start = document.querySelector(".start");
let pause = document.querySelector(".pause");
let stop = document.querySelector(".stop");
let h1 = document.querySelector("h1");
let seconds = 0;
let ms = 0;
h1.innerHTML = `${seconds}:${ms}`;
let timer = null;
start.onclick = function () {
// 重复点击开始按钮时,先停止上一次的计时器
clearInterval(timer);
timer = setInterval(() => {
if (ms === 9) {
++seconds;
ms = 0;
}
++ms;
h1.innerHTML = `${seconds}:${ms}`;
}, 100);
}
pause.onclick = function () {
clearInterval(timer);
}
stop.onclick = function () {
clearInterval(timer);
seconds = 0;
ms = 0;
h1.innerHTML = `${seconds}:${ms}`;
}
</script>
</body>
</html>
效果如下:
四、setTimeout和clearTimeout
<body>
<h1>5秒后,跳转到百度...</h1>
<script>
setTimeout(() => {
location.href = "https://www.baidu.com";
}, 5000)
</script>
</body>
效果如下:
分析:
location.href:表示跳转到其他链接。
setTimeout():表示,过多少秒后,执行方法。
五、防抖与节流
1、提出问题
某些事件,在短时间内会触发很多次。这极大的影响了性能。
比如window.onscroll事件,如下:
<!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>Demo29</title>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<h1>windows.onscroll</h1>
<script>
window.onscroll = function(){
console.log("hello world");
}
</script>
</body>
</html>
效果如下:
如图所示,鼠标滚轮轻轻滚动,事件在短时间内就触发了很多次。
如何解决呢?
2、防抖
<!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>Demo29</title>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<h1>windows.onscroll</h1>
<!-- 防抖 -->
<script>
let timer = null;
window.onscroll = function () {
// timer(计时器)不为空时,则让它停止
if (timer != null) {
clearTimeout(timer);
}
// 鼠标滚动一次,则立马执行计时器
// 计时器启动时,timer就不为空,则立马停止,并且打印,并且将timer置为空
timer = setTimeout(() => {
console.log("hello world");
timer = null;
}, 500)
}
</script>
</body>
</html>
效果如下:
效果分析:
在0.5秒内,如果多次滚动滚轮,则不会重复执行事件。
停止滚动时,才执行事件。
代码分析:
当鼠标滚动时,启动计时器,0.5秒后,执行事件。也就是说,0.5秒内,setTimeout内的代码没有执行。
此时,timer不为空了。就会把上一次的计时器(或者可以称作延时器)清除掉,并且鼠标持续滚动,也就是持续地开启下一个计时器。
直到我们停止滚轮滚动,清除计时器的代码不再执行,就只执行最后一次(上一次的计时器没有清除掉)的代码。
并且将timer置为空,下次可以再次使用。
从而实现防抖功能。
一次都不会执行。
3、节流
<!-- 节流 -->
<script>
let mark = true;
window.onscroll = function () {
if (mark) {
setTimeout(() => {
console.log("hello world");
mark = true;
}, 500)
}
mark = false;
}
</script>
效果如下:
效果分析:
当我们持续滚动滚轮时,每隔0.5秒,照样会执行事件。
当我们停止滚动时,最后再执行一次,则停止执行事件。
代码分析:
设个标记mark,初值为true。
滚轮滚动时,开启计时器,0.5秒后执行事件。
随后,mark被置为false。此时不再进入if方法。
然而,0.5秒后,事件启动,并且mark再次被置为true。因为滚轮持续在滚动,则,再一次进入if方法。从而开启下一个计时器。
这样就达到每0.5秒都执行一次事件。
4、案例——返回顶部(利用闭包封装算法)
<!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>Demo30</title>
<style>
body {
height: 2000px;
}
button {
position: fixed;
right: 100px;
bottom: 100px;
display: none;
}
</style>
</head>
<body>
<h1>hello world</h1>
<button>⬆</button>
<script>
let btn = document.querySelector("button");
btn.onclick = function () {
window.scrollTo(0, 0);
};
// 防抖
function debounce(fn) {
let timer = null;
function eventFun() {
if (timer != null) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn();
timer = null;
}, 500)
}
return eventFun;
}
// 节流
function throttle(fn) {
let mark = true;
// 直接返回函数也可以
return function () {
if (mark) {
setTimeout(() => {
fn();
mark = true;
}, 500)
}
mark = false;
}
}
window.onscroll = debounce(() => {
console.log("计数器");
if (document.documentElement.scrollTop > 0) {
btn.style.display = "block";
} else {
btn.style.display = "none";
}
});
</script>
</body>
</html>
分析:
实现的是一个:网页中的返回顶部功能。
其中使用到了防抖/节流。
通过闭包将防抖/节流算法封装起来。
input输入框,停下来时才去识别,这也可以使用防抖。