gpt4 book ai didi

html - 弹性盒调整大小

转载 作者:行者123 更新时间:2023-12-03 19:58:16 24 4
gpt4 key购买 nike

我正在尝试提出一种定义嵌套 flexbox 并允许调整其大小的有效方法。我认为它几乎就在那里:

http://jsfiddle.net/6j10L3x2/1/

我使用三个自定义元素纯粹是为了使标记更具声明性:

flex, flex-item, flex-resizer

一个 flex 代表容器。 flex-item 表示容器内的一个元素,flex-resizer 表示一个 resizer 小部件,它可以放置在两个 flex-item 之间以在它们之间添加调整大小的功能。

这一切似乎都非常有效。但是,它只处理使用 flex-grow 调整大小的项目。如果定义了 flex-shrink 或 flex-basis,则计算根本不起作用。

任何人都可以提出一种修改方法以使其适用于所有情况吗?我意识到在如何在具有各种 flex 配置的项目之间共享空间方面存在一些歧义,但欢迎任何输入。

任何替代方法也将受到欢迎。谢谢。

最佳答案

哇。我对您如何使用“flexGrow”、出色的想法和代码使用 vanilla javascript 调整 flexbox 元素的大小印象深刻。
我已经通过几种方式改进了您的代码,并且运行良好。
我做了什么?
1.- 我简化了 HTML:

  • 不要使用 柔性 内的元素弹性项目 .
  • 使用 柔性 弹性项目 元素,永远!,在另一个里面
    柔性 元素。

  • 2.- 解决了!
    当可见的 flex-item 大小小于其内容大小时,拆分器的跳转。
    3.- 我添加了不同的游标来表示状态的变化(setupResizerEvents、onMouseUp)以提高可用性。
    4.- 我添加了代码来防止拖动时光标闪烁。
    5.- 在 manageResize() 与 scrollWidth 和 scrollHeight 中使用 offsetWidth 和 offsetHeight 来避免在弹性项目内容溢出(溢出:自动)时拆分器在调整大小时跳转。
    这是代码:

    function manageResize(md, sizeProp, posProp) {
    var r = md.target;

    var prev = r.previousElementSibling;
    var next = r.nextElementSibling;
    if (!prev || !next) {
    return;
    }

    md.preventDefault();

    var prevSize = prev[sizeProp];
    var nextSize = next[sizeProp];
    var sumSize = prevSize + nextSize;
    var prevGrow = Number(prev.style.flexGrow);
    var nextGrow = Number(next.style.flexGrow);
    var sumGrow = prevGrow + nextGrow;
    var lastPos = md[posProp];

    function onMouseMove(mm) {
    var pos = mm[posProp];
    var d = pos - lastPos;
    prevSize += d;
    nextSize -= d;
    if (prevSize < 0) {
    nextSize += prevSize;
    pos -= prevSize;
    prevSize = 0;
    }
    if (nextSize < 0) {
    prevSize += nextSize;
    pos += nextSize;
    nextSize = 0;
    }

    var prevGrowNew = sumGrow * (prevSize / sumSize);
    var nextGrowNew = sumGrow * (nextSize / sumSize);

    prev.style.flexGrow = prevGrowNew;
    next.style.flexGrow = nextGrowNew;

    lastPos = pos;
    }

    function onMouseUp(mu) {
    // Change cursor to signal a state's change: stop resizing.
    const html = document.querySelector('html');
    html.style.cursor = 'default';

    if (posProp === 'pageX') {
    r.style.cursor = 'ew-resize';
    } else {
    r.style.cursor = 'ns-resize';
    }

    window.removeEventListener("mousemove", onMouseMove);
    window.removeEventListener("mouseup", onMouseUp);
    }

    window.addEventListener("mousemove", onMouseMove);
    window.addEventListener("mouseup", onMouseUp);
    }

    function setupResizerEvents() {
    document.body.addEventListener("mousedown", function (md) {

    // Used to avoid cursor's flickering
    const html = document.querySelector('html');

    var target = md.target;
    if (target.nodeType !== 1 || target.tagName !== "FLEX-RESIZER") {
    return;
    }
    var parent = target.parentNode;
    var h = parent.classList.contains("h");
    var v = parent.classList.contains("v");
    if (h && v) {
    return;
    } else if (h) {
    // Change cursor to signal a state's change: begin resizing on H.
    target.style.cursor = 'col-resize';
    html.style.cursor = 'col-resize'; // avoid cursor's flickering

    // use offsetWidth versus scrollWidth (and clientWidth) to avoid splitter's jump on resize when a flex-item content overflow (overflow: auto).
    manageResize(md, "offsetWidth", "pageX");

    } else if (v) {
    // Change cursor to signal a state's change: begin resizing on V.
    target.style.cursor = 'row-resize';
    html.style.cursor = 'row-resize'; // avoid cursor's flickering

    manageResize(md, "offsetHeight", "pageY");
    }
    });
    }

    setupResizerEvents();
    body {
    /* margin:0; */
    border: 10px solid #aaa;
    }

    flex {
    display: flex;
    overflow: hidden;
    }

    /* flex-item > flex {
    position: absolute;
    width: 100%;
    height: 100%;
    } */

    flex.h {
    flex-direction: row;
    }

    flex.v {
    flex-direction: column;
    }

    flex-item {
    /* display: flex; */
    /* position: relative; */
    /* overflow: hidden; */
    overflow: auto;
    }

    flex > flex-resizer {
    flex: 0 0 10px;
    /* background: white; */
    background-color: #aaa;
    background-repeat: no-repeat;
    background-position: center;
    }

    flex.h > flex-resizer {
    cursor: ew-resize;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='30'><path d='M2 0 v30 M5 0 v30 M8 0 v30' fill='none' stroke='black'/></svg>");
    }

    flex.v > flex-resizer {
    cursor: ns-resize;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='10'><path d='M0 2 h30 M0 5 h30 M0 8 h30' fill='none' stroke='black'/></svg>");
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>flex-splitter</title>
    <link rel="stylesheet" href="./src/styles.css">
    <script src="./src/index.js" defer></script>
    </head>

    <body>
    <flex class="v" style="flex: 1; height: 500px;">
    <flex-item style="flex: 1;">Flex 1</flex-item>
    <flex-resizer></flex-resizer>
    <flex class="h" style="flex: 1;">
    <flex-item style="flex: 1; background-color: aqua;">

    <!--
    The next section is an example to test the splitter when there is content inside a flex-item
    -->
    <section>
    <div>
    <label for="CursorCoor" style="display: block;">showCursorCoor: </label>
    <textarea id="CursorCoor" rows="6" cols="50" wrap="soft" readonly></textarea>
    </div>

    <br />

    <div>
    <label for="boxInfo" style="display: block;">showBoxInfo: </label>
    <textarea id="boxInfo" rows="6" cols="50" wrap="soft" readonly></textarea>
    </div>
    </section>

    </flex-item>
    <flex-resizer></flex-resizer>
    <flex class="v" style="flex: 2; ">
    <flex-item style="flex: 1; background: pink;">Flex 3</flex-item>
    <flex-resizer></flex-resizer>
    <flex class="h" style="flex: 1">
    <flex-item style="flex: 1; background: green;">Flex 4</flex-item>
    <flex-resizer></flex-resizer>
    <flex-item style="flex: 2;">Flex 5</flex-item>
    <!-- <flex-resizer></flex-resizer> -->
    <flex-item style="flex: 3; background: darkorange;">Flex 6</flex-item>
    </flex>
    </flex>
    </flex>
    </flex>

    </body>
    </html>

    或者在 Codesandbox 上查看:
    Edit sad-butterfly-1fwo4
    我希望它有帮助!

    关于html - 弹性盒调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28767221/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com