Javascript教室元素无法随窗口尺寸自适应调整问题求助
解决教室布局响应式问题及resize事件未触发问题
一、修复resize事件未触发问题
将resize事件监听移至DOMContentLoaded回调内,确保DOM完全加载后再注册事件,避免脚本加载顺序导致的注册失败,同时添加防抖优化避免频繁触发:
document.addEventListener('DOMContentLoaded', function() { var buttons = document.querySelectorAll('.floor-btn'); buttons.forEach(function(button) { button.addEventListener('click', function(event) { var floorNumber = parseInt(this.getAttribute('data-floor')); changeFloor(floorNumber); }); }); changeFloor(1); // 带防抖的resize事件监听 let resizeTimeout; window.addEventListener("resize", function() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { console.log("Resize Event"); const activeFloor = document.querySelector('.floor-btn.active').getAttribute('data-floor'); changeFloor(parseInt(activeFloor)); }, 200); }); });
同时检查浏览器控制台是否存在变量未定义等报错,这类问题会导致脚本中断,进而无法完成事件注册。
二、实现教室位置随窗口动态调整
当前教室使用固定像素定位,窗口变化时无法自适应,需改为基于容器的相对定位方案:
1. 调整容器CSS
给#map添加相对定位,让绝对定位的教室元素以它为基准:
#map { position: relative; width: 100%; height: calc(100% - 80px); /* 预留楼层按钮空间,可根据布局调整 */ overflow: hidden; }
2. 修改绘制逻辑,使用相对比例计算位置
假设JSON中的location坐标基于基准宽高(比如1920x1080),动态计算当前容器下的位置:
async function drawCabinets(floor) { if (classrooms_ === undefined) { console.log("Loading Classroms"); classrooms_ = await LoadCabinetsData(); } let classrooms = classrooms_[floor - 1]; const map = document.getElementById('map'); const tooltip = document.getElementById('tooltip'); const mapWidth = map.offsetWidth; const mapHeight = map.offsetHeight; // 替换为你的基准尺寸(JSON坐标对应的原始容器大小) const baseWidth = 1920; const baseHeight = 1080; map.innerHTML = ''; // 简化容器清空逻辑 if (classrooms !== undefined) { classrooms.forEach(function(classroom) { const room = document.createElement('div'); room.className = 'room'; // 计算相对位置百分比 const relativeX = (classroom.location[0] / baseWidth) * 100; const relativeY = (classroom.location[1] / baseHeight) * 100; room.style.left = `${relativeX}%`; room.style.top = `${relativeY}%`; room.style.backgroundColor = getColor(classroom.students, classroom.capacity); room.innerText = classroom.cabinet; if (classroom.type === 'Компьютерный') room.classList.add('computer-room'); if (classroom.type === 'Поточный') room.classList.add('stream-room'); room.addEventListener('mouseover', function() { tooltip.innerHTML = `Кабинет №${classroom.cabinet}<br>Тип: ${classroom.type}<br>Вместимость: ${classroom.capacity}<br>Сейчас в кабинете: ${classroom.students} студентов<br>Группы: ${classroom.groups.join(', ')}`; // 同步计算tooltip的动态位置 const tooltipX = (classroom.location[0] / baseWidth) * mapWidth + 40; const tooltipY = (classroom.location[1] / baseHeight) * mapHeight - 20; tooltip.style.left = `${tooltipX}px`; tooltip.style.top = `${tooltipY}px`; tooltip.style.display = 'block'; }); room.addEventListener('mouseout', function() { tooltip.style.display = 'none'; }); map.appendChild(room); }); } function getColor(students, capacity) { const percentage = (students / capacity) * 100; if (percentage < 25) return 'green'; if (percentage < 50) return 'lightgreen'; if (percentage < 75) return 'yellow'; if (percentage < 90) return 'orange'; return 'red'; } }
3. 简化changeFloor函数
function changeFloor(floorNumber) { const buttons = document.querySelectorAll('.floor-btn'); buttons.forEach(btn => btn.classList.remove('active')); const activeBtn = document.querySelector(`.floor-btn[data-floor="${floorNumber}"]`); activeBtn.classList.add('active'); const map = document.getElementById('map'); map.innerHTML = ''; drawCabinets(floorNumber); }
额外说明
- 如果JSON中的坐标本身就是百分比值,可直接省略基准尺寸计算,直接使用
classroom.location[0] + '%'作为位置值。 - 移动端测试时,确保viewport元标签正确设置(你的代码中已配置,无需修改)。
内容的提问来源于stack exchange,提问作者Pyr0Guy
相关产品推荐
相关产品推荐

