主要方法
setInterval设置间隔clearInterval清空计时器setTimeout延时触发clearTimeout取消延时触发
常用例子
网页中显示当前时间setInterval
<body><h1>12:00:00</h1><script>let h1 = document.querySelector("h1");setInterval(()=>{let timeNow = new Date();let hours = timeNow.getHours();let minutes = timeNow.getMinutes();let seconds =timeNow.getSeconds();let time = `${hours}:${minutes}:${seconds}`h1.innerHTML = time;},500)</script></body>
制作一个秒表setInterval clearInterval
<body><button class="start" >start</button><button class="pause">pause</button><button class="stop">stop</button><h1 class="time">10:9</h1><script>let start = document.querySelector(".start");let pause = document.querySelector(".pause");let stop = document.querySelector(".stop");let time = document.querySelector(".time");let seconds = 0;let ms = 0;time.innerHTML = `${seconds}:${ms}`;let timer = null;start.onclick = function(){clearInterval(timer);//防止重复点击时多个计时器使计数加快timer = setInterval(()=>{if(ms==9){seconds++;ms=0}ms++;time.innerHTML = `${seconds}:${ms}`;},100)}pause.onclick = function(){clearInterval(timer);}stop.onclick = function(){clearInterval(timer);seconds = 0;ms = 0;time.innerHTML = `${seconds}:${ms}`;}</script></body>
五秒后跳转setTimeout
<body><h1>Jump to Baidu after 5s</h1><script>setTimeout(()=>{location.href = "http://baidu.com"},5000)</script></body>
⭐防抖与节流(debounce & throttle)
目的:解决开发中常会遇到的性能问题
防抖:对于短时间多次触发事件的情况,使用防抖来停止事件持续触发
节流:防止短时间多次触发事件的情况,但是间隔时间内,还是需要不断触发
防抖
方法:window.onsroll , setTimeout
效果:一直滚动时不会一直执行“业务程序”,而停下来后过片刻才执行“业务程序”
<body><style>body{height: 2000px;}</style><h1>window.onscroll</h1><script>//防抖let timer = null;window.onscroll = function() {if(timer !== null){clearTimeout(timer);}timer = setTimeout(()=>{console.log("业务逻辑程序");timer = null;},500)//鼠标滚动事件被执行,setTimeout赋值给timer,此时timer不为null,0.5s内,onscroll事件被再次执行的话,timer依旧不为null,timer计时器则被clear,0.5s内事件没被执行,则执行业务逻辑程序,且timer被赋值为null}</script></body>
鼠标滚动事件被执行,setTimeout赋值给timer,使得timer不为null。若0.5s内,onscroll事件被再次执行的话,timer依旧不为null,timer计时器则被clear,重新计时;若0.5s内事件没被执行,则执行业务程序,且timer被赋值为null。
节流
方法:window.onsroll , setTimeout
效果:滚动时,间断地执行“业务程序”
<body><style>body{height: 2000px;}</style><h1>window.onscroll</h1><script>//节流let mark = true;window.onscroll = function(){if(mark){setTimeout(()=>{console.log("业务逻辑程序");mark = true;},500)}mark = false;}//onscroll事件执行了,此时setTimeout开始计时,mark被赋值为false,在计时结束之前--里面的方法被执行之前,mark始终为false,这个阶段onscroll事件都无法触发“业务逻辑事件”,直到计时器里面的方法被执行,才可执行“业务逻辑程序”。</script></body>
onscroll事件执行了,此时setTimeout开始计时,mark被赋值为false,在计时结束之前—里面的方法被执行之前,mark始终为false,这个阶段onscroll事件都无法触发“业务程序”,直到计时器里面的方法被执行,才可执行“业务程序”。
利用防抖与节流做一个返回顶部效果
方法:window.onscroll滚动条滚动事件document.documentElement.scrollTop页面滚动后与顶部距离window.scrollTo(x,y)使横向滚动条到x坐标处,竖向滚动条到y坐标处
防抖初始版本:
<body><style>#jump{position:fixed;right: 50px;bottom: 50px;width:60px;display:none;}body{height:4000px;}</style><h1>Top</h1><button id="jump">Jump To Top</button><script>let JumpBtn = document.querySelector("#jump");JumpBtn.onclick = function(){window.scrollTo(0,0);}let timer = null;//这里我们直接复制刚刚的防抖代码,把“业务逻辑程序”替换了window.onscroll = function() {if(timer !== null){clearTimeout(timer);}timer = setTimeout(()=>{//console.log("业务逻辑程序");if(document.documentElement.scrollTop > 0){JumpBtn.style.display="block";}else{JumpBtn.style.display="none";}timer = null;},500)}</script></body>
防抖闭包封装代码版本:
function debounce(businessLogicProgram){//防抖逻辑函数,业务逻辑程序作为参数调用let timer = null;function eventFunc(){if(timer !== null){clearTimeout(timer);}timer = setTimeout(()=>{//业务逻辑程序businessLogicProgram();timer = null;},500)}return eventFunc;}businessLogicProgram = function (){console.log("计数器")//用于测试if(document.documentElement.scrollTop >0){JumpBtn.style.display="block";}else{JumpBtn.style.display="none";}}window.onscroll = debounce(businessLogicProgram);//如需换个别的业务程序,只需新增一个函数后更改参数调用
功能效果逻辑一样,但是有了更好的可读性,多次使用时也更为简洁方便。
节流闭包版本
基本封装逻辑与防抖闭包版本一致
<body><style>#jump{position:fixed;right: 50px;bottom: 50px;width:60px;display:none;}body{height:4000px;}</style><h1>Top</h1><button id="jump">Jump To Top</button><script>let JumpBtn = document.querySelector("#jump");JumpBtn.onclick = function(){window.scrollTo(0,0);}function throttle(businessLogicProgram){let mark = true;function eventFunc(){if(mark){setTimeout(()=>{// console.log("业务逻辑程序");businessLogicProgram();mark = true;},500)}mark = false;}return eventFunc;}businessLogicProgram = function (){console.log("计数器")//用于测试if(document.documentElement.scrollTop >0){JumpBtn.style.display="block";}else{JumpBtn.style.display="none";}}window.onscroll = throttle(businessLogicProgram);</script></body>
也可以进一步优化简洁封装函数
function throttle(businessLogicProgram){let mark = true;return function(){if(mark){setTimeout(()=>{// console.log("业务逻辑程序");businessLogicProgram();mark = true;},500)}mark = false;};}
0.0
本文讲了鼠标滚动事件的情况,实际上,还有很多其他情况。开发时自然会遇到需要优化性能的时候,可以根据情况选择防抖或者节流。
