首页 > 其他分享 >js实现交通灯(两种方案)

js实现交通灯(两种方案)

时间:2024-03-17 18:55:06浏览次数:32  
标签:disTime 方案 交通灯 js green yellow ._ red

简介

刚在抖音上刷到一个面试题,说实现交通灯的方案,我一开始想到的是通过定时器去实现,没想到他提到了一个问询的方式去实现,借此记录下来,本文介绍了两种方案去实现交通灯以及对应的倒计时。废话不多说,上代码

html+css

html代码如下:

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<meta name="viewport" content="width=device-width, initial-scale=1.0">  
<title>Traffic Light</title>  
</head>  
<body>  
  
<div class="traffic-light-container">   
  <div id="green" class="traffic-light"></div>  
  <div id="yellow" class="traffic-light"></div>  
  <div id="red" class="traffic-light"></div>  
</div>  
  
<div class="countdown">60</div>  
<script src="./index.js"></script>
<!-- <script src="./index1.js"></script> -->
</body>  
</html>

css如下:

.traffic-light {  
  width: 150px;  
  height: 150px;  
  margin: 10px;  
  border: 1px solid black;  
  display: inline-block;  
  border-radius: 50%;
}  
.red { background-color: red; }  
.yellow { background-color: yellow; }  
.green { background-color: green; }  
.countdown {  
  font-size: 24px;  
  margin-top: 20px;  
}  

定时器

index.js代码如下:

const redLight = document.getElementById('red');  
const yellowLight = document.getElementById('yellow');  
const greenLight = document.getElementById('green');  
const countdownElement = document.querySelector('.countdown');  
  
let currentTime = 5; // 初始倒计时时间  
let currentLight = 'green'; // 初始交通灯颜色  
greenLight.classList.add('green');  
// 定义交通灯颜色变化的时间  
const lightDurations = {  
  green: 5000, // 绿灯时间(毫秒)  
  yellow: 2000, // 黄灯时间(毫秒)  
  red: 7000 // 红灯时间(毫秒)  
};  
  
// 更新倒计时的函数  
function updateCountdown() {  
  if (currentTime > 0) {  
    countdownElement.textContent = currentTime;  
    currentTime--;  
    setTimeout(updateCountdown, 1000);  
  } else {  
    changeLight();  
  }  
}  
  
// 切换交通灯颜色的函数  
function changeLight() {  
  switch (currentLight) {  
    case 'green':  
      greenLight.classList.remove('green');  
      yellowLight.classList.add('yellow');  
      currentLight = 'yellow';  
      currentTime = lightDurations.yellow / 1000; // 转换为秒  
      break;  
    case 'yellow':  
      yellowLight.classList.remove('yellow');  
      redLight.classList.add('red');  
      currentLight = 'red';  
      currentTime = lightDurations.red / 1000; // 转换为秒  
      break;  
    case 'red':  
      redLight.classList.remove('red');  
      greenLight.classList.add('green');  
      currentLight = 'green';  
      currentTime = lightDurations.green / 1000; // 转换为秒  
      break;  
  }  
  updateCountdown(); // 重置倒计时  
}  
  
// 初始化倒计时  
updateCountdown();  

问询

index1.js代码如下:

class TrafficLight {
  constructor(lights) {
    this._lights = lights;
    this._currentIndex = 0; // 记录当前灯下的索引
    this._time = Date.now(); // 记录当前时间
  }
  _update() {
    let disTime = this._disTime();
    // 计算交通灯的展示时间总和
    let total = this._lights.reduce((acc, cur) => {
      return acc + cur.lasts
    }, 0);

    // 代表一个完整的循环周期的开始时间
    this._time += total * Math.floor(disTime / total) * 1000
    disTime = disTime % total; // 从上一个循环周期的开始到现在,还有多少时间没有用完

    while (1) {
      // 在每次循环中,disTime 被减去当前交通灯颜色的持续时间(this.currentLight.lasts)。
      // 如果 disTime 仍然大于或等于 0,那么说明当前交通灯颜色还没有结束,
      // 方法将 _time 向前推进当前交通灯颜色的持续时间,并更新 _currentIndex 为下一个交通灯颜色的索引
      // 一旦 disTime 小于 0,说明当前交通灯颜色已经结束,循环终止。此时,_currentIndex 已经指向了下一个应该显示的交通灯颜色。
      disTime -= this.currentLight.lasts;
      if (disTime < 0) break
      else {
        this._time += this.currentLight.lasts * 1000
        this._currentIndex = (this._currentIndex + 1) % this._lights.length;
        // 将当前交通灯颜色的索引向前移动一个位置。如果当前已经是最后一个交通灯颜色,索引将回绕到数组的第一个元素。
        // 这样,交通灯颜色就能按照数组中的顺序循环切换
      }
    }
  }
  // 访问器
  get currentLight() {
    return this._lights[this._currentIndex]
  }
  // 计算从上次更新到现在经过了多少秒
  _disTime() {
    return (Date.now() - this._time) / 1000
  }
  // 获取当前灯的状态
  getCurrentLight() {
    this._update()
    return {
      color: this.currentLight.color,
      remain: this.currentLight.lasts - this._disTime()
    }
  }
}

