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字符串浏览器兼容问题分析
Dec 01 Javascript
Python脚本后台运行的几种方式
Mar 09 Javascript
jquery中ajax处理跨域的三大方式
Jan 05 Javascript
animate 实现滑动切换效果【实例代码】
May 05 Javascript
遍历json获得数据的几种方法小结
Jan 21 Javascript
微信小程序 滚动到某个位置添加class效果实现代码
Apr 19 Javascript
vue实现简单的MVVM框架
Aug 05 Javascript
微信小程序网络封装(简单高效)
Aug 06 Javascript
vue debug 二种方法
Sep 16 Javascript
Vue从TodoList中学父子组件通信
Feb 05 Javascript
vue仿淘宝滑动验证码功能(样式模仿)
Dec 10 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
May 11 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实现的购物车类实例
2015/06/17 PHP
php抽象方法和抽象类实例分析
2016/12/07 PHP
jQuery 改变CSS样式基础代码
2010/02/11 Javascript
基于jquery的气泡提示效果
2010/05/31 Javascript
javaScript 利用闭包模拟对象的私有属性
2011/12/29 Javascript
自动最大化窗口的Javascript代码
2013/05/22 Javascript
js与jQuery 获取父窗、子窗的iframe
2013/12/20 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
2014/01/03 Javascript
iframe窗口高度自适应的实现方法
2014/01/08 Javascript
js使用DOM操作实现简单留言板的方法
2015/04/10 Javascript
Bootstrap基本插件学习笔记之Alert警告框(20)
2016/12/08 Javascript
Vue.Js中的$watch()方法总结
2017/03/23 Javascript
vue双向绑定简要分析
2017/03/23 Javascript
JS去掉字符串前后空格、阻止表单提交的实现代码
2017/06/08 Javascript
JS抛物线动画实例制作
2018/02/24 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
2018/12/24 Javascript
Angular8路由守卫原理和使用方法
2019/08/29 Javascript
layui当点击文本框时弹出选择框,显示选择内容的例子
2019/09/02 Javascript
vue父子模板传值问题解决方法案例分析
2020/02/26 Javascript
python转换摩斯密码示例
2014/02/16 Python
Python中MySQL数据迁移到MongoDB脚本的方法
2016/04/28 Python
PyQt5每天必学之滑块控件QSlider
2018/04/20 Python
关于Python 的简单栅格图像边界提取方法
2019/07/05 Python
Python小整数对象池和字符串intern实例解析
2020/03/21 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
python dict乱码如何解决
2020/06/07 Python
小学生暑假感言
2014/02/06 职场文书
私人会所最新创业计划书范文
2014/03/24 职场文书
艺术设计专业求职自荐信
2014/05/19 职场文书
超越自我演讲稿
2014/05/21 职场文书
2014年招生工作总结
2014/11/26 职场文书
党支部综合考察意见
2015/06/01 职场文书
windows安装python超详细图文教程
2021/05/21 Python
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python
Ruby处理YAML和json数据
2022/04/18 Ruby
Hive HQL支持2种查询语句风格
2022/06/25 数据库