如何使用 JavaScript 垂直分割可调整大小的面板

问题描述 投票:0回答:2

如何使用当前代码 HTML、CSS 和 JavaScript 垂直分割可调整大小的面板。现在这段代码适用于水平可调整大小的分割。我必须在当前代码中进行哪些更改。

如何使用当前代码 HTML、CSS 和 JavaScript 垂直分割可调整大小的面板。现在这段代码适用于水平可调整大小的分割。我必须在当前代码中进行哪些更改。

// A function is used for dragging and moving
function dragElement(element, direction) {
  var md; // remember mouse down info
  const first = document.getElementById("first");
  const second = document.getElementById("second");

  element.onmousedown = onMouseDown;

  function onMouseDown(e) {
    //console.log("mouse down: " + e.clientX);
    md = {
      e,
      offsetLeft: element.offsetLeft,
      offsetTop: element.offsetTop,
      firstWidth: first.offsetWidth,
      secondWidth: second.offsetWidth
    };

    document.onmousemove = onMouseMove;
    document.onmouseup = () => {
      //console.log("mouse up");
      document.onmousemove = document.onmouseup = null;
    }
  }

  function onMouseMove(e) {
    //console.log("mouse move: " + e.clientX);
    var delta = {
      x: e.clientX - md.e.clientX,
      y: e.clientY - md.e.clientY
    };

    if (direction === "H") // Horizontal
    {
      // Prevent negative-sized elements
      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";
    }
  }
}


dragElement(document.getElementById("separator"), "H");
.splitter {
  width: 100%;
  height: 100px;
  display: flex;
}

#separator {
  cursor: col-resize;
  background-color: #aaa;
  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>");
  background-repeat: no-repeat;
  background-position: center;
  width: 10px;
  height: 100%;
  /* Prevent the browser's built-in drag from interfering */
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

#first {
  background-color: #dde;
  width: 20%;
  height: 100%;
  min-width: 10px;
}

#second {
  background-color: #eee;
  width: 80%;
  height: 100%;
  min-width: 10px;
}
<body>
  <div class="splitter">
    <div id="first"></div>
    <div id="separator"></div>
    <div id="second"></div>
  </div>
</body>

javascript html jquery panel
2个回答
1
投票

我会这样做。您将需要另一个

SVG
图像来正确设计分隔符,因为前一个图像是为了水平目的而创建的。

// A function is used for dragging and moving
function dragElement(element, direction) {
  var md; // remember mouse down info
  const first = document.getElementById("first");
  const second = document.getElementById("second");

  element.onmousedown = onMouseDown;

  function onMouseDown(e) {
    //console.log("mouse down: " + e.clientX);
    md = {
      e,
      offsetLeft: element.offsetLeft,
      offsetTop: element.offsetTop,
      firstHeight: first.offsetHeight,
      secondHeight: second.offsetHeight
    };

    document.onmousemove = onMouseMove;
    document.onmouseup = () => {
      //console.log("mouse up");
      document.onmousemove = document.onmouseup = null;
    }
  }

  function onMouseMove(e) {
    //console.log("mouse move: " + e.clientX);
    var delta = {
      x: e.clientX - md.e.clientX,
      y: e.clientY - md.e.clientY
    };

    if (direction === "V") // Vertical
    {        
      // Prevent negative-sized elements
      delta.x = Math.min(Math.max(delta.y, -md.firstHeight),
        md.secondHeight);

      element.style.top = md.offsetTop + delta.x + "px";
      first.style.height = (md.firstHeight + delta.x) + "px";
      second.style.height = (md.secondHeight - delta.x) + "px";
    }
  }
}


dragElement(document.getElementById("separator"), "V");
.splitter {
  width: 100%;
  height: 100px;  
}

#separator {
  cursor: col-resize;
  background-color: #aaa;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='3'><path d='M2 30 0 M5 0 v30 M8 0 v30' fill='none' stroke='black'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  width: 100%;
  height: 5px;
  /* Prevent the browser's built-in drag from interfering */
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

#first {
  background-color: #dde;
  width: 100%;
  height: 100%;
  min-width: 10px;
}

#second {
  background-color: #eee;
  width: 100%;
  height: 100%;
  min-width: 10px;
}
<body>
  <div class="splitter">
    <div id="first"></div>
    <div id="separator"></div>
    <div id="second"></div>
  </div>
</body>


0
投票

适用于桌面和触摸屏的版本。

来源:https://dirask.com/snippets/JavaScirpt-simple-vertical-splitter-component-in-Vanilla-JS-pOXbaj

