vue div支持拖动调整尺寸 支持PC和移动端

找到的html demo,只有pc端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<style>
    body,
    html {
        width: 100%;
        height: 100%;
        margin: 10;
    }

    #drag {
        width: 200px;
        height: 200px;
        padding: 15px;
        position: absolute;
        left: 100px;
        top: 100px;
        border: #00cdcd 2px solid;
        box-sizing: border-box;
    }
</style>


<script  type="text/javascript">

    setTimeout(()=>{

        let c = document.getElementById('drag')//需要调整尺寸的div
        console.log(c,document.body);
        document.body.addEventListener('mousemove', move)// body监听移动事件
        
        c.addEventListener('mousedown', down)// 鼠标按下事件
        
        document.body.addEventListener('mouseup', up)// 鼠标松开事件
    
        let issize = false// 是否开启尺寸修改
    
        let cX, cY	// 鼠标按下时的坐标,并在修改尺寸时保存上一个鼠标的位置
        
        let minW = 8,
            minH = 8// div可修改的最小宽高
        
        let dir = ''// 鼠标按下时的位置,使用n、s、w、e表示
    
        function up() {// 鼠标松开时结束尺寸修改
            issize = false
        }
        
        function down(e) {// 鼠标按下时开启尺寸修改
            let d = getDir(e)
            console.log('d',d);
            // 当位置为四个边和四个角时才开启尺寸修改
            if (d !== '') {
            // 当位置为底部开启尺寸修改
            // if (d === 's') {
                issize = true
                dir = d
                cX = e.clientX
                cY = e.clientY
            }
        }
        
        function move(e) {// 鼠标移动事件
            let d = getDir(e)
            let cursor
            if (d === '') cursor = 'default';
            else cursor = d + '-resize';
            // 修改鼠标显示效果
            c.style.cursor = cursor;
            // 当开启尺寸修改时,鼠标移动会修改div尺寸
            if (issize) {
                // 鼠标按下的位置在右边,修改宽度
                if (dir.indexOf('e') !== -1) {
                    c.style.width = Math.max(minW, c.offsetWidth + (e.clientX - cX)) + 'px'
                    cX = e.clientX
                }
                // 鼠标按下的位置在上部,修改高度
                if (dir.indexOf('n') !== -1) {
                    c.style.height = Math.max(minH, c.offsetHeight + (cY - e.clientY)) + 'px'
                    cY = e.clientY
                }
                // 鼠标按下的位置在底部,修改高度
                if (dir.indexOf('s') !== -1) {
                    c.style.height = Math.max(minH, c.offsetHeight + (e.clientY - cY)) + 'px'
                    cY = e.clientY
                }
                // 鼠标按下的位置在左边,修改宽度
                if (dir.indexOf('w') !== -1) {
                    c.style.width = Math.max(minW, c.offsetWidth + (cX - e.clientX)) + 'px'
                    cX = e.clientX
                }
            }
        }
        
        // 获取鼠标所在div的位置
        function getDir(ev) {
            let x, y, o, d;
            d = '';
    
            x = ev.offsetX;
            y = ev.offsetY;
            o = 10;
    
            if (y < o) d += 'n';
            else if (y > c.offsetHeight - o) d += 's';
            if (x < o) d += 'w';
            else if (x > c.offsetWidth - o) d += 'e';
    
            return d;
        }
    },1000)
</script>


<body>
    <div id="drag"></div>
</body>

</html>

改造后实现视频窗口上下拖拽的需求

