鼠标行为 → 坐标系

🌈 封装 - 获取鼠标相对文档位置

function pagePos(e) {
  var sLeft = getScrollOffset().left,
      sTop = getScrollOffset().top,
      // 获取文档左边框和上边框的宽度
      cLeft = document.documentElement.clientLeft || 0,
      cTop = document.documentElement.clientTop || 0;
  
  return {
  	X: e.clientX + sLeft - cLeft,
    Y: e.clientY + sTop - cTop
  }
}

拖拽 div

<!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>
    body {
      margin: 0;
      padding: 0;
    }
    .box {
      position: absolute;
      left: 0;
      top: 0;
      background-color: orange;
      width: 100px;
      height: 100px;
    }
  </style>
</head>
<body>
  <div class="box"></div>
  <script>
    function getScrollOffset() {
      if (window.pageXOffset) {
        return {
          left: window.pageXOffset,
          top: window.pageYOffset
        }
      } else {
        return {
          left: document.body.scrollLeft + document.documentElement.scrollLeft,
          top: document.body.scrollTop + document.documentElement.scrollTop
        }
      }
    }

    function pagePos(e) {
      var sLeft = getScrollOffset().left,
          sTop = getScrollOffset().top,
          cLeft = document.documentElement.clientLeft || 0,
          cTop = document.documentElement.clientTop || 0;

      return {
        X: e.clientX + sLeft - cLeft,
        Y: e.clientY + sTop - cTop
      }
    }

    function getStyles(elem, prop) {
      if (window.getComputedStyle) {
        if (prop) {
          return window.getComputedStyle(elem, null)[prop];
        } else {
          return window.getComputedStyle(elem, null);
        }
      } else {
        if (prop) {
          return window.currentStyle(elem, null)[prop];
        } else {
          return window.currentStyle(elem, null);
        }
      }
    }

    var box = document.getElementsByClassName("box")[0];

    box.onmousedown = function(e) {
      var e = e || window.event;
      // 鼠标离文档左侧距离 - box离文档左侧距离 = 鼠标距box左边缘距离
      var x = pagePos(e).X - parseInt(getStyles(box, 'left')),
          y = pagePos(e).Y - parseInt(getStyles(box, 'top'));
          
      document.onmousemove = function(e) {
        var e = e || window.event;
        // 每次再把x,y这段距离减去
        box.style.left = pagePos(e).X - x + 'px';
        box.style.top = pagePos(e).Y - y + 'px';
      }

      document.onmouseup = function(e) {
        this.onmousemove = null;
        this.onmouseup = null;
      }
    }
  </script>
</body>
</html>

🌈 封装

<!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>
    body {
      margin: 0;
      padding: 0;
    }
    .box {
      position: absolute;
      left: 0;
      top: 0;
      background-color: orange;
      width: 100px;
      height: 100px;
    }
  </style>
</head>
<body>
  <div class="box"></div>
  <script>
    // 添加事件
    function addEvent(elem, type, fn) {
      if (elem.addEventListener) {
        elem.addEventListener(type, fn, false);
      } else if (elem.attachEvent) {
        elem.attachEvent('on' + type, function() {
          fn.call(elem);
        })
      } else {
        elem['on' + type] = fn;
      }
    }

    // 移除事件
    function removeEvent(elem, type, fn) {
      if (elem.addEventListener) {
        elem.removeEventListener(type, fn, false);
      } else if (elem.attachEvent) {
        elem.detachEvent('on' + type, fn);
      } else {
        elem['on' + type] = null;
      }
    }

    // 获取页面偏移
    function getScrollOffset() {
      if (window.pageXOffset) {
        return {
          left: window.pageXOffset,
          top: window.pageYOffset
        }
      } else {
        return {
          left: document.body.scrollLeft + document.documentElement.scrollLeft,
          top: document.body.scrollTop + document.documentElement.scrollTop
        }
      }
    }

    // 获取鼠标相对文档偏移
    function pagePos(e) {
      var sLeft = getScrollOffset().left,
          sTop = getScrollOffset().top,
          cLeft = document.documentElement.clientLeft || 0,
          cTop = document.documentElement.clientTop || 0;

      return {
        X: e.clientX + sLeft - cLeft,
        Y: e.clientY + sTop - cTop
      }
    }

    // 获取元素样式
    function getStyles(elem, prop) {
      if (window.getComputedStyle) {
        if (prop) {
          return window.getComputedStyle(elem, null)[prop];
        } else {
          return window.getComputedStyle(elem, null);
        }
      } else {
        if (prop) {
          return window.currentStyle(elem, null)[prop];
        } else {
          return window.currentStyle(elem, null);
        }
      }
    }

    // 取消冒泡
    function cancelBubble(e) {
      var e = e || window.event;

      if (e.stopPropagation) {
        e.stopPropagation();
      } else {
        e.cancelBubble = true;
      }
    }

    // 阻止默认事件
    function preventDefaultEvent(e) {
      var e = e || window.event;
      if (e.preventDefaultEvent) {
        e.preventDefaultEvent();
      } else {
        e.returnValue = false;
      }
    }

    var box = document.getElementsByClassName("box")[0];
    drag(box);

    function drag(elem) {
      var x,
          y;
      addEvent(elem, 'mousedown', function(e) {
        var e = e || window.event;
        x = pagePos(e).X - parseInt(getStyles(elem, 'left'));
        y = pagePos(e).Y - parseInt(getStyles(elem, 'top'));
        
        addEvent(document, 'mousemove', mouseMove);
        addEvent(document, 'mouseup', mouseUp);
        cancelBubble(e);
        preventDefaultEvent(e);
      })
      
      function mouseMove(e) {
        var e = e || window.event;
        elem.style.left = pagePos(e).X - x + 'px';
        elem.style.top = pagePos(e).Y - y + 'px';
      }
      function mouseUp(e) {
        var e = e || window.event;
        removeEvent(document, 'mousemove', mouseMove);
        removeEvent(document, 'mouseup', mouseUp);
      }
    }
  </script>
</body>
</html>