Pure css3, pure js, splitpanes plug-in method for front-end area block dragging

1. Pure css3

The specific usage of the resize attribute can be found on MDN: https://developer.mozilla.org/zh-CN/docs/Web/CSS/resize

Effect link: http://js.jirengu.com/voleracixe/2/edit

Utilize the resize feature of the browser's non-overflow:auto element to achieve JavaScript-free column width control.

principle

There is a resize attribute in CSS. If the overflow attribute value of an element is not visible, the size of the element can be stretched by setting the resize attribute.

How to make the drag area larger?

Later research found that the drag bar of the resize attribute and the drag bar of the scroll bar are things in the same system. You only need to customize the scroll bar to indirectly set the size of the resize bar.

.resize-bar::-webkit-scrollbar {
    
    
    width: 200px; height: 200px;
}

a complete example

<!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>

2. Pure 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 () {
    
    
    const left = getEle('left')
  const right = getEle('right')
  const middle = getEle('middle')

  const middleWidth = 5
  middle.onmousedown = function (e) {
    
    
      const disX = (e || event).clientX
      middle.left = middle.offsetLeft
      document.onmousemove = function (e) {
    
    
        let middleLeft = middle.left + ((e || event).clientX - disX)
        const 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>

2.1. onmousedown, onmousemove, onmouseup mouse press/move/release

1. onmousedown——select element

oDiv.onmousedown = function(ev) {
    
    }

2. onmousemove - moving elements
Trigger frequency: not pixels, but interval time. Within a specified time (very short), if the position of the mouse changes from the previous position, it will trigger once

var i = 0;
document.onmousemove = function() {
    
    
    document.title = i++;  //鼠标移动,页面的标题发生变化,移动的越慢数字越大
}

3. onmouseup - release elements

document.onmouseup = function() {
    
    }

4. Structural relationship among the three

oDiv.onmousedown = function() {
    
    
    document.onmousemove = function() {
    
    } 
    //拖动的太快了超出元素的本身的位置会停在半路,所以元素改为文档
    document.onmouseup = function() {
    
    }  
    //如果有别的元素在拖动元素停止的位置之上,松开鼠标则还可以继续拖动,因为不是在拖动元素上松开的,所以元素应改为文档      
}

2.2. Attention

1. When dragging, if any text is selected, problems will occur.

Reason: When the mouse is pressed, if text is selected on the page, the browser's default dragging effect will be triggered.

Solution:

(1) Standard browser: block default behavior

return false;

(2) IE678: There is no way to prevent it, so you need to set up global capture - .setCapture()

if ( obj.setCapture ) {
    
    
       obj.setCapture();
}  

2.3 Switch the browser window size and recalculate the size

onMounted(() => {
    
    
  window.addEventListener('resize', () => {
    
    
    resizeInit()
  })
})
function resizeInit() {
    
    
    const left = getEle('left')
    const right = getEle('right')
    const middle = getEle('middle')
    left.style.width = '300px'
    middle.style.left = '310px'
    const maxWidth = (document.body.clientWidth - 50) * 2/3
    right.style.width = `${
      
      maxWidth - 311 - 20}px`
    right.style.left = '311px'
}

3. splitpanes plug-in (vertical and horizontal split windows)

Official website: https://antoniandre.github.io/splitpanes/
Use in vue3 project

Install

​​​​​​​pnpm i splitpanes@next

Use on the page

import {
    
     Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'

html in

min-size="0" max-size="35" sets the maximum and minimum percentages that can be adjusted in the left window

<splitpanes class="default-theme" @resize="paneSize = $event[0].size" style="height: 400px">
  <pane :size="paneSize" min-size="0" max-size="35">
    <span>{
    
    {
    
     paneSize }}%</span>
  </pane>
  <pane :size="100 - paneSize">
    <span>{
    
    {
    
     100 - paneSize }}%</span>
  </pane>
</splitpanes>

Guess you like

Origin blog.csdn.net/wang13679201813/article/details/130290260