Vue自定义指令实现element-ui dialog拖拽调整位置和窗口大小

2023-11-12

实现element-ui dialog拖拽调整位置和窗口大小

前言

本文主要记录给element-ui dialog添加可拖拽位置及可拖拽宽高的功能的整个过程(部分代码来自网络参考)。

自定义指令

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__wrapper')
    dialogHeaderEl.style.cursor = 'move'
    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)

    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft
      const disY = e.clientY - dialogHeaderEl.offsetTop

      // 获取到的值带px 正则匹配替换
      let styL, styT

      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if (sty.left.includes('%')) {
        styL = +document.body.clientWidth * (+sty.left.replace(/%/g, '') / 100)
        styT = +document.body.clientHeight * (+sty.top.replace(/%/g, '') / 100)
      } else {
        styL = +sty.left.replace(/px/g, '')
        styT = +sty.top.replace(/px/g, '')
      }

      document.onmousemove = function (e) {
        // 通过事件委托,计算移动的距离
        const l = e.clientX - disX
        const t = e.clientY - disY

        // 移动当前元素
        dragDom.style.left = `${l + styL}px`
        // 判断弹窗位置,防止弹窗头部移出可视区
        dragDom.style.top = `${(t + styT) < 0 ? 0 : t + styT}px`
      }

      document.onmouseup = function (e) {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
})

// v-dialogDragWidth: 弹窗宽度拖大 拖小
Vue.directive('dialogDragWidth', {
  bind (el, binding, vnode, oldVnode) {
    const dragDom = binding.value.$el
    el.style.cursor = 'se-resize'
    el.onmousedown = (e) => {
      // 鼠标按下,在原来页面上增加透明遮罩,防止部分元素例如iframe监听不到鼠标事件
      const mask = document.createElement('div')
      mask.setAttribute('style', 'position:fixed;top:0px;bottom:0px;left:0px;right:0px;background:rgba(0,0,0,0)')
      document.body.appendChild(mask)
      // 计算当前元素距离可视区的距离
      const disX = e.clientX - el.offsetLeft
      const disY = e.clientY - el.offsetTop
      document.body.onmousemove = function (e) {
        e.preventDefault() // 移动时禁用默认事件

        // 通过事件委托,计算移动的距离
        const l = e.clientX - disX
        const h = e.clientY - disY
        dragDom.style.width = `${l}px`
        // 判断弹窗高度,防止用于拖动的点移出可视区
        dragDom.style.height = `${h > document.body.offsetHeight ? document.body.offsetHeight : h}px`
      }
      document.body.onmouseup = function (e) {
        document.body.removeChild(mask) // 移除mask遮罩
        document.body.onmousemove = null
        document.body.onmouseup = null
      }
    }
  }
})

具体应用

<!-- 拖拽整个弹出层,保证窗口底下的页面仍然可操作-->
<div id="dialog" v-dialogDrag >
          <el-dialog
              ref="dialog__wrapper"
              title="弹窗"
              :visible.sync="dialogVisible"
              :modal="false"
              :close-on-click-modal="false"
              center>
            <div class="dialog-body">
   			  <!-- 弹窗内容 -->
            </div>
            <!--用于拖拽窗口大小的点(位于窗口右下角)-->
            <div class="pointRB" v-dialogDragWidth="$refs.dialog__wrapper"></div>
          </el-dialog>
        </div>
#dialog{
      ::v-deep.el-dialog__wrapper{
        right: unset;
        bottom: unset;
        height: 600px;
        .el-dialog .el-dialog__body{
          position: relative;
          .pointRB{
            width: 5px;
            height: 5px;
            position: absolute;
            right: 0;
            bottom: 0;
            z-index: 2;
          }
        }
      }
    }

注意点