const light = new TrafficLight([{
    color: 'red',
    lasts: 3
  },
  {
    color: 'yellow',
    lasts: 2
  }, {
    color: 'green',
    lasts: 5
  }
])
const countdown = document.querySelector('.countdown')
const trafficLightDom = document.querySelectorAll('.traffic-light')

function update() {
  const current = light.getCurrentLight();
  countdown.textContent = Math.ceil(current.remain)
  trafficLightDom.forEach(item=>{
    item.classList.remove('red', 'green', 'yellow')
    if(item.id === current.color){
      item.classList.add(current.color)
    }
  })
}
update()
// 动画,类似于定时器
function raf() {
  requestAnimationFrame(() => {
    raf()
    update()
  })
}

raf()

总结

没有太多的详细说明,我想看代码以及注释能看懂,若各位有看不懂或者觉得有问题的可以私聊我或者评论,大家一起共同进步

标签:disTime,方案,交通灯,js,green,yellow,._,red
From: https://www.cnblogs.com/sqh17/p/18078959

相关文章

  • 视野修炼-技术周刊第77期 | JSR 的愿景
    欢迎来到第77期的【视野修炼-技术周刊】,下面是本期的精选内容简介......
  • 硕芯科技SX1308DCDC升压方案
    数据手册特征大致如下升压型DCDC2~24V电压输入4A开关电流限制SOT23-6超小封装最高28V输出电压典型应用电路图如下:输出电压与反馈电阻关系如下 VREF为0.6V,如下电路为输出5V时的电路配置其中EN为该芯片的转换使能引脚,注意此处是转换而不是输出,所以当该引脚为低电平时,......
  • [nodejs] NodeJs/NPM入门教程
    0序nodejs是运行在服务器端的js,常用于前端工程师在本地电脑、或生产环境部署调试或运行前端工程。回想起来,上次使用nodejs,还在5年前做大学毕业设计时,基于前后端分离的实践(那时,业界正在兴起前后端分离的浪潮。当然了,现在的web工程,前后端分离已是默认的技术选择了)这次重......
  • 无感扩声解决方案特色解析
    需求分析 在教育,金融,安防领域。这些对声音要求比较高的领域,传统的扩声系统有着佩戴复杂,容易啸叫,声音不清晰等缺点。随着技术的不断进步,高清晰,带降噪,防啸叫,低延时的音频扩音系统逐渐成为行业的风向标。基于此,无感扩声这个概念被提到了一个新的层面并逐渐成为现实。 作为长期深......
  • 说JS作用域,就不得不说说自执行函数
    一个兜兜转转,从“北深”回到三线城市的小码农,热爱生活,热爱技术,在这里和大家分享一个技术人员的点点滴滴。欢迎大家关注我的微信公众号:果冻想前言不得不吐槽,学个JS,这个概念也太多了,但是这些概念你不懂吧,代码你都看不懂,你都寸步难行。好吧,这又遇到了作用域方面的知识盲区,然后发......
  • Clion输出中文乱码终极解决方案
    网上大部分方法是在编辑文件时将编码改成GBK,个人认为不太正确。现有一个终极解决的方案,不需要改成GBK。 保存关闭后,按住Ctrl+Shift+Alt+/(不够快捷的快捷键…)选中Registry… 然后取消run.processes.with.pty然后就可以了~ ......
  • js面试(防抖)
    一、什么是防抖防抖(Debounce)是一种用于减少特定事件触发频率的技术。在编程中,它通常用于确保函数或方法不会在很短的时间内被频繁调用,这有助于优化性能并避免不必要的计算或操作。防抖的实现原理是,在事件被触发后,一个定时器会被设置。如果在定时器完成之前,相同的事件再次被触发,......
  • 全栈的自我修养 ———— js如何处理并发的大量请求??
    假如一个事件段内传过来一百多个请求,我们该处理大量并发请求呢过程实现验证假如现在允许的并发量为4,有一百个请求!假如现在允许的并发量为1,有一百个请求!源码过程实现定义一个方法,这个方法会放入你在这个时间段接收到的请求,这里100位例!consturlArr=[]......
  • 淘宝代购系统:集成化解决方案的发展蓝图
    引言简述淘宝代购市场的现状和发展趋势,以及集成化解决方案在代购系统中的重要性。第一部分:淘宝代购系统概述 定义淘宝代购系统及其服务模式,分析代购系统的市场需求和用户群体,探讨代购系统所面临的主要挑战。第二部分:集成化解决方案的核心组件详细描述集成化解决方案的概......
  • 微信小程序uniapp+vue+nodejs宝宝成长记录系统的设计与实现
    本文先通过对相关系统的调研,提出开发基于微信小程序的宝宝成长记录系统的意义,然后使用当前主流的技术进行开发,满足基于微信小程序的宝宝成长记录系统的技术要求,分析系统需要实现的功能并进行设计。梳理业务流程,并根据功能设计数据库,最后通过编码实现,介绍实现的关键算法逻辑。在......