HTML5,DIV拖拽移动,左右吸边,适用移动端、PC端

HTML移动端完美支持苹果、安卓,CV大法走起!!!!

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
    <meta charset="utf-8" />
    <title>移动端DIV拖拽(左右吸边)</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <!-- <link rel="stylesheet" type="text/css" href="css/base_h5_rem.css"> -->
    <style>
      html{width: 100%;height: 100%;padding: 0; margin: 0;}
      body{width: 100%;height: 100%;padding: 0; margin: 0;}
      #body_div{width: 100%;height: 100%;display: flex;flex-direction: column;position: relative;background-color: #F2F2F2;}
    </style>
  </head>
  <body>
    <div id="body_div">
      <header style="text-align: center;padding: 15px 0;background-color: #FFFFFF;">移动端/PC端DIV拖拽(左右吸边)(js+vue.js)</header>
      <div style="flex: 1 1 auto;position: relative;">
        
        <!-- 注意position: absolute;和父级元素position: relative;属性 -->
        <div @touchstart="wtouchstart" @touchmove="wtouchmove" @touchend="wtouchend" @mousedown="wonmousedown" @mousemove="wonmousemove" @mouseup="wonmouseup" style="width: 50px;height: 50px;background-color: red;position: absolute;left: 0px;top: 15%; color: #FFFFFF; font-size: 12px;">我不超出灰色DIV</div>
        
      </div>
      
      <footer style="text-align: center;padding: 15px 0;background-color: #FFFFFF;">底部</footer>
      
      <!-- 注意position: absolute;和父级元素position: relative;属性 -->
      <div @touchstart="wtouchstart" @touchmove="wtouchmove" @touchend="wtouchend" @mousedown="wonmousedown" @mousemove="wonmousemove" @mouseup="wonmouseup" style="width: 70px;height: 70px;background-color: red;position: absolute;right: 0;top: 60%;color: #FFFFFF;">我不超出整个页面</div>
      
    </div>
  </body>