1.为保证窗口底下的页面仍然可操作,.el-dialog__wrapper样式的right和bottom属性必须unset,只保留left和top属性
2.监听拖拽调整大小时,若在特殊元素(base, bdo, br, head, html, iframe, meta, param, script, style 和title)上松开鼠标,无法监听onmouseup 事件
3.示例中可实现窗口大小调整的只有窗口右下角。
4.需要保证用于监听的部分(弹窗头部及右下角的point元素在可视区内)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue自定义指令实现element-ui dialog拖拽调整位置和窗口大小 的相关文章

  • React 组件渲染被调用两次而不改变状态

    我正在渲染一个简单的反应组件 其中没有设置状态和道具 我在渲染函数中仅将文本记录到控制台一次 但它被记录了两次 rendering counter rendering counter 下面是counter js组件的代码 import Re
  • 如何使用 Shopify API 将商品添加到购物车

    我正在使用 Shopify API 开发自定义网络应用程序 这里的想法是使用应用程序作为独家店面 只需向 Shopify API 发出请求 我已在我的 Shopify 帐户中设置了一个私人应用程序来执行此操作 我从 api 提取产品没有问题
  • Node + now.js + 模型-视图-控制-模式

    我正在使用基于 MVC 模式 模板和 PHP 类 的论坛软件 页面如下所示 domain com index php page Test 我想使用 Node 和 now js 在一个页面 domain com index php page
  • 使用智能菜单jquery打印json

    menu name Computers children name Notebook children name Apple name Windows name Tablets children name Apple name Androi
  • ScrollTop 在 Chrome/Safari 中不起作用

    我的网站上有一个循环内的表单 当有人提交表单时 查询字符串会添加到 URL 中 例如 updated 111 然后 我的 JQuery 脚本检查数字的 url 并在提交表单并重新加载页面后滚动到该 div 该脚本在 Firefox 中运行良
  • 方向改变后的javascript最大视口高度Android和iOS

    目标 查找设备的最大视口高度 包括设备的空间address bar这样我们就可以动态调整 min body 的大小并将内容向上推 问题 移动浏览器处理方向状态的方式不同 方向变化时更新 DOM 属性的方式也不同 使用 JavaScript
  • Chart.js - 如何将数组集合推入数据集

    我一直在尝试多种方法将数组集合推送到数据集中 任何人都可以帮助我根据下面的代码将数组推入堆积图表中 这是例子 Codepen 堆叠栏 https codepen io narendrajadhav pen abzpWam JavaScrip
  • 将其作为参数传递给 addEventListener()

    我想添加change一组复选框的事件 我如何访问this在我的事件函数中 这样当我执行事件时我可以访问复选框的值 这是我当前的代码 var checkboxes document getElementsByClassName cb Arra
  • 按日期对 JSON 进行排序

    我知道这一定相对简单 但我有一个 JSON 数据集 我想按日期排序 到目前为止 我每次都会遇到问题 现在我将日期存储为this lastUpdated 如果有帮助的话 我可以访问 jquery 但我意识到 sort 是本机 JS 提前致谢
  • jQuery 中如何判断 JSON 对象是否为空

    我有以下 JSON meta limit 20 next null offset 0 previous null total count 0 objects 我对对象感兴趣 我想知道对象是否为空并显示警报 像这样的东西 success fu
  • 我什么时候应该使用内联和外部 Javascript?

    我想知道什么时候应该包含外部脚本或将它们与 html 代码内联编写 就性能和易于维护而言 这方面的一般做法是什么 真实场景 我有几个需要客户端表单验证的 html 页面 为此 我使用了一个包含在所有这些页面上的 jQuery 插件 但问题是
  • Facebook 登录无法在移动浏览器中使用

    我使用 react facebook login 在我的网站中实现了 facebook 登录module https github com keppelen react facebook login 我在 ComponentDidMount
  • 元素在主体内找不到足够的空间 - JavaScript 样式

    相关信息 该页面包含两个元素 An
  • 如何从Web JavaScript应用程序获取桌面C#程序中的变量

    我遇到一个问题 有两个应用程序 一种是 C 中的桌面应用程序 另一种是 javascript 中的 Web 应用程序 运行桌面应用程序中的一些变量或信息需要传输到Web应用程序 有谁知道如何解决这个问题 有人愿意提供更多细节来解决这个问题吗
  • 根据数据更改图例颜色高图表

    我可以根据数据动态设置列的颜色 但无法弄清楚如何更改图例中的颜色 请注意 jsfiddle 最新的条形图是绿色的 但图例是蓝色的 有没有办法改变列颜色也会改变图例颜色 这是我用于列颜色的代码 jsfiddle http jsfiddle n
  • D3 时间解析返回 null

    根据此页面上的说明 https github com mbostock d3 wiki Time Formatting https github com mbostock d3 wiki Time Formatting我正在尝试解析 ISO
  • Bootstrap 3 - 模态背景不会根据模态对话框的高度调整大小?

    我将一个表单放入模式中 并尝试在用户触发单选按钮时显示表单的一些隐藏字段 显示隐藏字段后 模态自动重新缩放的高度 但模态背景的高度不能用作模态对话框 我该如何解决它 div class modal fade div class modal
  • Firefox 和 Chrome 为 offsetTop 提供了不同的值

    我试图相对于输入字段定位一个跨度元素 让我们称之为 工具提示跨度 为此 我将工具提示跨度和输入字段包装在另一个跨度元素中 我们称之为 包装器跨度 该元素具有position relative 然后我设置position absolute在工
  • 检测图像是否损坏或损坏

    我需要以编程方式检查用户在我的应用程序上选择作为壁纸的图像是否已损坏或损坏 基本上我为用户提供了选择自己的图像作为壁纸的选项 现在 当图像加载时 我只想检查它是否已损坏 如果您正在寻找 PHP 解决方案而不是 javascript 解决方案
  • python 函数返回 javascript date.getTime()

    我正在尝试创建一个简单的 python 函数 它将返回与 javascript 相同的值new Date getTime 方法 如所写here http www w3schools com js js dates asp javascrip

