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


Posted in Javascript onAugust 17, 2018

element-ui对话框可拖拽及边界处理

应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案。很多大神给出的代码是没有解决边界问题的,但是不解决边界问题存在一个bug,拖到不可视区域后边再也拖不回来了,不信你们可以试试。

在实现的功能的情况下,封装成了js文件,然后再main.js中引入后可全局使用。

还是上代码吧

功能实现代码directives.js代码如下:

import Vue from 'vue';
 
// v-dialogDrag: 弹窗拖拽属性
Vue.directive('dialogDrag', {
  bind(el, binding, vnode, oldVnode) {
    const dialogHeaderEl = el.querySelector('.el-dialog__header');
    const dragDom = el.querySelector('.el-dialog');
    //dialogHeaderEl.style.cursor = 'move';
    dialogHeaderEl.style.cssText += ';cursor:move;'
    dragDom.style.cssText += ';top:0px;'
 
    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const sty = (function() {
        if (window.document.currentStyle) {
            return (dom, attr) => dom.currentStyle[attr];
        } else{
            return (dom, attr) => getComputedStyle(dom, false)[attr];
        }
    })()    
    
    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
      const disY = e.clientY - dialogHeaderEl.offsetTop;
      
      const screenWidth = document.body.clientWidth; // body当前宽度
        const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) 
        
        const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
        const dragDomheight = dragDom.offsetHeight; // 对话框高度
        
        const minDragDomLeft = dragDom.offsetLeft;
        const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
        
        const minDragDomTop = dragDom.offsetTop;
        const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
 
      
      // 获取到的值带px 正则匹配替换
      let styL = sty(dragDom, 'left');
      let styT = sty(dragDom, 'top');
 
      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if(styL.includes('%')) {
        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
        styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
      }else {
        styL = +styL.replace(/\px/g, '');
        styT = +styT.replace(/\px/g, '');
      };
      
      document.onmousemove = function (e) {
        // 通过事件委托,计算移动的距离 
                let left = e.clientX - disX;
                let top = e.clientY - disY;
                
                // 边界处理
                if (-(left) > minDragDomLeft) {
                    left = -(minDragDomLeft);
                } else if (left > maxDragDomLeft) {
                    left = maxDragDomLeft;
                }
                
                if (-(top) > minDragDomTop) {
                    top = -(minDragDomTop);
                } else if (top > maxDragDomTop) {
                    top = maxDragDomTop;
                }
 
        // 移动当前元素 
                dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
      };
 
      document.onmouseup = function (e) {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    } 
  }
})

在边界处理上,因为在我的项目中无法获取到body的高度(被这个折磨了好久),所以采取了获取可见区域高度,这里补充点知识

document.body.clientWidth //BODY对象宽度
document.body.clientHeight //BODY对象高度
document.documentElement.clientWidth //可见区域宽度
document.documentElement.clientHeight //可见区域高度

在main.js中引入

// 引入Dialog可拖拽,注意文件所在目录。目前尚未发现引入的先后关系,若有再补充
import './directives.js';

ue文件中使用:

在el-dialog标签中加入v-dialogDrag属性

<el-dialog v-dialogDrag></el-dialog>

具体使用便是这样,希望有人看到哈哈哈,当然主要还是想帮到大家。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript入门·对象属性方法大总结
Oct 01 Javascript
javascript之bind使用介绍
Oct 09 Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
Jul 05 Javascript
Javascript动画效果(3)
Oct 11 Javascript
ng-options和ng-checked在表单中的高级运用(推荐)
Jan 21 Javascript
jQuery实现遍历复选框的方法示例
Mar 06 Javascript
Vue2仿淘宝实现省市区三级联动
Apr 15 Javascript
angular使用md5,CryptoJS des加密的方法
Jun 03 Javascript
微信小程序 如何获取网络状态
Jul 26 Javascript
微信小程序实现蓝牙打印
Sep 23 Javascript
微信小程序 flexbox layout快速实现基本布局的解决方案
Mar 24 Javascript
js作用域及作用域链工作引擎
Jul 07 Javascript
原生JS实现的简单轮播图功能【适合新手】
Aug 17 #Javascript
layer.confirm取消按钮绑定事件的方法
Aug 17 #Javascript
LayerClose弹窗关闭刷新方法
Aug 17 #Javascript
详解vue移动端项目的适配(以mint-ui为例)
Aug 17 #Javascript
layui前端框架之table表数据的刷新方法
Aug 17 #Javascript
Vue登录注册并保持登录状态的方法
Aug 17 #Javascript
小程序清理本地缓存的方法
Aug 17 #Javascript
You might like
php中文字符截取防乱码
2008/03/28 PHP
php生成图形验证码几种方法小结
2013/08/15 PHP
PHP中使用memcache存储session的三种配置方法
2014/04/05 PHP
php获取文件名后缀常用方法小结
2015/02/24 PHP
PHP常用工具函数小结【移除XSS攻击、UTF8与GBK编码转换等】
2019/04/27 PHP
js getBoundingClientRect() 来获取页面元素的位置
2010/11/25 Javascript
用Javascript评估用户输入密码的强度实现代码
2011/11/30 Javascript
本地图片预览(支持IE6/IE7/IE8/Firefox3)经验总结
2013/03/25 Javascript
jQuery动态效果显示人物结构关系图的方法
2015/05/07 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
jQuery插件DataTable使用方法详解(.Net平台)
2016/12/22 Javascript
Bootstrap轮播图学习使用
2017/02/10 Javascript
BootStrap实现带关闭按钮功能
2017/02/15 Javascript
vue中如何引入jQuery和Bootstrap
2017/04/10 jQuery
jQuery实现拼图小游戏(实例讲解)
2017/07/24 jQuery
让nodeJS支持ES6的词法----babel的安装和使用方法
2017/07/31 NodeJs
js+html获取系统当前时间
2017/11/10 Javascript
ajax请求+vue.js渲染+页面加载的示例
2018/02/11 Javascript
vue项目打包上传github并制作预览链接(pages)
2019/04/19 Javascript
vue中axios实现数据交互与跨域问题
2019/05/12 Javascript
layui 弹出层回调获取弹出层数据的例子
2019/09/02 Javascript
vue实现学生信息管理系统
2020/05/30 Javascript
Vue的v-model的几种修饰符.lazy,.number和.trim的用法说明
2020/08/05 Javascript
[01:00:12]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第一场
2018/04/09 DOTA
Python列表append和+的区别浅析
2015/02/02 Python
python创建进程fork用法
2015/06/04 Python
浅析Python中元祖、列表和字典的区别
2016/08/17 Python
Python中属性和描述符的正确使用
2016/08/23 Python
用yum安装MySQLdb模块的步骤方法
2016/12/15 Python
不要用强制方法杀掉python线程
2017/02/26 Python
在Mac上删除自己安装的Python方法
2018/10/29 Python
python3爬虫中多线程的优势总结
2020/11/24 Python
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
艺术设计专业求职自荐信
2014/05/19 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
中学教师教学工作总结
2015/08/13 职场文书