async dragVideo() {
  if (!this.isDragEnv) return

  document.body.removeEventListener('mousemove', move)
  document.body.removeEventListener('mouseup', up)
  // 移动端监听touch事件
  document.body.removeEventListener('touchmove', move)
  document.body.removeEventListener('touchend', up)

  // 等待dom初始化完成
  await this.sleep(500)

  // 接口控制是否开启拖动
  let allowVideoDrag = false
  await window.zlCourseService
    .getScreenScale({})
    .then(res => {
      allowVideoDrag = res && res.button
    })
    .catch(() => {
      allowVideoDrag = false
    })
  this.allowVideoDrag = allowVideoDrag
  if (!allowVideoDrag) return

  // 拖动窗口功能
  let clientWidth = document.body.clientWidth // 页面可见宽度
  let clientHeight = document.body.clientHeight // 页面可见高度

  if (clientWidth < 600) return

  let c = document.querySelector('.xxx') //需要拖动的div videoBox
  if (!c) return

  let video = document.querySelector('.xxx video')
  video = video && video.parentElement
  let headerBox = document.querySelector('.header-box')
  let outContainer = document.querySelector('.out-container')
  let footer = document.querySelector('.play-video-bottombox')

  video.style.height = video.offsetHeight - 4 + 'px' // 视频窗口高度-4px, 避免覆盖拖动div

  document.body.addEventListener('mousemove', move) // body监听移动事件
  document.body.addEventListener('mouseup', up) // 鼠标松开事件
  document.body.addEventListener('touchmove', move)
  document.body.addEventListener('touchend', up)

  let issize = false // 是否开启尺寸修改

  let cY // 鼠标按下时的坐标,并在修改尺寸时保存上一个鼠标的位置

  let minH = clientHeight * 0.3, // div可修改的最小宽高
    maxH = clientHeight * 0.8

  let dir = '' // 鼠标按下时的位置,使用n、s、w、e表示

  function up() {
    // 鼠标松开时结束尺寸修改
    issize = false
  }

  function down(e) {
    // 鼠标按下时开启尺寸修改
    let d = getDir(e)
    // 当位置为底部开启尺寸修改
    if (d === 's') {
      issize = true
      dir = d
      cY =
        e.clientY ||
        (e.targetTouches[0] ? e.targetTouches[0].clientY : 0) // 鼠标||touch
    }
  }

  const _this = this
  async function move(e) {
    // 更新获取的页面宽高的值
    clientWidth = document.body.clientWidth // 页面可见宽度
    clientHeight = document.body.clientHeight // 页面可见高度
    if (clientWidth < 600) return

    // 切换线路老师等会销毁dom 需重新获取dom
    c = document.querySelector('.xxx') //需要拖动的div videoBox
    if (!c) return
    video = document.querySelector('.xxx video')
    video = video && video.parentElement

    c.removeEventListener('mousedown', down)
    c.removeEventListener('touchstart', down)
    await _this.sleep(0)
    c.addEventListener('mousedown', down) // 鼠标按下事件
    c.addEventListener('touchstart', down) 

    // 鼠标移动事件
    let d = getDir(e)
    let cursor
    if (d === '') cursor = 'default'
    else cursor = d + '-resize'

    // 修改鼠标显示效果
    c.style.cursor = cursor
    if (_this.dragTimer !== null) {
      clearTimeout(_this.dragTimer)
      _this.dragTimer = null
    }
    _this.dragTimer = setTimeout(() => {
      // 当开启尺寸修改时,且鼠标按下的位置在底部,修改高度
      // console.log('issize',issize,dir);
      let clientY = 0
      if (issize && dir.indexOf('s') !== -1) {
        if (e.clientY !== undefined) {
          // 鼠标
          clientY = e.clientY
        } else if (e.targetTouches[0]) {
          // 触屏
          clientY = e.targetTouches[0].clientY
        }
        clientY = clientY || 0

        // console.log('修改高度');
        let finallyH = Math.max(minH, c.offsetHeight + (clientY - cY))
        finallyH = Math.min(finallyH, maxH)

        c.style.height = finallyH + 'px'
        cY = clientY

        // 改变视频容器宽高
        if (video) {
          video.style.width = clientWidth + 'px'
          video.style.height = finallyH - 4 + 'px' // 视频窗口高度-4px, 避免覆盖拖动div
        }
        // 改变下半部分高度
        let outContainerH =
          clientHeight -
          finallyH -
          ((headerBox && headerBox.offsetHeight) || 0) -
          ((footer && footer.offsetHeight) || 0)
        outContainer.style.height = outContainerH + 'px'

        // 保存高度信息 用于还原
        _this.dragHeightInfo = {
          finallyH,
          clientWidth,
          outContainerH
        }
      }
    }, 0)
  }

  // 获取鼠标所在div的位置
  function getDir(ev) {
    let y, o, d
    d = ''
    // y = ev.offsetY
    let offsetY = 0

    if (ev.offsetY !== undefined) {
      // 鼠标
      offsetY = ev.offsetY
    } else if (ev.touches[0]) {
      // 触屏
      offsetY = ev.touches[0].clientY
    }

    y = offsetY || 0

    o = 10

    if (y < o) d += 'n'
    else if (y > c.offsetHeight - o) d += 's'

    return d
  }
}
posted @ 2023-02-09 11:04  珞珞9527  阅读(29)  评论(0编辑  收藏  举报