如何动态缩放HTML可拖拽网格元素且不影响其父容器布局?
问题原因
父容器高度变化核心是两个布局问题:
#grid_container_static未设置固定高度,默认高度自适应内容,内部网格缩放时会自动撑开容器高度,进而影响外层的#central_container- 可拖拽的
#grid_container_movable处于常规文档流中,自身尺寸变化会直接影响父容器的布局计算
修复方案
第一步:修改CSS规则
替换原有CSS为以下内容,核心是固定可视容器高度、将可移动网格脱离文档流:
html, body{ margin: 0px; display: flex; flex-direction: column; /* 补充html高度声明,让百分比高度生效 */ height: 100vh; } * { box-sizing:border-box; } #header{ background-color: green; /* 头部固定高度即可,不需要flex-grow占比 */ height: 80px; } #main { /* 主体占满剩余视口空间 */ flex: 1; display: flex; flex-direction: column; } #central_container{ background-color: red; min-height: 60%; max-height: 60%; } #grid_container_static{ overflow: hidden; /* 固定高度撑满父容器 */ height: 100%; position: relative; } #grid_container_movable { /* 脱离文档流,尺寸变化不影响父容器 */ position: absolute; top: 0; left: 0; }
第二步:可选的JS优化
现有缩放逻辑可以补充两个体验优化:
- 只在鼠标 hover 到网格区域时触发缩放,避免拦截页面全局滚轮事件
- 缩放时阻止默认滚轮行为,避免页面滚动
修改后的JS代码参考:
const gridArea = document.getElementById('grid_container_static') let current_tile_size = 10 // 记得初始化默认瓦片尺寸 gridArea.addEventListener("wheel", event => { // 阻止默认滚轮行为 event.preventDefault() const delta = Math.sign(event.deltaY); if(delta < 0){ current_tile_size ++; }else{ if(current_tile_size > 1){ current_tile_size --; } } const tiles = document.getElementsByClassName('tile'); for(let i = 0; i < tiles.length; i++){ tiles[i].style.width = current_tile_size + "px"; // 建议换成px,避免继承字体大小影响尺寸 tiles[i].style.height = current_tile_size + "px"; } });
修改后可移动网格的缩放、拖拽都不会再影响外层父容器尺寸,超出可视区域的部分会被#grid_container_static自动隐藏。
内容的提问来源于stack exchange,提问作者firion
相关产品推荐
相关产品推荐

