el-dialog加放大缩小和可移动

1.js文件

import Vue from 'vue'
// v-dialogDrag: 弹窗拖拽
Vue.directive('dialogDrag', {
  bind(el, binding, vnode, oldVnode) {
    //初始非全屏 
    let isFullScreen = false;
    //当前宽高 
    let nowWidth = 0;
    let nowHight = 0;
    //当前顶部高度 
    let nowMarginTop = 0;

    const dialogHeaderEl = el.querySelector('.el-dialog__header')
    // 弹窗
    const dragDom = el.querySelector('.el-dialog')
    const changeBig = el.querySelector('.changeBig');
    const changeSmall = el.querySelector('.changeSmall');
    const minimizeBtn = el.querySelector('.minimizeBtn'); //最小化按钮
    const recover = el.querySelector('.recover'); //恢复
    const minimize = el.querySelector('.minimize'); //最小化
    const isminimize = el.querySelector('.isminimize'); //不是最小化
    dragDom.style.overflow = "auto";
    dialogHeaderEl.style.cursor = 'move';
    // 获取原有属性 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]
      }
    })()
    // 移动
    let moveDown = (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)
        // eslint-disable-next-line no-useless-escape
        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
        // eslint-disable-next-line no-useless-escape
        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
      }
    }
    dialogHeaderEl.onmousedown = moveDown;

    // 放大
    changeBig.onclick = (e) => {
      changeBig.style.display = 'none';
      changeSmall.style.display = 'block';
      nowHight = dragDom.clientHeight;
      nowWidth = dragDom.clientWidth;
      nowMarginTop = dragDom.style.marginTop;
      dragDom.style.left = 0;
      dragDom.style.top = 0;
      dragDom.style.height = "93VH";
      dragDom.style.width = "100VW";
      dragDom.style.marginTop = 0;
      isFullScreen = true;
      dialogHeaderEl.style.cursor = 'initial';
      dialogHeaderEl.onmousedown = null;
      el.querySelector('.historyList').style.height = '400px';
    }
    // 缩小
    changeSmall.onclick = (e) => {
      changeBig.style.display = 'block';
      changeSmall.style.display = 'none';
      dragDom.style.height = "auto";
      dragDom.style.width = nowWidth + 'px';
      // dragDom.style.marginTop = nowMarginTop; 
      dragDom.style.top = nowMarginTop;
      isFullScreen = false;
      dialogHeaderEl.style.cursor = 'move';
      dialogHeaderEl.onmousedown = moveDown;
      el.querySelector('.historyList').style.height = '120px';
    }
    // 最小化
    minimizeBtn.onclick = (e) => {
      minimize.style.display = 'block';
      isminimize.style.display = 'none';
      dragDom.style.width = '15%';
      dragDom.style.height = dialogHeaderEl.offsetHeight + 'px';
      dragDom.style.overflow = 'hidden';
      el.querySelector('.el-dialog__body').style.display = 'none';
      dialogHeaderEl.style.cursor = 'move';
      dialogHeaderEl.onmousedown = moveDown;
    }
    // 最小化恢复
    recover.onclick = (e) => {
      changeBig.style.display = 'block';
      changeSmall.style.display = 'none';
      dragDom.style.height = "auto";
      dragDom.style.width = '30%';
      dragDom.style.top = nowMarginTop;
      el.querySelector('.el-dialog__body').style.display = 'block';
      isFullScreen = false;
      dialogHeaderEl.style.cursor = 'move';
      dialogHeaderEl.onmousedown = moveDown;
      isminimize.style.display = 'block';
      minimize.style.display = 'none';
      el.querySelector('.historyList').style.height = '120px';
    }
  }
})

2.vue页面中引入
import '@/components/drag/index.js';

3.dialog弹框(外加一层dialogWrap类包裹)

<div class="dialogWrap">
      <el-dialog
        v-dialogDrag
        ref="zDialogRef"
        title="详情"
        :visible.sync="visible"
        :width="width"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        :show-close="false"
        :modal="false"
      >
        <div slot="title" class="medium bigbtn isminimize">
          <div class="lefts">
            <span>这里是标题</span>
          </div>
          <div class="icons">
            <i
              title="最小化"
              class="el-icon-minus minimizeBtn"
              style="font-size: 24px"
            ></i>
            <i
              title="全屏"
              class="el-icon-full-screen changeBig"
              style="font-size: 24px"
            ></i>
            <i
              title="缩小"
              class="el-icon-rank changeSmall"
              style="font-size: 24px"
            ></i>
            <i
              title="关闭"
              class="el-icon-close"
              style="font-size: 24px"
              @click="closeDialog"
            ></i>
          </div>
        </div>
        <div slot="title" class="medium minimize">
          <div class="lefts">
            <span>缩小后的标题</span>
          </div>
          <div class="icons">
            <i
              title="放大"
              class="el-icon-full-screen recover"
              style="font-size: 24px"
            ></i>
            <i
              title="关闭"
              class="el-icon-close"
              style="font-size: 24px"
              @click="closeDialog"
            ></i>
          </div>
        </div>
        <div class="dialogBodyEl dial" id="content">这里是内容</div>
      </el-dialog>
    </div>

4.css

.dialogWrap {
  .el-dialog {
    position: fixed;
    top: 20vh;
    left: 50%;
    margin: 0 !important;
  }
  .el-dialog__wrapper {
    z-index: 999999999 !important;
  }
  .el-dialog__header {
    background: #fff;
  }
  .el-dialog__header .el-dialog__title {
    font-size: 18px;
    color: #303133;
  }
  .el-dialog__headerbtn .el-dialog__close {
    color: #409eff;
  }
  .el-dialog__body {
    padding: 0;
  }
}
.no_select {
  -webkit-touch-callout: none;
  /* iOS Safari */
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -khtml-user-select: none;
  /* Konqueror */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* Internet Explorer/Edge */
  user-select: none;
  /* Non-prefixed version, currently */
}
.dialogWrap .el-dialog {
  .el-dialog__header {
    width: 100%;
    padding: 10px 10px 10px !important;
    display: flex;
    border-bottom: 1px solid #ccc;
    @extend .no_select;
    cursor: auto;
    box-sizing: border-box;

    line-height: 1.5 !important;
    .medium {
      width: 100%;
      height: 100%;
      // display: flex;
      overflow: hidden;
      div {
        flex: 1;
      }

      .lefts {
        margin-top: 3px;
        float: left;
        text-align: left;
        width: 80%;
        text-overflow: ellipsis;
        overflow: hidden;
        white-space: nowrap;
        span {
          text-align: left;
          font-size: 16px;
          color: #606266;
        }
      }

      .icons {
        display: flex;
        justify-content: flex-end;
        float: right;
        i {
          color: #5f6368;
          font-size: 18px !important;
          display: block;
          padding: 3px;
        }

        i:hover {
          background: #dcdfe6;
          cursor: pointer;
        }

        .el-icon-close:hover {
          background: #dcdfe6;
          // color: #fff;
        }

        .changeSmall {
          display: none;
        }
      }
    }
  }
}
.minimize {
  display: none;
}
posted @   刘酸酸sour  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示