2451.灯的颜色变化 深入掌握 DOM 选择器与定时器:从交通灯案例到蓝桥杯 Web 考点全解 在蓝桥杯 Web 方向竞赛中,DOM 操作 与定时器控制 是高频考点。本文以一个经典的交通灯控制案例为切入点,全面解析 document.querySelector 的 ID/Class 选择语法、style.display 显隐控制、setInterval 与 setTimeout 的核心区别,并提供记忆技巧、对比表格及拓展真题实战。 📌 案例原始代码回顾 // 显示红色灯 function red() { document.querySelector('#redlight').style.display = 'inline-block'; document.querySelector('#greenlight').style.display = 'none'; document.querySelector('#defaultlight').style.display = 'none'; } // 显示绿色灯 function green() { document.querySelector('#redlight').style.display = 'none'; document.querySelector('#greenlight').style.display = 'inline-block'; document.querySelector('#defaultlight').style.display = 'none'; } // 交通灯计时控制(3秒红,6秒绿后停止) function trafficlights() { var number = 0; var timer = setInterval(() => { number++; if (number == 3) { // 3秒后亮红灯 red(); } else if (number == 6) { // 6秒后亮绿灯并停止 green(); clearInterval(timer); } }, 1000); }一、DOM 选择器核心语法:querySelector 与 ID/Class 实战 1.1 document.querySelector 基础 querySelector 接受一个 CSS 选择器字符串 ,返回文档中匹配的第一个元素。若需所有匹配元素,使用 querySelectorAll。
// 通过 ID 选择(必须加 #) const redLight = document.querySelector('#redlight'); // 推荐 // 通过 Class 选择(必须加 .) const greenLight = document.querySelector('.greenlight'); // 通过标签名选择 const div = document.querySelector('div'); // 通过属性选择 const input = document.querySelector('[type="button"]');1.2 ID 与 Class 获取方式的语法差异对比
方法 语法示例 返回类型 匹配规则 性能 querySelector('#id')document.querySelector('#box')单个元素或 null CSS 选择器,支持任意复杂选择器 中等 getElementById('id')document.getElementById('box')单个元素或 null 仅通过 ID(不加 #) 最快 querySelector('.class')document.querySelector('.item')单个元素或 null 返回第一个匹配的 class 中等 getElementsByClassName('class')document.getElementsByClassName('item')HTMLCollection 动态集合通过 class 名,返回所有匹配元素 较快 getElementsByTagName('div')document.getElementsByTagName('div')HTMLCollection 通过标签名 较快
1.3 记忆技巧 🧠 # 像一把钩子钩住唯一的 ID;. 像一粒种子撒向多个 class。 口诀 :ID 用井号(#),Class 用点号(.)
选择目标 querySelector 写法 传统方法写法 记忆点 ID '#myId'getElementById('myId')ID 就像身份证号,唯一且带# Class '.myClass'getElementsByClassName('myClass')Class 就像班级,很多人用.
二、style.display 控制元素显隐 2.1 常用属性值详解 // 隐藏元素(不占位) element.style.display = 'none'; // 显示为块级元素(独占一行) element.style.display = 'block'; // 显示为行内块(不独占一行,可设宽高) element.style.display = 'inline-block'; // 恢复默认(通常为 block 或 inline) element.style.display = '';2.2 各属性值对比表
display 值 是否可见 是否占位 典型场景 none❌ 不可见 ❌ 不占位 彻底隐藏元素,如同不存在 block✅ 可见 ✅ 占位 块级元素,如 <div>、<p> inline✅ 可见 ✅ 占位 行内元素,无法设置宽高 inline-block✅ 可见 ✅ 占位 行内但可设宽高(交通灯常用)
注意 :交通灯案例中使用 inline-block 使三个灯水平排列且可控制尺寸,用 none 切换显示。三、定时器对决:setInterval vs setTimeout 3.1 基本语法与停止方法 // setTimeout:延迟执行一次 let timer1 = setTimeout(() => { console.log('只执行一次'); }, 1000); clearTimeout(timer1); // 取消执行 // setInterval:间隔重复执行 let timer2 = setInterval(() => { console.log('每秒一次'); }, 1000); clearInterval(timer2); // 停止循环3.2 核心区别对比表
对比维度 setIntervalsetTimeout执行次数 无限次,直到被清除 仅一次 间隔控制 固定间隔重复调用 延迟指定时间后调用一次 停止方法 clearInterval(timerId)clearTimeout(timerId)典型场景 轮播图、倒计时、实时刷新 延迟加载、动画暂停、防抖 累加偏移问题 可能存在(任务执行时间 > 间隔) 无(仅一次) 递归模拟替代 可被递归 setTimeout 替代,更精确 无法直接替代 setInterval
3.3 记忆技巧 🧠 Interval → 中间有间隔(重复) Timeout → 时间到(一次) 口诀 :Interval 反复横跳,Timeout 一次就好;Clear 记得要调用,否则内存会爆掉。3.4 递归 setTimeout 实现精确循环(蓝桥杯推荐写法) let count = 0; function loop() { console.log('执行第', ++count, '次'); setTimeout(loop, 1000); // 递归调用,确保上一次执行完再开始下一次 } setTimeout(loop, 1000);优势 :避免 setInterval 因代码执行耗时导致的间隔偏差,更可控。
四、交通灯案例深度分析与拓展(红 → 黄 → 绿 循环) 4.1 原代码的优缺点 ✅ 优点:逻辑清晰,使用 setInterval 简单实现了顺序切换。 ❌ 缺点:只执行一轮(红3秒,绿3秒)后停止,不满足实际交通灯循环需求。 没有黄灯过渡,与现实不符。 未处理初始状态(默认灯显示)。 4.2 蓝桥杯风格完整实现(红→黄→绿循环,递归setTimeout) <!DOCTYPE html> <html> <head> <style> .traffic-light { display: inline-block; width: 80px; height: 80px; border-radius: 50%; margin: 10px; background-color: gray; } #redlight { background-color: red; } #yellowlight { background-color: yellow; } #greenlight { background-color: green; } .light-container { text-align: center; margin-top: 50px; } </style> </head> <body> <div> <div></div> <div></div> <div></div> </div> <button>启动交通灯</button> <script> // 获取灯元素 const redLight = document.querySelector('#redlight'); const yellowLight = document.querySelector('#yellowlight'); const greenLight = document.querySelector('#greenlight'); // 通用显隐函数 function showLight(lightToShow) { // 先将所有灯隐藏(none 不占位) redLight.style.display = 'none'; yellowLight.style.display = 'none'; greenLight.style.display = 'none'; // 显示目标灯(inline-block 保持占位和大小) lightToShow.style.display = 'inline-block'; } // 状态枚举 const STATES = { RED: 'red', YELLOW: 'yellow', GREEN: 'green' }; let currentState = STATES.RED; let timerId = null; // 核心循环函数(递归setTimeout) function runTrafficLight() { switch (currentState) { case STATES.RED: showLight(redLight); currentState = STATES.YELLOW; timerId = setTimeout(runTrafficLight, 3000); // 红灯亮3秒 break; case STATES.YELLOW: showLight(yellowLight); currentState = STATES.GREEN; timerId = setTimeout(runTrafficLight, 2000); // 黄灯亮2秒 break; case STATES.GREEN: showLight(greenLight); currentState = STATES.RED; timerId = setTimeout(runTrafficLight, 4000); // 绿灯亮4秒 break; default: break; } } // 启动交通灯(先清除旧定时器) function startTrafficLight() { if (timerId) { clearTimeout(timerId); timerId = null; } currentState = STATES.RED; // 重置为红灯 runTrafficLight(); // 开始循环 } // 绑定按钮事件 document.querySelector('#startBtn').addEventListener('click', startTrafficLight); // 页面初始化默认显示红灯(可选) startTrafficLight(); </script> </body> </html>代码注释重点 :
使用 setTimeout 递归替代 setInterval,避免循环内任务阻塞造成的延迟累积。 通过 switch 状态机管理灯色顺序,易于扩展。 每次切换前先 clearTimeout 保证唯一定时器,防止内存泄漏。 五、蓝桥杯 Web 考点映射与真题技巧 5.1 常见考点
考点类别 典型题目要求 本题对应技能 DOM 元素获取 使用 querySelector 或 getElementById 获取元素 获取交通灯元素并修改样式 定时器控制 实现自动轮播、倒计时或动画 控制灯色切换时间 事件绑定 点击按钮启动/停止定时器 添加开始按钮事件 样式动态修改 改变元素 display、backgroundColor 等属性 切换灯可见性及颜色 防止内存泄漏 页面关闭或组件销毁时清除定时器 使用 clearTimeout/clearInterval 性能优化 用递归 setTimeout 代替 setInterval 避免间隔累积偏移
5.2 真题变形示例 题目 :设计一个红绿灯,红灯亮 5 秒 → 黄灯亮 2 秒 → 绿灯亮 5 秒,并无限循环。要求提供开始和暂停按钮,暂停时清除定时器,恢复后继续当前状态。解决方案思路 :
记录当前状态和剩余时间。 使用 setTimeout 递归 + 一个全局标志控制暂停恢复。 暂停时 clearTimeout 并保存剩余时间,恢复时重新设置定时器。 六、知识点速查汇总表 6.1 DOM 选择器总结
需求 推荐方法 示例 获取单个 ID 元素 querySelector('#id') 或 getElementByIddocument.querySelector('#box')获取单个 Class 元素 querySelector('.class')document.querySelector('.item')获取所有 Class 元素 querySelectorAll('.class')document.querySelectorAll('.item')获取动态集合(实时) getElementsByClassName / getElementsByTagNamedocument.getElementsByClassName('item')
6.2 定时器选择指南
场景 选择方案 理由 延迟执行一次 setTimeout简单可靠 固定间隔重复(无阻塞风险) setInterval代码简洁 固定间隔重复(任务耗时可能>间隔) 递归 setTimeout 避免任务重叠和偏移 需要暂停恢复的循环动画 递归 setTimeout + 状态保存 精确控制时间点
6.3 display 属性速查
值 特性 典型应用 none隐藏,不占位,相当于元素消失 模态框关闭、选项卡切换 block块级,独占一行,可设宽高 布局容器 <div> inline行内,不可设宽高,多个并排 文本修饰 <span> inline-block行内块,不独占,可设宽高 导航栏、交通灯图标
七、总结 通过交通灯这个看似简单的案例,我们串联了 DOM 选择器 (尤其是 ID 与 Class 的 querySelector 语法)、样式显隐控制 以及 JavaScript 定时器 三大核心考点。掌握这些知识,不仅能够应对蓝桥杯 Web 方向的常见操作题,更能为复杂动画、轮播图、倒计时等实战功能打下坚实基础。
最后送你一句记忆口诀 :
ID 前带 #,Class 点开花;显隐 display,none 与块家;定时器分两家,Interval 重复 Timeout 一下;递归替代防偏差,蓝桥杯上笑哈哈。 🚦 现在,去点亮你自己的交通灯吧!希望你的人生一路绿灯加油💪