elementUI 弹出框添加可自定义拖拽和拉伸功能,并处理边界问题
开发完后台管理系统的弹出框模块,被添加拖拽和拉伸功能,看了很多网上成熟的帖子引到项目里总有一点问题,下面是根据自己的需求实现的步骤:
首先在vue项目中创建一个js文件eg:dialog.js
import Vue from 'vue'
// v-dialogDrag: 弹窗拖拽属性
Vue.directive('dialogDrag', {
bind (el, binding, vnode, oldVnode) {
// 自定义属性,判断是否可拖拽
if (!binding.value) return
const dialogHeaderEl = el.querySelector('.el-dialog__header')
const dragDom = el.querySelector('.el-dialog')
dialogHeaderEl.style.cssText += ';cursor:move;'
dragDom.style.cssText += ';top:0px;' // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = (function () {
if (document.body.currentStyle) {
// 在ie下兼容写法
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')
// 为兼容ie
if (styL === 'auto') styL = '0px'
let styT = sty(dragDom, 'top') console.log(styL)
// 注意在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
}
return false
}
}
}) Vue.directive('dialogChange', {
bind (el, binding, vnode, oldVnode) {
// 自定义属性,判断是否可拉伸
if (!binding.value) return
const dragDom = el.querySelector('.el-dialog')
let dragMouse
// 在弹出框的右下角添加可拉伸标志 class='mouse'
for (let i = 0; i < dragDom.childNodes[2].childNodes.length; i++) {
if (dragDom.childNodes[2].childNodes[i].className === 'mouse') {
dragMouse = dragDom.childNodes[2].childNodes[i]
}
}
// 鼠标拖拽
dragMouse.onmousedown = (e) => {
// content区域
const content = dragDom.parentNode.parentNode.parentNode.parentNode
const disX = e.clientX - dragDom.offsetWidth
const disY = e.clientY - dragDom.offsetHeight document.onmousemove = function (e) {
e.preventDefault() // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
let width = e.clientX - disX
let height = e.clientY - disY if (width > content.offsetWidth && height < content.offsetHeight) {
dragDom.style.height = `${height}px`
} else if (width < content.offsetWidth && height > content.offsetHeight) {
dragDom.style.width = `${width}px`
} else if (width < content.offsetWidth && height < content.offsetHeight) {
dragDom.style.width = `${width}px`
dragDom.style.height = `${height}px`
}
}
document.onmouseup = function (e) {
document.onmousemove = null
document.onmouseup = null
}
return false
}
}
})
在main.js中引用
import './components/dialog'
dialog组件 代码中添加v-if为了让每次弹出框都不继承上一次的改变:
<el-dialog
v-if=dialog.dialogVisible
v-dialogDrag:{dialogDrag}=dialog.dialogDrag
v-dialogChange:{dialogChange}=dialog.dialogChange
ref="dialog__wrapper"
:close-on-click-modal="false"
:title=dialog.title
:visible.sync="dialog.dialogVisible"
:before-close="handleClose">
<div class="dialog-body">
<div class="line">
<slot name="content"></slot>
</div>
</div>
<slot slot="footer" class="dialog-footer"></slot>
</el-dialog>
在引用组件时, data返回一个:
dialog: {// dialog显示隐藏
dialogVisible: false,
dialogDrag: true, // 可拖拽
dialogChange: true, // 可拉伸
title: '详情'
}
elementUI 弹出框添加可自定义拖拽和拉伸功能,并处理边界问题的更多相关文章
- 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框
vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...
- jQuery 学习笔记3 点击弹出一个div并允许拖拽移动
这里我看了下http://qings.blog.51cto.com/4857138/998878/ 的文章,感谢他的分享. 首先我们有一个a标签和一个div,div默认是不显示的,当用户点击时改为显示 ...
- js自定义弹出框
js自定义弹出框: 代码如下 <html> <head><title>自定义弹出对话框</title> <style type ="te ...
- 自定义一个类似UIAlertView的弹出框
这个是和UIAlertView类似,但是可以自定义view的样式废话不多说,上代码: 首先第一步:创建一个继承自View的类如: #import <UIKit/UIKit.h> @clas ...
- UIPresentationController - iOS自定义模态弹出框
参考: https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/Definin ...
- 练习:javascript弹出框及地址选择功能,可拖拽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue之element-ui设置全局弹出框
这样的需求,在主要功能完成后,需要进行交互效果的完善,需要给请求api的时候添加一个加载中的一个弹出框.但是每个页面每个页面过的话,会很费时间和精力,这里我们可以采用element-ui中的服务式弹出 ...
- jquery实现自定义弹出框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- unity 之 自定义弹出框
一.弹出框的搭建: 布局如图:Message为整个父物体,并且添加UiMessage代码.panel为遮罩. MessageBox为整个提示框,Panel为标题,ok为确定按钮,cancel为取消按钮 ...
随机推荐
- django shell的基本使用
作者:python技术人 博客:https://www.cnblogs.com/lpdeboke/ 在日常工作再发中,经常需要测试一些对象.函数.类...等是否正确,但是如果整体运行项目特别麻烦,并且 ...
- Consul集群Server+Client模式
Consul集群Server+Client模式 架构示意图 只使用Consul的Server模式有以下2个问题: 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题. Serve ...
- docker添加加速器
通过 Docker 官方镜像加速,中国区用户能够快速访问最流行的 Docker 镜像.该镜像托管于中国大陆,本地用户现在将会享受到更快的下载速度和更强的稳定性,从而能够更敏捷地开发和交付 Docker ...
- 【洛谷p3958】奶酪
奶酪[题目链接] 题前废话不知道说啥了啊qwq(越来越沉默寡言) 好了看题: SOLUTION: 思路的话,大概是搜索,然后大概广搜??? 但是我们今天写深搜(也是听xcg大佬讲了以后的整理博) 首先 ...
- 原生JS代码实现随机产生一个16进制的颜色值
封装一个函数 function getColor() { var str = "#"; //一个十六进制的值的数组 var arr = ["0", " ...
- mybatis的if标签判断子类属性-There is no getter for property named 'export' in
1 <select id="findList" resultType="BndExport"> SELECT <include refid=& ...
- Oracle 11g+Windows10 x64安装、配置过程记录
备注:本想在自己电脑上安装个oracle练习用,但是害怕安装过程中出现问题,而oracle的卸载又是出了名的麻烦,所以用虚拟机搭建了一个跟本机一样的系统,同时记录下安装的每一步. 环境:windows ...
- VMware新加网卡NAT连接(内网)出现本机与虚拟机ping不通的问题
今新加网卡NAT连接,配置好之后始终出现eth1:link is not ready. 虚拟机与本机不能建立连接. 解决方案:windows里面打开服务开启VMware NAT Service,并关闭 ...
- OGG复制进程延迟不断增长
1.注意通过进程查找sql_id时,进程号要查询两次 2.杀进程的连接 https://www.cnblogs.com/kerrycode/p/4034231.html 参考资料 1.https:// ...
- 解决 INSTALL FAILED CONFLICTING PROVIDER
1.现象: 2.产生原因 INSTALL FAILED CONFLICTING PROVIDER 产生的原因通常是因为系统中已经安装的apk的provider中的authorities相同了,导致在安 ...