You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现父容器内可拖拽调整、自适应适配的四子div(保持宽高比)

实现可拖拽保持宽高比且自动适配父容器的四子面板布局

需求回顾

要做一个包含4个子div的父容器,满足:

  • 子div可拖拽角落调整大小,且保持自身宽高比
  • 某个子div放大时,其他子div自动缩小,整体始终适配父容器

现有代码问题分析

你当前用了jQuery UI的resizable插件,但缺少两个关键设置:

  1. 没开启宽高比锁定,拖拽时子元素会变形
  2. 固定的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>

关键修改说明

  1. 宽高比锁定:给resizable添加aspectRatio参数,值设为父容器的宽高比(或你需要的固定比例),确保拖拽时子元素不会变形
  2. 动态空间分配:监听resize事件,计算当前元素的尺寸变化量,让其他子元素平分这个变化量,自动缩小以适配父容器
  3. 拖拽手柄控制:通过handles指定拖拽的角落(示例用右下角se,可根据需求修改)

注意事项

  • 如果需要自定义子元素的宽高比,只需修改aspectRatio的值即可
  • 父容器的宽高如果改为自适应(比如width: 100vw),记得在初始化时动态获取容器尺寸
  • 拖拽过程中如果出现元素跳动,可尝试优化尺寸计算的精度(比如取整)

内容的提问来源于stack exchange,提问作者Thea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:03:36