随机推荐

  • 2021斯坦福CS224N课程笔记~2

    2 Neural Classifiers 2 1本篇内容覆盖 word2vec与词向量回顾 算法优化基础 计数与共现矩阵 GloVe模型 词向量评估 word senses 2 2 回顾 word2vec 的主要思想 2 2 1 主要步骤
  • Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime

    报错 在进行编译的时候运行到下面的错误 Node Sass does not yet support your current environment Windows 64 bit with Unsupported runtime 88 这
  • 芯片电源引脚的电容选择

    主要内容 参考如下 DC 100K 10uF以上的钽电容或铝电解 100K 10M 100nF 0 1uF 陶瓷电容 10M 100M 10nF 0 01uF 陶瓷电容 100M以上 1nF 0 001uF 陶瓷电容和PCB的地平面与电源平
  • ggplot2技巧书《R数据可视化手册》读书笔记:第二章 快速探索数据

    2 1绘制散点图 基础绘图 plot data x data y ggplot2 qplot data x data y 提前安装 加载ggplot2 qplot x y data 等价于 ggplot data aes x y geom
  • 医学图像分割--Stacked fully convolutional networks with multi-channel learning

    Stacked fully convolutional networks with multi channel learning application to medical image segmentation https link sp
  • c++基本使用(类的静态成员)

    c 基本使用 类的静态成员 静态成员属性 静态成员方法 类的静态成员包括 静态成员变量 静态成员函数 静态成员属性 用 static 关键字把类的成员变量声明为静态 表示它在程序中 不仅是对象 是共享的 静态成员使用类名加范围解析运算符 就
  • 【Dash搭建可视化网站】项目1:使用Dash创建简单网页

    项目1 使用Dash创建简单网页 项目1 使用Dash创建简单网页 1 1 官网示例 1 2 绘制简单网页的基本步骤 1 3 创建一个稍微有意思的页面 手动反爬虫 禁止转载 原博地址 https blog csdn net lys 828
  • Ansible 企业级自动化运维平台开发实战

    一 运维开发 普通的运维方式 使用Xshell或者脚本去操作服务器 运维开发的方式 可以实现把运维的工作Web化 运维开发优点 可以把运维工作简单化 运维工作规划化 运维开发 负责具体的产品的运维工作 同时也需要进行基本的开发 了解业务的痛
  • WPF之层级数据模板HierarchicalDataTemplate的使用

    WPF之层级数据模板HierarchicalDataTemplate的使用 1 HierarchicalDataTemplate List 2 HierarchicalDataTemplate XML 3 TreeView Hierarch
  • 基于Yolov5目标检测的物体分类识别及定位(一) -- 数据集原图获取与标注

    从本篇博客正式开始深度学习项目的记录 实例代码只会放通用的代码 数据集和训练数据也是不会全部放出 系列文章 基于Yolov5目标检测的物体分类识别及定位 一 数据集原图获取与标注 基于Yolov5目标检测的物体分类识别及定位 二 yolov
  • 一道简单的PV操作题

    这是川大操作系统的一道期末考试题 There is an cage and only one animal can be put into this cage The hunters can put tiger into the cage
  • Android自定义View的数独游戏

    Android自定义View的数独游戏 先说一下数独游戏的规则 在整个横坐标和纵坐标的9个格子上只能填土1 9的数字且不重复 在当前3 3 的格子上填入1 9数字且不重复 先给大家看效果图 项目思路 1 UI呈现 这个放在 GameView
  • exit函数及与return的区别

    通常情况 exit 0 表示程序正常 exit 1 exit 1 表示程序异常退出 exit 2 表示表示系统找不到指定的文件 用Error lookup可以查看 exit 结束当前进程 当前程序 在整个程序中 只要调用exit就结束 当前
  • [深度学习]Part1 Python高级Ch25 cnocr——【DeepBlue学习笔记】

    本文仅供学习使用 ocr入门包 具体的文字识别需了解其他内容 Python高级 Ch25 cnocr 25 cnocr 25 1 几个 简单 的例子 25 1 1 信用卡识别 25 1 2 文字截图识别 25 2 使用逻辑 25 cnocr
  • 网页打开软件显示无法连接服务器,Safari 浏览器无法打开网页怎么办

    Safari 浏览器打不开网页 因为无法连接到服务器怎么解决 在最近 我们使用苹果手机的 Safari 浏览器时 很多小伙伴都收到了打不开网页因为无法连接到服务器的提示 那怎么解决这种情况呢 下面就和小编一起来看看吧 1 网址已注销 禁用
  • ES6---新增数据类型Symbol

    es6新标 加入了新的数据类型Symbol与新的数据结构set map 他们各有特点 Symbol let a Symbol console log typeof a symbol js语言的数据类型再添一员 Symbol Symbol f
  • 基于注册中心如何实现全链路灰度

    1 为什么需要服务发现 2 微服务注册中心 3 基于注册中心如何实现全链路灰度 4 GRPC 如何结合注册中心 GRPC服务发现与全链路灰度 为什么需要服务发现 服务拆分 配置调用 如果有很多服务怎么办 服务注册 服务发现 注册中心的架构
  • 华为OD机试2022Q4【租车骑绿岛】

    之前想复杂了 其实很简单的一题 题目 租车骑绿岛 100分 部门组织绿岛骑行团建活动 租用公共双人自行车 每辆自行车最多坐两人 做最大载重M 给出部门每个人的体重 请问最多需要租用多少双人自行车 输入描述 第一行两个数字m n 分别代表自行
  • 如何安装PHP框架

    目录 什么是PHP框架 第一步 安装PHP依赖包 第二步 导入PHP相关包 第三步 解包并切换进指定目录 第四步 在PHP目录内编译安装 第五步 编译 第六步 拷贝配置文件进行编辑 第七步 修改时区 第八步 修改文件指定路径 第九步 将命令
  • Vue自定义指令实现element-ui dialog拖拽调整位置和窗口大小

    实现element ui dialog拖拽调整位置和窗口大小 前言 自定义指令 具体应用 注意点 前言 本文主要记录给element ui dialog添加可拖拽位置及可拖拽宽高的功能的整个过程 部分代码来自网络参考 自定义指令 impor