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 相关文章推荐
js资料prototype 属性
Mar 13 Javascript
基于JQuery实现相同内容合并单元格的代码
Jan 12 Javascript
不使用XMLHttpRequest实现异步加载 Iframe和script
Oct 29 Javascript
js实现文字在按钮上滚动的方法
Aug 20 Javascript
限制只能输入数字的实现代码
May 16 Javascript
Bootstrap编写一个兼容主流浏览器的受众巨幕式风格页面
Jul 01 Javascript
最简单纯JavaScript实现Tab标签页切换的方式(推荐)
Jul 25 Javascript
利用vue实现模态框组件
Dec 19 Javascript
不得不看之JavaScript构造函数及new运算符
Aug 21 Javascript
对Vue2 自定义全局指令Vue.directive和指令的生命周期介绍
Aug 30 Javascript
iview实现select tree树形下拉框的示例代码
Dec 21 Javascript
如何在微信小程序中使用骨架屏的步骤
Jun 12 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验证码(支持中文)
2007/02/14 PHP
某大型网络公司应聘时的笔试题目附答案
2008/03/27 PHP
PHP屏蔽蜘蛛访问代码及常用搜索引擎的HTTP_USER_AGENT
2013/03/06 PHP
PHP实现定时执行任务的方法
2014/10/05 PHP
Zend Framework教程之动作的基类Zend_Controller_Action详解
2016/03/07 PHP
PHP简单判断字符串是否包含另一个字符串的方法
2016/03/25 PHP
基于jquery的当鼠标滚轮到最底端继续加载新数据思路分享(多用于微博、空间、论坛 )
2011/10/10 Javascript
点击隐藏页面左栏或右栏实现js代码
2013/04/01 Javascript
js调用图片隐藏&amp;显示实现代码
2013/09/13 Javascript
在Google 地图上实现做的标记相连接
2015/01/05 Javascript
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
每天一篇javascript学习小结(RegExp对象)
2015/11/17 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
2016/02/24 Javascript
全面了解javascript三元运算符
2016/06/27 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
2017/03/08 Javascript
原生JS实现 MUI导航栏透明渐变效果
2017/11/07 Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
2019/01/18 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
js实现固定区域内的不重叠随机圆
2019/10/24 Javascript
[39:07]LGD vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
Python中join和split用法实例
2015/04/14 Python
Python基础学习之类与实例基本用法与注意事项详解
2019/06/17 Python
Python生成六万个随机,唯一的8位数字和数字组成的随机字符串实例
2020/03/03 Python
TensorFlow使用Graph的基本操作的实现
2020/04/22 Python
基于Python脚本实现邮件报警功能
2020/05/20 Python
Python中格式化字符串的四种实现
2020/05/26 Python
Django微信小程序后台开发教程的实现
2020/06/03 Python
Python3与fastdfs分布式文件系统如何实现交互
2020/06/23 Python
pandas参数设置的实用小技巧
2020/08/23 Python
罗德与泰勒百货官网:Lord & Taylor
2016/08/12 全球购物
阿迪达斯希腊官方网上商店:adidas希腊
2019/04/06 全球购物
中海讯通笔试题
2015/09/15 面试题
体育专业大学生职业生涯规划范文:打造自己的运动帝国
2014/09/12 职场文书
小学数学继续教育研修日志
2015/11/13 职场文书
MySQL外键约束(FOREIGN KEY)案例讲解
2021/08/23 MySQL