主要方法

setInterval设置间隔
clearInterval清空计时器
setTimeout延时触发
clearTimeout取消延时触发

常用例子

网页中显示当前时间setInterval

  1. <body>
  2. <h1>12:00:00</h1>
  3. <script>
  4. let h1 = document.querySelector("h1");
  5. setInterval(()=>{
  6. let timeNow = new Date();
  7. let hours = timeNow.getHours();
  8. let minutes = timeNow.getMinutes();
  9. let seconds =timeNow.getSeconds();
  10. let time = `${hours}:${minutes}:${seconds}`
  11. h1.innerHTML = time;
  12. },500)
  13. </script>
  14. </body>

制作一个秒表setInterval clearInterval

  1. <body>
  2. <button class="start" >start</button>
  3. <button class="pause">pause</button>
  4. <button class="stop">stop</button>
  5. <h1 class="time">10:9</h1>
  6. <script>
  7. let start = document.querySelector(".start");
  8. let pause = document.querySelector(".pause");
  9. let stop = document.querySelector(".stop");
  10. let time = document.querySelector(".time");
  11. let seconds = 0;
  12. let ms = 0;
  13. time.innerHTML = `${seconds}:${ms}`;
  14. let timer = null;
  15. start.onclick = function(){
  16. clearInterval(timer);//防止重复点击时多个计时器使计数加快
  17. timer = setInterval(()=>{
  18. if(ms==9){seconds++;ms=0}
  19. ms++;
  20. time.innerHTML = `${seconds}:${ms}`;
  21. },100)
  22. }
  23. pause.onclick = function(){
  24. clearInterval(timer);
  25. }
  26. stop.onclick = function(){
  27. clearInterval(timer);
  28. seconds = 0;ms = 0;
  29. time.innerHTML = `${seconds}:${ms}`;
  30. }
  31. </script>
  32. </body>

五秒后跳转setTimeout

  1. <body>
  2. <h1>Jump to Baidu after 5s</h1>
  3. <script>
  4. setTimeout(()=>{
  5. location.href = "http://baidu.com"
  6. },5000)
  7. </script>
  8. </body>

⭐防抖与节流(debounce & throttle)


目的:解决开发中常会遇到的性能问题
防抖:对于短时间多次触发事件的情况,使用防抖来停止事件持续触发
节流:防止短时间多次触发事件的情况,但是间隔时间内,还是需要不断触发


防抖

方法:window.onsroll , setTimeout
效果:一直滚动时不会一直执行“业务程序”,而停下来后过片刻才执行“业务程序”

  1. <body>
  2. <style>
  3. body{
  4. height: 2000px;
  5. }
  6. </style>
  7. <h1>window.onscroll</h1>
  8. <script>
  9. //防抖
  10. let timer = null;
  11. window.onscroll = function() {
  12. if(timer !== null){
  13. clearTimeout(timer);
  14. }
  15. timer = setTimeout(()=>{
  16. console.log("业务逻辑程序");
  17. timer = null;
  18. },500)//鼠标滚动事件被执行,setTimeout赋值给timer,此时timer不为null,0.5s内,onscroll事件被再次执行的话,timer依旧不为null,timer计时器则被clear,0.5s内事件没被执行,则执行业务逻辑程序,且timer被赋值为null
  19. }
  20. </script>
  21. </body>

鼠标滚动事件被执行,setTimeout赋值给timer,使得timer不为null。若0.5s内,onscroll事件被再次执行的话,timer依旧不为null,timer计时器则被clear,重新计时;若0.5s内事件没被执行,则执行业务程序,且timer被赋值为null。


节流

方法:window.onsroll , setTimeout
效果:滚动时,间断地执行“业务程序”

  1. <body>
  2. <style>
  3. body{
  4. height: 2000px;
  5. }
  6. </style>
  7. <h1>window.onscroll</h1>
  8. <script>
  9. //节流
  10. let mark = true;
  11. window.onscroll = function(){
  12. if(mark){
  13. setTimeout(()=>{
  14. console.log("业务逻辑程序");
  15. mark = true;
  16. },500)
  17. }
  18. mark = false;
  19. }
  20. //onscroll事件执行了,此时setTimeout开始计时,mark被赋值为false,在计时结束之前--里面的方法被执行之前,mark始终为false,这个阶段onscroll事件都无法触发“业务逻辑事件”,直到计时器里面的方法被执行,才可执行“业务逻辑程序”。
  21. </script>
  22. </body>

