【问题标题】:Issues with div size and position updates on mouse move event鼠标移动事件中 div 大小和位置更新的问题
【发布时间】:2020-08-29 01:20:31
【问题描述】:

我正在使用 html、css 和 javascript 实现一个简单的水平拆分窗格,改编自 post

虽然对于垂直拆分窗格来说一切都很顺利,但水平实现是生涩的。 div 的大小和位置跳到了一个意外的值,但我无法确定何时。

问题在 sn-p 以下非常微妙,但可以观察到一些跳跃和滞后。

以下片段:

function dragElement(element, direction) {

    var md;
    const first = document.getElementById("map");
    const second = document.getElementById("table");

    element.onmousedown = onMouseDown;

    function onMouseDown(e) {
        md = {
            e,
            offsetLeft: element.offsetLeft,
            offsetTop: element.offsetTop,
            offsetBottom: element.offsetBottom,
            firstWidth: first.offsetWidth,
            secondWidth: second.offsetWidth,
            firstHeight: first.offsetHeight,
            secondHeight: first.offsetHeight
        };

        document.onmousemove = onMouseMove;

        document.onmouseup = () => {
            document.onmousemove = document.onmouseup = null;
        }
    }

    function onMouseMove(e) {

        var delta = {
            x: e.clientX - md.e.x,
            y: e.clientY - md.e.y
        };

        if (direction === "H") {
            delta.x = Math.min(Math.max(delta.x, - md.firstWidth),
                md.secondWidth);
            element.style.left = md.offsetLeft + delta.x + "px";
            first.style.width = (md.firstWidth + delta.x) + "px";
            second.style.width = (md.secondWidth - delta.x) + "px";
        }

        if (direction === "V") {
            delta.y = Math.min(Math.max(delta.y, - md.firstHeight), md.secondHeight);
            element.style.top = md.offsetTop + delta.y + "px";
            first.style.height = (md.firstHeight + delta.y) + "px";
            second.style.height = (md.secondHeight - delta.y) + "px";
        }
    }
}
dragElement(document.getElementById("separator"), "V");
html,
body {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

.splitter {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}


/*for horizontal*/

#separator {
  cursor: row-resize;
  background-color: #aaa;
  background-repeat: no-repeat;
  background-position: center;
  width: 100%;
  height: 10px;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

#map {
  width: 100%;
  height: 20%;
  min-height: 10px;
  padding: 0;
  margin: 0;
}

#table {
  width: 100%;
  height: 20%;
  min-height: 10px;
}
<div class="splitter">
  <div id="map"></div>
  <div id="separator"></div>
  <div id="table"></div>
</div>

【问题讨论】:

  • 您选择的解决方案有缺陷。它不会超过第一个元素高度的两倍。为了轻松测试它,请将分隔符尽可能靠近顶部。然后尝试将其尽可能靠近底部。
  • 它没有采用最流行的解决方案,最初是一个 SO 答案,最终由 20 多名经验丰富的开发人员在 5 年内改进,它在所有可能的浏览器中进行了测试,具有 0 个依赖项,具有持续集成和自动化测试,您选择了不那么流行的,因此使用少得多,因此测试少得多,没有 CI 或 AT。最后,它们之间的区别在于,第一个比第二个投入了更多的开发时间。两者都是免费的。现在你要求其他人修复它的“微妙”缺陷。 尝试过什么?
  • @tao 我明白你的意思。我的选择主要基于我在最流行的“答案”和原始答案的日期方面遇到的一些初始问题。我可以看到较旧的答案中较新的 cmets 应该如何在我的选择中占据更大的权重。
  • 那我们来解决问题X。 :) 您要解决的问题是什么?请提供用例和所有限制条件。

标签: javascript html css


【解决方案1】:

原因是当我们上下移动时 secondHeight 为 0。 所以我得到拆分器类的高度并减去 firstHeight 形式,其值等于 secondHeight。

secondHeight: (splitter.offsetHeight - first.offsetHeight)

function dragElement(element, direction) {

    var md;
    const first = document.getElementById("map");
    const second = document.getElementById("table");
    const splitter = document.getElementById("container");

    element.onmousedown = onMouseDown;

    function onMouseDown(e) {
        md = {
            e,
            offsetLeft: element.offsetLeft,
            offsetTop: element.offsetTop,
            offsetBottom: element.offsetBottom,
            firstWidth: first.offsetWidth,
            secondWidth: second.offsetWidth,
            firstHeight: first.offsetHeight,
            secondHeight: (splitter.offsetHeight - first.offsetHeight)
        };
        document.onmousemove = onMouseMove;

        document.onmouseup = () => {
            document.onmousemove = document.onmouseup = null;
        }
    }

    function onMouseMove(e) {

        var delta = {
            x: e.clientX - md.e.x,
            y: e.clientY - md.e.y
        };

        if (direction === "H") {
            delta.x = Math.min(Math.max(delta.x, -md.firstWidth),
                md.secondWidth);
            element.style.left = md.offsetLeft + delta.x + "px";
            first.style.width = (md.firstWidth + delta.x) + "px";
            second.style.width = (md.secondWidth - delta.x) + "px";
        }

        if (direction === "V") {
            delta.y = Math.min(Math.max(delta.y, -md.firstHeight), md.secondHeight);
            element.style.top = md.offsetTop + delta.y + "px";
            first.style.height = (md.firstHeight + delta.y) + "px";
            second.style.height = (md.secondHeight - delta.y) + "px";
        }
    }
}

dragElement(document.getElementById("separator"), "V");
html,
body {
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
}

.splitter {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}


/*for horizontal*/

#separator {
    cursor: row-resize;
    background-color: #aaa;
    background-repeat: no-repeat;
    background-position: center;
    width: 100%;
    height: 10px;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

#map {
    width: 100%;
    height: 20%;
    min-height: 10px;
    padding: 0;
    margin: 0;
}

#table {
    width: 100%;
    height: 20%;
    min-height: 10px;
}
<div id="container" class="splitter">
    <div id="map"></div>
    <div id="separator"></div>
    <div id="table"></div>
</div>

【讨论】:

    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多