</html>
<script>
  // 注意元素的定位,相对或者固定定位,必须脱离文档流
  // 注意元素的定位,相对或者固定定位,必须脱离文档流
  // 注意元素的定位,相对或者固定定位,必须脱离文档流
  // 我是相对定位,相对于父元素
    new Vue({
        el: "#body_div",
        data: {
      mouseStartX: 0,
      mouseStartY: 0,
      currX: 0,
      currY: 0,
      pcDownFlag: false
        },
        created() {
      
        },
        methods: {
      // 移动端事件 touch start
      wtouchstart(e){
        // 相对于父元素的右上角座标为 x=0,y=0
        this.mouseStartX = e.changedTouches[0].pageX //获取鼠标点击的X坐标
        this.mouseStartY = e.changedTouches[0].pageY //获取鼠标点击的Y坐标
        this.currX = e.changedTouches[0].target.offsetLeft //相对于当前窗口X轴的偏移量
        this.currY = e.changedTouches[0].target.offsetTop //相对于当前窗口Y轴的偏移量
      },
      // 移动端事件 touch move
      wtouchmove(e){
        let currDom = e.changedTouches[0].target
        e.preventDefault();
        moveX=e.changedTouches[0].pageX;//移动过程中X轴的坐标
        moveY=e.changedTouches[0].pageY;//移动过程中Y轴的坐标
        let leftX = this.mouseStartX-this.currX  //鼠标所能移动的最左端是当前鼠标距div左边距的位置
        let rightX = currDom.parentNode.clientWidth-currDom.clientWidth+leftX  //鼠标所能移动的最右端是当前窗口距离减去鼠标距div最右端位置
        let topY = this.mouseStartY-this.currY  //鼠标所能移动最上端是当前鼠标距div上边距的位置
        let bottomY = currDom.parentNode.clientHeight-currDom.clientHeight+topY //鼠标所能移动最下端是当前窗口距离减去鼠标距div最下端位置
        if(moveX<leftX){moveX=leftX;}
        if(moveX>rightX){moveX=rightX;}
        if(moveY<topY){moveY=topY;}
        if(moveY>bottomY){moveY=bottomY;}
        currDom.style.left = (moveX+ this.currX-this.mouseStartX) + 'px'
        currDom.style.top = (moveY+this.currY-this.mouseStartY) + 'px'
      },
      // 移动端事件 touch end
      wtouchend(e){
        const currDom = e.changedTouches[0].target
        e.preventDefault();
        moveX=e.changedTouches[0].pageX;//移动过程中X轴的坐标
        moveY=e.changedTouches[0].pageY;//移动过程中Y轴的坐标
        if(this.currX == currDom.offsetLeft && this.currY == currDom.offsetTop){
          // div座标未移动,认为它是点击事件
          console.log('点击事件');
        }else{
          let left = moveX+ this.currX-this.mouseStartX
          // 以下是左右吸边计算
          let subX = currDom.parentNode.clientWidth - currDom.clientWidth
          if(left >= subX/2){
            currDom.style.left = subX + 'px'
          }else{
            currDom.style.left = 0 + 'px'
          }
        }
      },
      // 电脑端原理一样,看下边方法名变了,删除了changedTouches[0]这个,其它就只有CV了
      // 电脑端 onmouse down
      wonmousedown (e){
        // 相对于父元素的右上角座标为 x=0,y=0
        this.mouseStartX = e.pageX //获取鼠标点击的X坐标
        this.mouseStartY = e.pageY //获取鼠标点击的Y坐标
        this.currX = e.target.offsetLeft //相对于当前窗口X轴的偏移量
        this.currY = e.target.offsetTop //相对于当前窗口Y轴的偏移量
        this.pcDownFlag = true
      },
      // 电脑端 onmouse move
      wonmousemove(e){
        if(!this.pcDownFlag){ //这是移动端touch和mouse方法唯一的区别了,试着可以注释掉,就知道原因了
          return
        }
        let currDom = e.target
        e.preventDefault();
        moveX=e.pageX;//移动过程中X轴的坐标
        moveY=e.pageY;//移动过程中Y轴的坐标
        let leftX = this.mouseStartX-this.currX  //鼠标所能移动的最左端是当前鼠标距div左边距的位置
        let rightX = currDom.parentNode.clientWidth-currDom.clientWidth+leftX  //鼠标所能移动的最右端是当前窗口距离减去鼠标距div最右端位置
        let topY = this.mouseStartY-this.currY  //鼠标所能移动最上端是当前鼠标距div上边距的位置
        let bottomY = currDom.parentNode.clientHeight-currDom.clientHeight+topY //鼠标所能移动最下端是当前窗口距离减去鼠标距div最下端位置
        if(moveX<leftX){moveX=leftX;}
        if(moveX>rightX){moveX=rightX;}
        if(moveY<topY){moveY=topY;}
        if(moveY>bottomY){moveY=bottomY;}
        currDom.style.left = (moveX+ this.currX-this.mouseStartX) + 'px'
        currDom.style.top = (moveY+this.currY-this.mouseStartY) + 'px'
      },
      // 电脑端 onmouse up
      wonmouseup(e){
        this.pcDownFlag = false
        const currDom = e.target
        e.preventDefault();
        moveX=e.pageX;//移动过程中X轴的坐标
        moveY=e.pageY;//移动过程中Y轴的坐标
        if(this.currX == currDom.offsetLeft && this.currY == currDom.offsetTop){
          // div座标未移动,认为它是点击事件
          console.log('点击事件');
        }else{
          let left = moveX+ this.currX-this.mouseStartX
          // 以下是左右吸边计算
          let subX = currDom.parentNode.clientWidth - currDom.clientWidth
          if(left >= subX/2){
            currDom.style.left = subX + 'px'
          }else{
            currDom.style.left = 0 + 'px'
          }
        }
      }
        }
    })
</script>

 

 

 

posted @ 2021-06-30 18:07  黑~白  阅读(1091)  评论(0编辑  收藏  举报