onscroll事件执行了,此时setTimeout开始计时,mark被赋值为false,在计时结束之前—里面的方法被执行之前,mark始终为false,这个阶段onscroll事件都无法触发“业务程序”,直到计时器里面的方法被执行,才可执行“业务程序”。

利用防抖与节流做一个返回顶部效果

方法:
window.onscroll滚动条滚动事件
document.documentElement.scrollTop页面滚动后与顶部距离
window.scrollTo(x,y)使横向滚动条到x坐标处,竖向滚动条到y坐标处


防抖初始版本:
  1. <body>
  2. <style>
  3. #jump{
  4. position:fixed;
  5. right: 50px;
  6. bottom: 50px;
  7. width:60px;
  8. display:none;
  9. }
  10. body{
  11. height:4000px;
  12. }
  13. </style>
  14. <h1>Top</h1>
  15. <button id="jump">Jump To Top</button>
  16. <script>
  17. let JumpBtn = document.querySelector("#jump");
  18. JumpBtn.onclick = function(){
  19. window.scrollTo(0,0);
  20. }
  21. let timer = null;
  22. //这里我们直接复制刚刚的防抖代码,把“业务逻辑程序”替换了
  23. window.onscroll = function() {
  24. if(timer !== null){
  25. clearTimeout(timer);
  26. }
  27. timer = setTimeout(()=>{
  28. //console.log("业务逻辑程序");
  29. if(document.documentElement.scrollTop > 0){
  30. JumpBtn.style.display="block";
  31. }else{
  32. JumpBtn.style.display="none";
  33. }
  34. timer = null;
  35. },500)
  36. }
  37. </script>
  38. </body>

但是会发现,这种版本,这代码,也忒丑了~

防抖闭包封装代码版本:
  1. function debounce(businessLogicProgram){//防抖逻辑函数,业务逻辑程序作为参数调用
  2. let timer = null;
  3. function eventFunc(){
  4. if(timer !== null){
  5. clearTimeout(timer);
  6. }
  7. timer = setTimeout(()=>{
  8. //业务逻辑程序
  9. businessLogicProgram();
  10. timer = null;
  11. },500)
  12. }
  13. return eventFunc;
  14. }
  15. businessLogicProgram = function (){
  16. console.log("计数器")//用于测试
  17. if(document.documentElement.scrollTop >0){
  18. JumpBtn.style.display="block";
  19. }else{
  20. JumpBtn.style.display="none";
  21. }
  22. }
  23. window.onscroll = debounce(businessLogicProgram);//如需换个别的业务程序,只需新增一个函数后更改参数调用

功能效果逻辑一样,但是有了更好的可读性,多次使用时也更为简洁方便。

节流闭包版本

基本封装逻辑与防抖闭包版本一致

  1. <body>
  2. <style>
  3. #jump{
  4. position:fixed;
  5. right: 50px;
  6. bottom: 50px;
  7. width:60px;
  8. display:none;
  9. }
  10. body{
  11. height:4000px;
  12. }
  13. </style>
  14. <h1>Top</h1>
  15. <button id="jump">Jump To Top</button>
  16. <script>
  17. let JumpBtn = document.querySelector("#jump");
  18. JumpBtn.onclick = function(){
  19. window.scrollTo(0,0);
  20. }
  21. function throttle(businessLogicProgram){
  22. let mark = true;
  23. function eventFunc(){
  24. if(mark){
  25. setTimeout(()=>{
  26. // console.log("业务逻辑程序");
  27. businessLogicProgram();
  28. mark = true;
  29. },500)
  30. }
  31. mark = false;
  32. }
  33. return eventFunc;
  34. }
  35. businessLogicProgram = function (){
  36. console.log("计数器")//用于测试
  37. if(document.documentElement.scrollTop >0){
  38. JumpBtn.style.display="block";
  39. }else{
  40. JumpBtn.style.display="none";
  41. }
  42. }
  43. window.onscroll = throttle(businessLogicProgram);
  44. </script>
  45. </body>

也可以进一步优化简洁封装函数

  1. function throttle(businessLogicProgram){
  2. let mark = true;
  3. return function(){
  4. if(mark){
  5. setTimeout(()=>{
  6. // console.log("业务逻辑程序");
  7. businessLogicProgram();
  8. mark = true;
  9. },500)
  10. }
  11. mark = false;
  12. };
  13. }

0.0

本文讲了鼠标滚动事件的情况,实际上,还有很多其他情况。开发时自然会遇到需要优化性能的时候,可以根据情况选择防抖或者节流。