鼠标拖动效果

211 阅读1分钟

大家好,我是梅巴哥er


好久不写这种效果了,突然写起来,还真费了点力气。 放这里,以后用的时候复习一下。

下面的代码直接CV到编辑器里,用浏览器打开页面就能直接用。

原生js写的,在框架范围内,不用考虑兼容性问题。

不管用的哪种框架,拿去就能用。


web端拖动代码案例
<!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>
  <style>
    * {
        padding: 0;
        left: 0;
      }
      .box {
        position: relative;
        width: 200px;
        height: 80px;
        background-color: aqua;
        overflow: hidden;
      }
      .box1 {
        position: absolute;
        top: 0;
        left: 0;
        width: 250px;
        height: 100%;
        background-color: pink;
      }
      .bar {
        position: relative;
        width: 200px;
        height: 10px;
        overflow: hidden;
      }
      .bar1 {
        position: absolute;
        top: 0;
        left: 0;
        width: 50%;
        height: 100%;
        background-color: red;
      }
  </style>
</head>
<body>
  <div class="box">
    <div class="box1">12112214311241fafgatggagtq</div>
  </div>
  <div class="bar">
    <div class="bar1"></div>
  </div>
  <script>
    window.addEventListener('load', function() {
    var log = console.log || window.console.log;
    var $ = document.querySelector.bind(document);

    var box = $('.box');
    var box1 = $('.box1');
    var bar = $('.bar');
    var bar1 = $('.bar1');

    var ex; //鼠标点击box1的初始位置
    var bl; //box1的初始left值
    var bo; //bar1的初始left值

    box1.onmousedown = function(e) {
      e.preventDefault();
      bl = box1.offsetLeft;
      bo = bar1.offsetLeft;
      ex = e.offsetX;
      box1.style.cursor = 'move';
      box1.onmousemove = function(e) {
        if(bl + e.offsetX - ex >= 0) {
          box1.style.left = 0;
          bar1.style.left = 0;
        } else if(bl + e.offsetX - ex <= box.offsetWidth - box1.offsetWidth) {
          box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
          bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
        } else {
          box1.style.left = bl + e.offsetX - ex + 'px';
          bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(e.offsetX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
        }
      }
      document.onmouseup = function() {
        box1.onmousemove = null;
      }
    }

  })
  </script>
</body>
</html>

拖动方法在web页面的封装
function moveBarFn(obj) {
    var box = $('.' + obj.box);
    var box1 = $('.' + obj.box1);
    var bar = $('.' + obj.bar);
    var bar1 = $('.' + obj.bar1);
    var ex; //鼠标点击到box1时的x位置
    var bl; //box1的初始left值
    var bo; //bar1的初始left值
    box1.onmousedown = function(e) {
      e.preventDefault();
      bl = box1.offsetLeft;
      bo = bar1.offsetLeft;
      ex = e.offsetX;
      box1.style.cursor = 'move';
      box1.onmousemove = function(e) {
        if(bl + e.offsetX - ex >= 0) {
          box1.style.left = 0;
          bar1.style.left = 0;
        } else if(bl + e.offsetX - ex <= box.offsetWidth - box1.offsetWidth) {
          box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
          bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
        } else {
          box1.style.left = bl + e.offsetX - ex + 'px';
          bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(e.offsetX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
        }
      }
      document.onmouseup = function() {
        box1.onmousemove = null;
      }
    }
  }
封装后的用法
var obj = {
    box: 'box',
    box1: 'box1',
    bar: 'bar',
    bar1: 'bar1',
  }
moveBarFn(obj);

注意事项(避雷针)
  • 如果box1中有子盒子是带有relative定位的,e.offsetX的值会变得混乱不堪。这是因为它的值是鼠标的点击位置和最近定位的盒子之间的距离。

在这里插入图片描述
以上图为例。分别点击abcde五个点,对应的e.offsetX并不是依次增加的,因为他们的相对位置是不一样的。(可以自己log输出一下看看)

  • 解决办法

    • 尽量避免要移动的盒子里,还存在带有定位的子盒子的情况。
    • 如果不能避免,可以在box盒子里,加上一个absolute定位的遮盖层,覆盖在box1之上。
    • 这样就可以让鼠标点击的是遮盖层,而非box1盒子。
    • 或者干脆不用e.offsetX, 而改用和定位无关的e.clientX

app端的拖动代码案例
<!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>
  <style>
    * {
  padding: 0;
  left: 0;
}
.box {
  position: relative;
  width: 200px;
  height: 80px;
  background-color: aqua;
  overflow: hidden;
}
.box1 {
  position: absolute;
  top: 0;
  left: 0;
  width: 250px;
  height: 100%;
  background-color: pink;
}
.box2 {
  position: relative;
  width: 100px;
  height: 50px;
  margin-left: 50px;
  margin-top: 20px;
  background-color: blue;
}
.bar {
  position: relative;
  width: 200px;
  height: 10px;
  overflow: hidden;
}
.bar1 {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background-color: red;
}
  </style>
</head>
<body>
  <div class="box">
    <div class="box1">12112214311241fafgatggagtq
      <div class="box2"></div>
    </div>
  </div>
  <div class="bar">
    <div class="bar1"></div>
  </div>
  <script>
    window.addEventListener('load', function() {
  var log = console.log || window.console.log;
  var $ = document.querySelector.bind(document);

  var box = $('.box');
  var box1 = $('.box1');
  var bar = $('.bar');
  var bar1 = $('.bar1');
  box1.ontouchstart = function(e) {
    e.preventDefault();
    var touch = e.touches[0];
    var ex = touch.clientX;
    var bl = box1.offsetLeft;
    var bo = bar1.offsetLeft;
    box1.ontouchmove = function(e) {
      var touch = e.touches[0];
      if(bl + touch.clientX - ex >= 0) {
        box1.style.left = 0;
        bar1.style.left = 0;
      } else if(bl + touch.clientX - ex <= box.offsetWidth - box1.offsetWidth) {
        box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
        bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
      } else {
        box1.style.left = bl + touch.clientX - ex + 'px';
        bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(touch.clientX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
      }
    }
    document.ontouchend = function(e) {
      box1.ontouchmove = null;
    }
  }

})
  </script>
</body>
</html>
app端拖动方法简单封装
function moveBarFn(obj) {
    var box = $('.' + obj.box);
    var box1 = $('.' + obj.box1);
    var bar = $('.' + obj.bar);
    var bar1 = $('.' + obj.bar1);
    box1.ontouchstart = function(e) {
      e.preventDefault();
      var touch = e.touches[0];
      var ex = touch.clientX;
      var bl = box1.offsetLeft;
      var bo = bar1.offsetLeft;
      box1.ontouchmove = function(e) {
        var touch = e.touches[0];
        if(bl + touch.clientX - ex >= 0) {
          box1.style.left = 0;
          bar1.style.left = 0;
        } else if(bl + touch.clientX - ex <= box.offsetWidth - box1.offsetWidth) {
          box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
          bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
        } else {
          box1.style.left = bl + touch.clientX - ex + 'px';
          bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(touch.clientX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
        }
      }
      document.ontouchend = function(e) {
        box1.ontouchmove = null;
      }
    }
  }
使用示例
var obj = {
    box: 'box', //外层盒子的类名
    box1: 'box1', //要移动的盒子的类名
    bar: 'bar', //包裹滑动条的盒子类名
    bar1: 'bar1', //滑动条的类名
  }
  moveBarFn(obj); //调用函数
app端注意事项
  • app的 ontouchstart 相当于web的onmousedown,鼠标放下,触摸屏幕
  • app的 ontouchmove 相当于web的onmousenove,鼠标移动
  • app的 ontouchend 相当于web的onmouseup,鼠标抬起,离开`屏幕
  • 需要注意的是,在ontouchstart和ontouchmove事件中,都有var touch = e.touches[0]; ,这是选取触摸点的,事件里都要带上,不然触摸无效。

或许还需要注意
  • 看下自己的项目里,在执行完拖动时,是否还需要复位。
  • 初始化,初始化,初始化对于每个项目,都相当重要。所以,适当注意是否需要复位。