首先还是要明确几个概念,这里通过修改css并截图给大家介绍下,理解了这几个概念,代码写起来会得心应手许多。

  • clientWidth,clientHeight
  • scrollWidth,scrollHeight
  • offsetWidth,offsetHeight
  • clientLeft,clientTop
  • scrollLeft,scrollTop
  • offsetLeft,offsetTop

1. clientWidth,clientHeight

clientWidth,clientHeight表示对象内容的可视区的宽度,不包括滚动条和边框,会随对象显示大小的变化而改变。

上图中,我给el-scrollbar__view这个div增加了10px的红色边框,整个div的实际高度,宽度变成了3452px,1920px,观察clientWidth,clientHeight的值是3432px,1900px,并没有包含边框和滚动条的宽度。

2. scrollWidth,scrollHeight

scrollWidth,scrollHeight表示对象的实际内容的宽度,不包括边框(但是包括滚动条),会随对象中内容超过可视区后而变大。

 

上图中,我还是给el-scrollbar__view这个div增加了10px的红色边框,整个div的实际高度,宽度变成了3452px,1920px,观察scrollWidth,scrollHeight的值是3432px,1900px,并没有包含边框的宽度。

3. offsetWidth,offsetHeight

offsetWidth,offsetHeight表示对象整体的实际宽度,包括滚动条和边框,会随对象显示大小的变化而改变。

 上图中,我还是给el-scrollbar__view这个div增加了10px的红色边框,整个div的实际高度,宽度变成了3452px,1920px,观察scrollWidth,scrollHeight的值仍然是3452px,1920px,包含滚动条和边框。

4. clientLeft,clientTop

clientLeft,clientTop表示对象边框的宽度。

 上图中,我还是给el-scrollbar__view这个div增加了10px的红色边框,观察clientLeft, clientTop均为10px。

5. scrollLeft,scrollTop

scrollLeft,scrollTop表示对象的显示(可见)的内容与该对象实际的内容的距离。

 上图中,我们给content这个section设置了宽高均是300px,并设置显示滚动条,将滚动条拖动一部分,观察scrollLeft,scrollTop的值分别是164px,204px,这对应着当前内容距离原来实际内容的距离(假设蓝色框是实际内容的距离)。

6. offsetLeft,offsetTop

offsetLeft,offsetTop表示对象边框的外边缘距离与已定位的父容器(offsetparent)的内边距离(不包括元素的边框和父容器的边框)。

 
上图中,el-dialog这个div距离已定位的父容器(这里是el-dialog__wrapper)的宽高分别是672px,61px,与offsetLeft,offsetTop值一致。
 
 

我们给el-dialog__wrapper加上一个20px的黄色边框,给el-dialog加上一个10px的蓝色边框,再来观察offsetLeft,offsetTop的值,发现在计算时,是从黄色边框的内边距到蓝色边框的外边距,不包括边框。

7. coding

明确上述概念之后,我们来着手写代码,先说下我的业务场景。

有一个dialog弹框,弹框的背景并不是全屏的,只在除header,sidebar的地方显示,要求拖拽dialog弹框不能超过背景。

我们在main.js同级目录创建directives.js,具体代码如下

 1 import Vue from 'vue';
2
3 // v-dialogDrag 弹窗拖拽
4 Vue.directive('dialogDrag', {
5 bind(el, binding, vnode, oldVnode) {
6 const dialogHeaderEl = el.querySelector('.el-dialog__header');
7 const dragDom = el.querySelector('.el-dialog');
8 dialogHeaderEl.style.cursor = 'move';
9 // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
10 const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
11 dialogHeaderEl.onmousedown = (e) => {
12 console.log('屏幕高度', document.documentElement.clientHeight);
13 console.log('弹窗高度', dragDom.offsetHeight);
14 // 鼠标按下,获取鼠标在盒子内的坐标
15 const disX = e.clientX - dialogHeaderEl.offsetLeft;
16 const disY = e.clientY - dialogHeaderEl.offsetTop;
17 // 获取到的值带px 正则匹配替换
18 let styL;
19 let styT;
20 // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
21 if (sty.left.includes('%')) {
22 styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
23 styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
24 } else {
25 styL = +sty.left.replace(/\px/g, '');
26 styT = +sty.top.replace(/\px/g, '');
27 }
28 // 鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标就是模态框的left和top值
29 document.onmousemove = function(e) {
30 // 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
31 const l = e.clientX - disX;
32 const t = e.clientY - disY;
33
34 let finallyL = l + styL;
35 let finallyT = t + styT;
36
37 // 边界值判定 注意clientWidth scrollWidth区别 要减去之前的top left值
38 let limitL = (document.documentElement.clientWidth - dragDom.clientWidth) / 2;
39 if (finallyL < -limitL) {
40 finallyL = -limitL;
41 } else if (finallyL > limitL) {
42 finallyL = limitL;
43 }
44 let limitT = document.documentElement.clientHeight * 15 / 100;
45 let limitB = document.documentElement.clientHeight - dragDom.clientHeight - limitT;
46 if (finallyT < -limitT) {
47 finallyT = -limitT;
48 } else if (finallyT > limitB) {
49 finallyT = limitB;
50 }
51 // 移动当前元素
52 dragDom.style.left = `${finallyL}px`;
53 dragDom.style.top = `${finallyT}px`;
54 };
55 document.onmouseup = function(e) {
56 document.onmousemove = null;
57 document.onmouseup = null;
58 };
59 };
60 }
61 });

