前端小记 前端小记
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
  • 学习笔记

    • 《Vue》踩坑笔记
    • TypeScript学习笔记
    • 小程序笔记
    • JavaScript设计模式笔记
  • 工具
  • CentOS
  • Java
  • Docker
  • Linux
  • Maven
  • MySQL
  • 其他
  • 技术文档
  • GitHub部署及推送
  • Nodejs
  • 博客搭建
  • Fullpage全屏轮播插件
  • svn
  • 学习
  • 系统重装
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

sweetheart

前端小记
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
  • 学习笔记

    • 《Vue》踩坑笔记
    • TypeScript学习笔记
    • 小程序笔记
    • JavaScript设计模式笔记
  • 工具
  • CentOS
  • Java
  • Docker
  • Linux
  • Maven
  • MySQL
  • 其他
  • 技术文档
  • GitHub部署及推送
  • Nodejs
  • 博客搭建
  • Fullpage全屏轮播插件
  • svn
  • 学习
  • 系统重装
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript

    • JavaScript基础
    • JavaScript原型与原型链
    • JavaScript执行上下文
    • JavaScript作用域与作用域链
    • JavaScript闭包
    • JavaScript对象创建模式
    • JavaScript继承模式
    • JavaScript线程机制和事件机制
    • JavaScript赋值与浅拷贝与深拷贝解析
    • JS常用的正则表达式
    • html&css实现简单的注册页面
    • JS对注册页面进行表单校验
    • 动态表格&全选
    • 元素拖拽实现
      • 思路
      • 代码实现
      • 限制范围
      • 磁性吸附
  • Vue

  • 学习笔记

  • 工具

  • 其他

  • 前端
  • JavaScript
sweetheart
2021-04-12
目录

元素拖拽实现

# 元素拖拽实现

# 思路

1.拿到鼠标点击元素时,元素一开始的位置

2.拿到鼠标移动的距离
            拿到鼠标点击的位置,拿到鼠标移动时实时的位置,
                鼠标移动的实时位置 = 鼠标移动时实时的位置 - 鼠标点击的位置

3.确定鼠标移动后元素的位置(元素一开始的位置+鼠标移动的距离)
1
2
3
4
5
6
7

# 代码实现

<!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>前端小记-拖拽</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      .wrap {
        position: relative;
        height: 100%;
        background: #bfa;
      }
      .wrap > .test {
        position: absolute;
        left: 100px;
        top: 100px;
        background: pink;
        width: 200px;
        height: 200px;
      }
    </style>
  </head>
  <body>
    <div class="wrap">
      <div class="test"></div>
    </div>
  </body>
  <script>
    /*拖拽的思路:
        1.拿到鼠标点击元素时,元素一开始的位置

        2.拿到鼠标移动的距离
                 拿到鼠标点击的位置,拿到鼠标移动时实时的位置,
                       鼠标移动的实时位置 = 鼠标移动时实时的位置 - 鼠标点击的位置

        3.确定鼠标移动后元素的位置(元素一开始的位置+鼠标移动的距离)
    */
    window.onload = function () {
      // 获取元素
      let testNode = document.querySelector(".wrap > .test");
      // 获取元素的起始位置
      let startPoint = { x: 0, y: 0 };
      // 鼠标按下时的位置
      let mouseDownPoint = { x: 0, y: 0 };
      // 鼠标移动时的位置
      let mouseMovePoint = { x: 0, y: 0 };
      // 鼠标移动的距离
      let dis = { x: 0, y: 0 };

      // 为了在下面可以更方便的清除鼠标移动事件和鼠标抬起事件,此时选择使用dom0事件
      testNode.onmousedown = function (ev) {
        //1.拿到鼠标点击元素时,元素一开始的位置
        // 此时的offsetLeft是相对于整个视口的,因为此时的包含块就是初始包含块就是视口
        startPoint.x = this.offsetLeft;
        startPoint.y = this.offsetTop;

        // 2.拿到鼠标点击元素时,鼠标一开始的位置
        // 此时的ev.clientX也是参照于视口的
        mouseDownPoint.x = ev.clientX;
        mouseDownPoint.y = ev.clientY;

        // 鼠标移动事件必须在鼠标按下事件之后才能触发,所以将mousemove事件放到mousedown事件的内部
        document.onmousemove = function (ev) {
          mouseMovePoint.x = ev.clientX;
          mouseMovePoint.y = ev.clientY;
          dis.x = mouseMovePoint.x - mouseDownPoint.x;
          dis.y = mouseMovePoint.y - mouseDownPoint.y;

          testNode.style.left = startPoint.x + dis.x + "px";
          testNode.style.top = startPoint.y + dis.y + "px";
        };
        // 当鼠标抬起的时候将鼠标移动事件和鼠标抬起事件清除,防止鼠标抬起之后再移动鼠标导致元素跟着移动
        document.onmouseup = function () {
          document.onmousemove = document.onmouseup = null;
        };
        // 禁止浏览器的默认行为
        return false;
      };
    };
  </script>
</html>

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

# 限制范围

在鼠标移动事件中添加移动范围的代码,新的鼠标移动事件的代码如下:

 // 鼠标移动事件必须在鼠标按下事件之后才能触发,所以将mousemove事件放到mousedown事件的内部
document.onmousemove = function (ev) {
    mouseMovePoint.x = ev.clientX;
    mouseMovePoint.y = ev.clientY;
    dis.x = mouseMovePoint.x - mouseDownPoint.x;
    dis.y = mouseMovePoint.y - mouseDownPoint.y;
    let L = startPoint.x + dis.x;
    let T = startPoint.y + dis.y;

    if (L < 0) {
    L = 0;
    }
    if (T < 0) {
    T = 0;
    }
    if (
    T >
    document.documentElement.clientHeight - testNode.offsetHeight
    ) {
    T = document.documentElement.clientHeight - testNode.offsetHeight;
    }
    if (L > document.documentElement.clientWidth - testNode.offsetWidth) {
    L = document.documentElement.clientWidth - testNode.offsetWidth;
    }

    testNode.style.left = L + "px";
    testNode.style.top = T + "px";
};
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

# 磁性吸附

在元素移动到具体边框较小的距离时将元素直接吸附到边框上,修改后的鼠标移动事件具体代码如下:

// 鼠标移动事件必须在鼠标按下事件之后才能触发,所以将mousemove事件放到mousedown事件的内部
document.onmousemove = function (ev) {
    mouseMovePoint.x = ev.clientX;
    mouseMovePoint.y = ev.clientY;
    dis.x = mouseMovePoint.x - mouseDownPoint.x;
    dis.y = mouseMovePoint.y - mouseDownPoint.y;
    let L = startPoint.x + dis.x;
    let T = startPoint.y + dis.y;

    if (L < 30) {
    L = 0;
    } else if (
    L >
    document.documentElement.clientWidth - testNode.offsetWidth - 30
    ) {
    L = document.documentElement.clientWidth - testNode.offsetWidth;
    }
    if (T < 30) {
    T = 0;
    } else if (
    T >
    document.documentElement.clientHeight - testNode.offsetHeight - 30
    ) {
    T = document.documentElement.clientHeight - testNode.offsetHeight;
    }

    testNode.style.left = L + "px";
    testNode.style.top = T + "px";
};
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
完善页面 (opens new window)
上次更新: 2024-11-28 17:23:47
动态表格&全选
Vue-CLI4创建Vue项目

← 动态表格&全选 Vue-CLI4创建Vue项目→

最近更新
01
git常用操作手册
12-26
02
常用的前端工具库
12-19
03
前端构建工具
12-19
更多文章>
前端小记 版权所有 | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式