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 19 Javascript
JQuery中对Select的option项的添加、删除、取值
Aug 25 Javascript
js实现分享到随页面滚动而滑动效果的方法
Apr 10 Javascript
Angular 2.x学习教程之结构指令详解
May 25 Javascript
JavaScript取得gridview中获取checkbox选中的值
Jul 24 Javascript
BootStrap模态框和select2合用时input无法获取焦点的解决方法
Sep 01 Javascript
React实践之Tree组件的使用方法
Sep 30 Javascript
Vue 开发音乐播放器之歌手页右侧快速入口功能
Aug 08 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
Apr 30 Javascript
React+TypeScript+webpack4多入口配置详解
Aug 08 Javascript
vue 函数调用加括号与不加括号的区别
Oct 29 Javascript
JavaScript严格模式不支持八进制的问题讲解
Nov 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读取flv文件的播放时间长度
2009/09/03 PHP
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
适合PHP初学者阅读的4本经典书籍
2016/09/23 PHP
利用PHP获取网站访客的所在地位置
2017/01/18 PHP
PHP实现正则表达式分组捕获操作示例
2018/02/03 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
2020/02/29 PHP
Javascript YUI 读码日记之 YAHOO.util.Dom - Part.2 0
2008/03/22 Javascript
浅谈Nodejs观察者模式
2015/10/13 NodeJs
简单总结JavaScript中的String字符串类型
2016/05/26 Javascript
Bootstrap Navbar Component实现响应式导航
2016/10/08 Javascript
Bootstrap CSS布局之代码
2016/12/17 Javascript
JavaScript实现移动端轮播效果
2017/06/06 Javascript
JS模拟超市简易收银台小程序代码解析
2017/08/18 Javascript
webpack配置之后端渲染详解
2017/10/26 Javascript
angular 未登录状态拦截路由跳转的方法
2018/10/09 Javascript
基于three.js实现的3D粒子动效实例代码
2019/04/09 Javascript
微信小程序3D轮播实现代码
2019/09/19 Javascript
JavaScript闭包原理与用法学习笔记
2020/05/29 Javascript
用vue写一个日历
2020/11/02 Javascript
js异步接口并发数量控制的方法示例
2020/11/22 Javascript
浅谈Python中的数据类型
2015/05/05 Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
2018/04/27 Python
python3.X 抓取火车票信息【修正版】
2018/06/19 Python
深入浅析Python科学计算库Scipy及安装步骤
2019/10/12 Python
Python读取excel文件中带公式的值的实现
2020/04/17 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
使用python创建Excel工作簿及工作表过程图解
2020/05/27 Python
Pandas的数据过滤实现
2021/01/15 Python
CSS3中Transform动画属性用法详解
2016/07/04 HTML / CSS
servlet面试题
2012/08/20 面试题
竞选大队长演讲稿
2014/04/29 职场文书
民事诉讼代理委托书
2014/10/08 职场文书
2014年局领导班子自身建设情况汇报
2014/11/21 职场文书
2014年保洁工作总结
2014/11/24 职场文书
2015初中政治教学工作总结
2015/07/21 职场文书
入党积极分子培养联系人意见
2015/08/12 职场文书