参考网址:https://www.jianshu.com/p/c3ce06c423af?tdsourcetag=s_pctim_aiomsg

简单实现el-dialog的拖拽功能的更多相关文章

  1. 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽

    前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...

  2. 移动端多个DIV简单拖拽功能

    移动端多个DIV简单拖拽功能. 这个demo与之前写的一个例子差不了多少,只是这个多了一层遍历而已. <!DOCTYPE html> <html lang="en" ...

  3. 使用 vue3 的自定义指令给 element-plus 的 el-dialog 增加拖拽功能

    element-plus 提供的 el-dialog 对话框功能非常强大,只是美中不足不能通过拖拽的方式改变位置,有点小遗憾,那么怎么办呢?我们可以通过 vue 的自定义指令来实现一个可以拖拽的对话框 ...

  4. vue实现element-ui对话框可拖拽功能

    element-ui对话框可拖拽及边界处理 应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案.很多大神给出的代码是没有解 ...

  5. 实现element-ui对话框可拖拽功能

    element-ui对话框可拖拽及边界处理 应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案.很多大神给出的代码是没有解 ...

  6. RCP:拖拽功能的实现 Drag and Drop

    SWT中的拖拽是使用的org.eclipse.swt.dnd. 有三个需要密切注意的类: 1.DragSource 2.DropTarget 3.Transfer DragSource封装了需要被拖拽 ...

  7. js实现登陆页面的拖拽功能

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>登 ...

  8. duilib中控件拖拽功能的实现方法(附源码)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...

  9. React Editor 应用编辑器(1) - 拖拽功能剖析

    这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...

  10. 使用NGUI实现拖拽功能(拼图小游戏)

    上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...

随机推荐

  1. 吉特日化MES & Redis 运行远程访问的配置

    在吉特日化MES系统部署实施过程中,经常需要配置Redis需要运行远程IP访问Redis.使用Redis的目的主要是为了解决缓存的问题,同时解决打印过程中推送数据的问题. 一. Redis 的安装目录 ...

  2. HTTP 代理服务器的设计与实现(C++)

    实验内容 设计并实现一个基本 HTTP 代理服务器.要求在指定端口(例如 8080)接收来自客户的 HTTP 请求并且根据其中的 URL 地址访问该地址 所指向的 HTTP 服务器(原服务器),接收 ...

  3. WinForm如何将子控件插入FlowLayoutPanel开始位置

    需求描述 动态将控件插入到FlowLayoutPanel控件的开始位置 实现方案 将控件添加到FlowLayoutPanel的Controls集合中,默认插到末尾 使用SetChildIndex方法更 ...

  4. Java 在Excel中添加筛选器并执行筛选

    以下内容介绍通过Java程序在Excel添加筛选器并执行筛选.程序需要使用Excel工具类库Free Spire.XLS for Java,本文中使用的是免费版,可在官网下载jar包,解压导入jar文 ...

  5. 听6位专家畅谈AI大模型落地实践:场景和人才是关键

    本文分享自华为云社区<听6位专家畅谈AI大模型落地实践:场景和人才是关键>,作者:华为云社区精选. 随着人工智能技术的不断突破,越来越多的行业开始应用AI技术来提高效率.降低成本.改善用户 ...

  6. 【华为云技术分享】STM32L476移植华为LiteOS系列教程(二)---开发前准备

    在进行移植华为LiteOS开发工作之前,我们是需要提前做一些准备工作,如:开发工具.环境.源码等相关事宜. 一.准备开发工具 STM32CubeMX用于生成工程文件:STM32CubeMX下载地址 I ...

  7. 重磅更新!Sermant 1.2.0 release版本新特性速览

    本文分享自华为云社区<重磅更新!Sermant 1.2.0 release版本新特性速览>,作者:华为云开源. 10月,Sermant社区正式发布了1.2.0 release版本,距离上一 ...

  8. SARIF:DevSecOps工具与平台交互的桥梁

    摘要:静态扫描工具融入在DevSecOps的开发过程中,对提高产品的整体的安全水平发挥着重要的作用.为了获取安全检查能力覆盖的最大化,开发团队通常会引入多个安全扫描工具.为了降低各种分析工具的结果汇总 ...

  9. 传统数据库改造难?华为云GaussDB“五心”解决

    摘要:快来看看华为云GaussDB奉上的"五心"诚意吧~ 本文分享自华为云社区<传统数据库改造难?华为云GaussDB"五心"解决>,作者: Gau ...

  10. Excel 查找替换 -- 快速填充

    单元格匹配,这样就不会把 70 的 0 替换成 7零 了 Ctrl + E 快速填充 一列变多行 快速填充 1. 快速拆分数据 一列数据中包含了姓名和手机号码,这时你需要进行数据拆分,快速填充可以实现 ...