如何实现父容器内可拖拽调整、自适应适配的四子div(保持宽高比)
实现可拖拽保持宽高比且自动适配父容器的四子面板布局
需求回顾
要做一个包含4个子div的父容器,满足:
- 子div可拖拽角落调整大小,且保持自身宽高比
- 某个子div放大时,其他子div自动缩小,整体始终适配父容器
现有代码问题分析
你当前用了jQuery UI的resizable插件,但缺少两个关键设置:
- 没开启宽高比锁定,拖拽时子元素会变形
- 固定的Grid布局(
repeat(2, 1fr))无法动态调整其他子元素的空间分配
解决方案代码
下面是修改后的完整代码,已经实现需求:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Resize</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css"> <style> #container { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; grid-gap: 2px; border: 10px #333 solid; width: 1000px; height: 758px; position: relative; } .resizable { border: 2px solid navy; } /* 自定义拖拽手柄样式(可选) */ .ui-resizable-se { background: #333; width: 12px; height: 12px; } </style> <script src="https://code.jquery.com/jquery-3.6.0.js"></script> <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script> </head> <body> <div id="container"> <div class="resizable"></div> <div class="resizable"></div> <div class="resizable"></div> <div class="resizable"></div> </div> <script> $(function() { const container = $('#container'); const containerWidth = container.width(); const containerHeight = container.height(); const aspectRatio = containerWidth / containerHeight; // 和父容器同比例,可自定义 // 初始化所有可拖拽元素 $(".resizable").resizable({ containment: "#container", aspectRatio: aspectRatio, // 锁定宽高比 handles: 'se', // 指定右下角拖拽手柄,可修改为ne/sw等其他角落 start: function() { // 记录初始尺寸,用于后续计算 $(this).data('initialSize', { width: $(this).width(), height: $(this).height() }); }, resize: function(event, ui) { const currentEl = $(this); const initialSize = currentEl.data('initialSize'); const sizeDiff = { width: ui.size.width - initialSize.width, height: ui.size.height - initialSize.height }; // 计算每个其他元素需要缩小的尺寸(平分差值) const otherEls = $(".resizable").not(currentEl); const shrinkPerEl = { width: sizeDiff.width / otherEls.length, height: sizeDiff.height / otherEls.length }; // 调整其他元素大小,同时保持宽高比 otherEls.each(function() { const newWidth = $(this).width() - shrinkPerEl.width; const newHeight = newWidth / aspectRatio; $(this).width(newWidth).height(newHeight); }); // 更新当前元素的初始尺寸,用于下一次拖拽计算 currentEl.data('initialSize', { width: ui.size.width, height: ui.size.height }); } }); }); </script> </body> </html>
关键修改说明
- 宽高比锁定:给
resizable添加aspectRatio参数,值设为父容器的宽高比(或你需要的固定比例),确保拖拽时子元素不会变形 - 动态空间分配:监听
resize事件,计算当前元素的尺寸变化量,让其他子元素平分这个变化量,自动缩小以适配父容器 - 拖拽手柄控制:通过
handles指定拖拽的角落(示例用右下角se,可根据需求修改)
注意事项
- 如果需要自定义子元素的宽高比,只需修改
aspectRatio的值即可 - 父容器的宽高如果改为自适应(比如
width: 100vw),记得在初始化时动态获取容器尺寸 - 拖拽过程中如果出现元素跳动,可尝试优化尺寸计算的精度(比如取整)
内容的提问来源于stack exchange,提问作者Thea
相关产品推荐
相关产品推荐

