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 06 Javascript
javascript new fun的执行过程
Aug 05 Javascript
js输入框邮箱自动提示功能代码实现
Dec 10 Javascript
JavaScript函数节流概念与用法实例详解
Jun 20 Javascript
js发送短信倒计时的简单实现方法
Sep 08 Javascript
js实现仿购物车加减效果
Mar 01 Javascript
jquery实现搜索框功能实例详解
Jul 23 jQuery
JS使用cookie保存用户登录信息操作示例
May 30 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
Aug 01 Javascript
layui表格分页 记录勾选的实例
Sep 02 Javascript
JS实现横向轮播图(中级版)
Jan 18 Javascript
JavaScript 与 TypeScript之间的联系
Nov 27 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 IP转换整形(ip2long)的详解
2013/06/06 PHP
phalcon框架使用指南
2016/02/23 PHP
A标签触发onclick事件而不跳转的多种解决方法
2013/06/27 Javascript
jQuery事件绑定on()、bind()与delegate() 方法详解
2015/06/03 Javascript
JavaScript实现对下拉列表值进行排序的方法
2015/07/15 Javascript
jQuery简单实现提交数据出现loading进度条的方法
2016/03/29 Javascript
jQuery Ajax 上传文件处理方式介绍(推荐)
2016/06/30 Javascript
JavaScript实现水平进度条拖拽效果
2017/01/18 Javascript
bootstrap fileinput实现文件上传功能
2017/08/23 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
vue实现Excel文件的上传与下载功能的两种方式
2019/06/28 Javascript
Vue项目中使用better-scroll实现菜单映射功能方法
2019/09/11 Javascript
javascript跳转与返回和刷新页面的实例代码
2019/11/20 Javascript
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
python连接MySQL、MongoDB、Redis、memcache等数据库的方法
2013/11/15 Python
动感网页相册 python编写简单文件夹内图片浏览工具
2016/08/17 Python
Python程序员面试题 你必须提前准备!
2018/01/16 Python
Windows 8.1 64bit下搭建 Scrapy 0.22 环境
2018/11/18 Python
python requests 库请求带有文件参数的接口实例
2019/01/03 Python
用Python PIL实现几个简单的图片特效
2019/01/18 Python
python selenium登录豆瓣网过程解析
2019/08/10 Python
win10下安装Anaconda的教程(python环境+jupyter_notebook)
2019/10/23 Python
用python实现名片管理系统
2020/06/18 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
html5通过postMessage进行跨域通信的方法
2017/12/04 HTML / CSS
html5 canvas的绘制文本自动换行的示例代码
2018/09/17 HTML / CSS
挪威太阳镜和眼镜网上商城:SmartBuyGlasses挪威
2016/08/20 全球购物
Shopty西班牙:缝纫机在线销售
2018/01/26 全球购物
英国领先的露营和露营车品牌之一:OLPRO
2019/08/06 全球购物
照片礼物和装饰:MyPhoto
2019/11/02 全球购物
宾馆总经理岗位职责
2014/02/14 职场文书
餐厅执行经理岗位职责范本
2014/02/26 职场文书
美容院合作经营协议书
2014/10/10 职场文书
学生会个人总结范文
2015/02/15 职场文书
活动简报范文
2015/07/22 职场文书