Jacleklm's Blog

实现鼠标拖拽DOM + 页面视图总结

2019/11/17

知识储备

常用的鼠标事件

  • click
  • dbclick:双击
  • mouseenter:当鼠标指针首次移动到元素上时触发。不冒泡
  • mouseleave:当鼠标指针移出元素时触发。不冒泡
  • mousedown:当元素上按下鼠标按钮时候触发
  • mouseup:当元素上释放鼠标按钮时触发
  • mousemove:当鼠标指针在元素内部移动时重复地触发
  • mouseover:当鼠标指针移动到元素上时触发
  • mouseout:当鼠标指针移出元素时触发

事件对象

当触发某个事件时,会产生一个事件对象,这个对象包含着所有与事件有关的信息。会作为参数传递给函数,IE8以及之前的版本event对象是作为window对象的属性存在的。故有了以下常见的写法:function (e) { e = e || window.event; ... } 。事件对象的属性如下:


应用:

1
2
3
4
5
6
7
8
9
10
11
function stopPro(e) {
var e = e || window.event;
// 得到事件目标DOM对象
let dom = e.target || e.srcElement;
// 阻止冒泡
window.event ? e.cancelBubble = true : e.stopPropagation();
// 取消默认事件
window.event ? e.returnValue = false : e.preventDefault();
// 阻止默认行为(但会继续冒泡)
return false
}

坐标

事件对象

  • event对象.screenX / screenY :相对电脑屏幕的坐标,距离左边框和上边框的距离
  • event对象.clientX / clientY :相对浏览器可视区的坐标,同理

DOM节点

DOM节点.offsetLeft / offsetTop

可以获得元素 距离上方或外层元素 的位置,本质和 style.top 是一样的。二者区别:offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位(px);offsetTop 只读,而 style.top 可读写。同理offsetWidth 与 style.width、offsetHeight 与 style.height

DOM节点.clientHeight / clientWidth

浏览器中可视区高度。width + padding(不含border)

DOM节点.scrollHeight / scrollWidth

元素内容真实的宽度,内容不超出盒子高度时为盒子的clientWidth

Window视图

window.innerWidth / innerHeight:浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏) (低版本IE浏览器< IE9不支持)

实现

思路

拖拽无非是鼠标按下点击元素;鼠标移动,元素移动;鼠标抬起,元素停止不动
所以这里我们需要绑定三个事件:mousedown、mousemove、mouseup

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
window.onload = function () {
//【drag元素必须是是绝对定位】
var drag = document.getElementById('box');
drag.onmousedown = function (e) {
// IE8以及之前的版本event对象是作为window对象的属性存在的。故有了以下常见的写法:
e = e || window.event;
//鼠标点与拖拽元素边框的距离。由于DOM.offsetLeft 和DOM.style.left本质是一样的,所以可以这么写
let diffX = e.clientX - drag.offsetLeft;
let diffY = e.clientY - drag.offsetTop;
drag.onmousemove = function (e) {
e = e || window.event;
let left = e.clientX - diffX;
let top = e.clientY - diffY;
//避免拖出可视区外
if (left < 0) { left = 0; }
else if (left > window.innerWidth - drag.offsetWidth) {
//超出了就放在innerWidth的位置,注意这段代码不要写错
left = window.innerWidth - drag.offsetWidth;
}
if (top < 0) top = 0;
else if (top > window.innerHeight - drag.offsetHeight) {
top = window, innerHeight - drag.offsetHeight;
}
drag.style.left = left + 'px';
drag.style.top = top + 'px';
}
drag.onmouseup = function () {
drag.onmousemove = null;
drag.onmousedown = null;
}
}
}
CATALOG
  1. 1. 知识储备
    1. 1.1. 常用的鼠标事件
    2. 1.2. 事件对象
    3. 1.3. 坐标
      1. 1.3.1. 事件对象
      2. 1.3.2. DOM节点
        1. 1.3.2.1. DOM节点.offsetLeft / offsetTop
        2. 1.3.2.2. DOM节点.clientHeight / clientWidth
        3. 1.3.2.3. DOM节点.scrollHeight / scrollWidth
      3. 1.3.3. Window视图
  2. 2. 实现
    1. 2.1. 思路
    2. 2.2. 实现