简单实现el-dialog的拖拽功能
首先还是要明确几个概念,这里通过修改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表示对象整体的实际宽度,包括滚动条和边框,会随对象显示大小的变化而改变。
4. clientLeft,clientTop
clientLeft,clientTop表示对象边框的宽度。
5. scrollLeft,scrollTop
scrollLeft,scrollTop表示对象的显示(可见)的内容与该对象实际的内容的距离。
6. offsetLeft,offsetTop
offsetLeft,offsetTop表示对象边框的外边缘距离与已定位的父容器(offsetparent)的内边距离(不包括元素的边框和父容器的边框)。
我们给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的拖拽功能的更多相关文章
- 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽
前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...
- 移动端多个DIV简单拖拽功能
移动端多个DIV简单拖拽功能. 这个demo与之前写的一个例子差不了多少,只是这个多了一层遍历而已. <!DOCTYPE html> <html lang="en" ...
- 使用 vue3 的自定义指令给 element-plus 的 el-dialog 增加拖拽功能
element-plus 提供的 el-dialog 对话框功能非常强大,只是美中不足不能通过拖拽的方式改变位置,有点小遗憾,那么怎么办呢?我们可以通过 vue 的自定义指令来实现一个可以拖拽的对话框 ...
- vue实现element-ui对话框可拖拽功能
element-ui对话框可拖拽及边界处理 应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案.很多大神给出的代码是没有解 ...
- 实现element-ui对话框可拖拽功能
element-ui对话框可拖拽及边界处理 应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案.很多大神给出的代码是没有解 ...
- RCP:拖拽功能的实现 Drag and Drop
SWT中的拖拽是使用的org.eclipse.swt.dnd. 有三个需要密切注意的类: 1.DragSource 2.DropTarget 3.Transfer DragSource封装了需要被拖拽 ...
- js实现登陆页面的拖拽功能
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>登 ...
- duilib中控件拖拽功能的实现方法(附源码)
转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...
- React Editor 应用编辑器(1) - 拖拽功能剖析
这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...
- 使用NGUI实现拖拽功能(拼图小游戏)
上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...
随机推荐
- Http的演进
Http的演进 Http在1.1版本之前具有无状态的特点,每次请求都需要通过TCP三次握手四次挥手与服务器重新建立连接.比如某个客户端在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户请求 ...
- [python][图像切割]给定手写数字图片完成数字切割
import torch import torch.nn as nn from torchvision import transforms from PIL import Image, ImageOp ...
- Rong晔大佬教程学习(1):背景与项目设计目标
riscv实际上是一种ISA的指令集,而处理器的设计的基本结构是不变的(如下所示),其区别在于所选用的指令集的类型,一般有ARM.RISCV.MIPS等,采用了不同的引擎,那么车的外观.系统等也会随之 ...
- Hudi 在 vivo 湖仓一体的落地实践
作者:vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下,vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能.主要应用在流批同源.实时链路优化及宽表拼接等业务场景 ...
- 微服务项目-小Q视频网
1.后台管理系统(更新中...) (1)讲师列表 (2)添加讲师 (3)导入课程分类 (4)课程分类列表 其他功能就不一一截图了,后台详细功能如下 2.前台会员系统(更新中...) (1)前台的技术栈 ...
- 【Python微信机器人】第六篇:优化使用方式,可pip安装
优化内容 这篇不聊技术点,说一下优化后的Python机器人代码怎么使用,优化内容如下: 将hook库独立成一个库,发布到pypi,可使用pip安装 将微信相关的代码发布成另一个库,也可以pip安装 g ...
- 解析$nextTick魔力,为啥大家都爱它?
1.为什么需要使用$nextTick? 首先我们来看看官方对于$nextTick的定义: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 由于vu ...
- django查询-列延迟加载only()、defer()
这玩意和sqlalchemy的几乎一样. only():只加载给定的列,其他列只有在使用时会发起二次查询 defer():不加载指定的列,刚好和only()相反. 实例: >>> r ...
- Bazel 如何生成 clangd/clang-tidy 所需的 compile_commands.json
VSCode 中如何使用 clang-tidy 安装 clangd 插件 禁用 ms-cpp 插件(VSCode 会自动提示有冲突) 生成 clangd 所需的 compile_commands.js ...
- Luogu P1654 概率DP
原题链接 题意 我们面前有一个长度为\(N\)的01序列,位置 \(a_i\) 有 \(p_i\) 的概率是1,否则为0. 序列中,一段长为 \(x\) 的连续1会带来 \(x^3\) 的加分(这段全 ...