兩欄佈局左右拖拽效果實現方案

兩欄佈局左右拖拽效果實現方案

CSS方式實現

screenshot-20220718-144148

第一種利用的css的方式實現,利用瀏覽器非 overflow:auto 元素 設置 resize 可以拉伸的特性實現無JavaScript的分欄寬度控制。

webkit瀏覽器下滾動條可以自定義,其中resize區域大小就是scrollbar的大小,於是,我們可以將整個拉伸區域變成和容器一樣高

紅色的就是擴大後的區域

不推薦使用css的方式實現,畢竟兼容性並不好。在火狐上表現不佳。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AA-drag</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      .fl-container {
        width: 100%;
        height: 100vh;
        overflow: hidden;
      }
      .fl-resize-bar,
      .fl-resize-bar::-webkit-scrollbar {
        width: 400px;
      }
      .fl-left {
        position: relative;
        float: left;
        height: 100vh;
        background: pink;
      }
      .fl-right {
        box-sizing: border-box;
        overflow-x: hidden;
        height: 100vh;
      }
      .fl-cont-right {
        height: 200vh;
      }
      .fl-resize-bar {
        height: inherit;
        resize: horizontal;
        cursor: ew-resize;
        cursor: col-resize;
        opacity: 0;
        overflow: scroll;
      }
      .fl-resize-bar::-webkit-scrollbar {
        width: 400px;
        height: inherit;
      }

      .fl-cont-left {
        position: absolute;
        top: 0;
        right: 4px; /* 拖拽線的間距 */
        bottom: 0;
        left: 0;
        overflow-x: hidden;
        background: #fff;
      }

      .fl-resize-line {
        position: absolute;
        right: 1px;
        top: 0;
        bottom: 0;
        border-right: 2px solid #bbb;
        pointer-events: none;
      }
      .fl-resize-bar:hover ~ .fl-resize-line,
      .fl-resize-bar:active ~ .fl-resize-line {
        border-right: 2px dashed skyblue;
      }

      /* Firefox只有下面一小塊區域可以拉伸 */
      @supports (-moz-user-select: none) {
        .fl-resize-bar:hover ~ .fl-resize-line,
        .fl-resize-bar:active ~ .fl-resize-line {
          border-right: 2px solid #bbb;
        }
        .fl-resize-bar:hover ~ .fl-resize-line::after,
        .fl-resize-bar:active ~ .fl-resize-line::after {
          content: '';
          position: absolute;
          width: 16px;
          height: 16px;
          bottom: 0;
          right: -8px;
          background: url(https://www.zhangxinxu.com/study/201903/css-idea/resize.svg);
          background-size: 100% 100%;
          z-index: 1;
        }
      }
    </style>
  </head>
  <body>
    <div class="fl-container">
      <div class="fl-left">
        <div class="fl-resize-bar"></div>
        <div class="fl-resize-line"></div>
        <div class="fl-cont-left">左側內容</div>
      </div>
      <div class="fl-right">
        <div class="fl-cont-right">
          右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容 右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容
          右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側
          內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容右側內容
        </div>
      </div>
    </div>
  </body>
</html>

使用js方式實現

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AA-drag</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      #left,
      #right,
      #middle {
        height: 100vh;
        position: absolute;
      }
      #left {
        width: 300px;
        background: #ccc;
      }
      #middle {
        width: 5px;
        background: #666;
        left: 300px;
      }
      #middle:hover {
        cursor: col-resize;
      }
      #right {
        right: 0;
        background: #ccc;
        left: 305px;
        width: auto;
      }
    </style>
  </head>
  <body>
    <div id="left">左側內容</div>
    <div id="middle"></div>
    <div id="right">右側內容</div>
  </body>
</html>
<script>
  function getEle(id) {
    return document.getElementById(id);
  }
  window.onload = function () {
    let left = getEle('left');
    let right = getEle('right');
    let middle = getEle('middle');

    let middleWidth = 5;
    middle.onmousedown = function (e) {
      var disX = (e || event).clientX;
      middle.left = middle.offsetLeft;
      document.onmousemove = function (e) {
        let middleLeft = middle.left + ((e || event).clientX - disX);
        let maxWidth = document.body.clientWidth;
        middleLeft < 0 && (middleLeft = 0);
        middleLeft > maxWidth && (middleLeft = maxWidth);
        middle.style.left = left.style.width = middleLeft + 'px';
        right.style.width = maxWidth - middleLeft - middleWidth + 'px';
        right.style.left = middleLeft + middleWidth + 'px';
        return false;
      };
      document.onmouseup = function () {
        document.onmousemove = null;
        document.onmouseup = null;
        middle.releaseCapture && middle.releaseCapture();
      };
      middle.setCapture && middle.setCapture();
      return false;
    };
  };
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章