<!doctype html>
<html>
<head>
  <style>

    div.splitter {
        border: 1px solid #e4e4e4;
        width: 300px; height: 200px;
        display: flex;
        flex-direction: column;
    }
    
    div.panel {
        flex: auto;
        max-height: calc(100% - 6px);
        overflow: auto;
    }

    div.resizer {
        position: relative;
        border: 1px #e4e4e4;
        border-style: solid none;
        background: rgb(228, 228, 228, 20%) url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2230.267%22%20height%3D%226.267%22%20viewBox%3D%220%200%208.006%201.658%22%3E%3Cpath%20fill%3D%22%23cfcfcf%22%20d%3D%22M8.008%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM6.95%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM5.892%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM4.832%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM3.776%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM2.717%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM1.657%200v.6h-.6V0Zm0%201.058v.6h-.6v-.6zM.6%200v.6H0V0Zm0%201.058v.6H0v-.6z%22%2F%3E%3C%2Fsvg%3E') no-repeat center / 18px;
        flex: 0 0 6px;
        cursor: row-resize;  /* OR:  n-resize */
        /* the below styles disable selection for resizer element           */
        -webkit-touch-callout: none;  /* iOS Safari                         */
          -webkit-user-select: none;  /* Safari                             */
           -khtml-user-select: none;  /* Konqueror HTML                     */
             -moz-user-select: none;  /* Firefox in the past (old versions) */
              -ms-user-select: none;  /* Internet Explorer (>=10) / Edge    */
                  user-select: none;  /* Currently supported:               */
                                      /* Chrome, Opera and Firefox          */
    }

    div.resizer:hover::after {
        position: absolute;
        top: -6px; right: 0; bottom: -6px; left: 0;
        background: rgb(228, 228, 228, 30%);
        display: block;
        content: ''
    }

  </style>
  <script type="text/javascript">

    function computeMargins(element) {
        var style = element.currentStyle || window.getComputedStyle(element);
        return {
            marginTop: parseInt(style.marginTop),
            marginBottom: parseInt(style.marginBottom)
        };
    }

    function prepareResizer(master, resizer) {
        var removed = false;
        var dragging = false;
        var position;
        var style = master.style;
        var handleMouseDown = function(event) {
            var margins = computeMargins(master);
            position = margins.marginTop + margins.marginBottom + master.offsetHeight - event.clientY;
            dragging = true;
        };
        var handleMouseUp = function(event) {
            dragging = false;
        };
        var handleMouseMove = function(event) {
            if (dragging) {
                var y = position + event.clientY;
                style.flex = `0 0 ${y}px`;
            }
        };
        var handleTouchStart = function(event) {
            var touches = event.touches;
            if (touches.length === 1) {
                event.preventDefault();
                var touch = touches[0];
                handleMouseDown({
                    clientX: touch.clientX,
                    clientY: touch.clientY
                });
            }
        };
        var handleTouchEnd = function(event) {
            var touches = event.touches;
            if (touches.length === 0) {
                handleMouseUp({});
            }
        };
        var handleTouchMove = function(event) {
           if (dragging) {
                event.preventDefault();
                var touches = event.touches;
                if (touches.length === 1) {
                    var touch = touches[0];
                    handleMouseMove({
                        clientX: touch.clientX,
                        clientY: touch.clientY
                    });
                }
            }
        };
        resizer.addEventListener('mousedown', handleMouseDown);
        resizer.addEventListener('touchstart', handleTouchStart);
        window.addEventListener('mouseup', handleMouseUp);
        window.addEventListener('touchend', handleTouchEnd);
        window.addEventListener('mousemove', handleMouseMove);
        window.addEventListener('touchmove', handleTouchMove);
        return function() {
            if (removed) {
                return;
            }
            resizer.removeEventListener('mousedown', handleMouseDown);
            resizer.removeEventListener('touchstart', handleTouchStart);
            window.removeEventListener('mouseup', handleMouseUp);
            window.removeEventListener('touchmove', handleTouchEnd);
            window.removeEventListener('mousemove', handleMouseMove);
            window.removeEventListener('touchend', handleTouchMove);
            removed = true;
        };
    }

  </script>
</head>
<body>
  <div class="splitter">
    <div id="master" class="panel">Panel 1</div>
    <div id="resizer" class="resizer"></div>
    <div class="panel">Panel 2</div>
  </div>
  <script>

      var master = document.querySelector('#master');
      var resizer = document.querySelector('#resizer');

      prepareResizer(master, resizer);

  </script>
</body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.