export default { bind(el, binding, vnode, oldVnode) { // 弹框可拉伸最小宽高 const minWidth = 400; const minHeight = 300;

// 初始非全屏
let isFullScreen = true;

// 当前宽高
let nowWidth = 0;
let nowHight = 0;

// 当前顶部高度
let nowMarginTop = 0;

// 获取弹框头部(这部分可双击全屏)
const dialogHeaderEl = el.querySelector('.el-dialog__header');


// 弹窗
const dragDom = el.querySelector('.el-dialog');

// 给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog;
dragDom.style.overflow = 'auto';

// 清除选择头部文字效果
// dialogHeaderEl.onselectstart = new Function("return false");

// 头部加上可拖动cursor
dialogHeaderEl.style.cursor = 'move';

// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);

const moveDown = (e) => {
  // 鼠标按下,计算当前元素距离可视区的距离
  const disX = e.clientX - dialogHeaderEl.offsetLeft;
  const disY = e.clientY - dialogHeaderEl.offsetTop;
  const winWidth = document.documentElement.clientWidth;
  const winHeight = document.documentElement.clientHeight;
  const maxWidth = winWidth - dragDom.offsetWidth;
  const maxHeight = winHeight - dragDom.offsetHeight;
  let styL, styT;

  if (sty.left.includes('%')) {
    styL = +winWidth * (+sty.left.replace(/%/g, '') / 100);
    styT = +winHeight * (+sty.top.replace(/%/g, '') / 100);
  } else {
    styL = +sty.left.replace(/\px/g, '');
    styT = +sty.top.replace(/\px/g, '');
  }

  document.onmousemove = function (e) {
    let l = e.clientX - disX;
    let t = e.clientY - disY;

    if (l < 0) {
      l = 0;
    } else if (l > maxWidth) {
      l = maxWidth;
    }

    if (t < 0) {
      t = 0;
    } else if (t > maxHeight) {
      t = maxHeight;
    }

    dragDom.style.left = `${l + styL}px`;
    dragDom.style.top = `${t + styT}px`;
  };

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

dialogHeaderEl.onmousedown = moveDown;

// 双击头部全屏效果
dialogHeaderEl.ondblclick = (e) => {
  if (isFullScreen) {
    // 全屏状态下禁用拖拽事件
    dialogHeaderEl.onmousedown = null;

    // 设置新的宽高和位置
    nowHight = dragDom.clientHeight;
    nowWidth = dragDom.clientWidth;
    nowMarginTop = dragDom.style.marginTop;
    dragDom.style.height = '100%';
    dragDom.style.width = '100%';
    dragDom.style.marginTop = 0;
    isFullScreen = false;
  } else {
    // 恢复原始大小和位置
    dragDom.style.height = `${nowHight}px`;
    dragDom.style.width = `${nowWidth}px`;
    dragDom.style.marginTop = nowMarginTop;
    isFullScreen = true;

    // 重新启用拖拽事件
    dialogHeaderEl.onmousedown = moveDown;
  }
};

},

}; 加上不能拖拽出上下左右页面,加上放大后不能拖拽出上下左右页面

内容:需要在moveDown函数中添加边界判断,以保证弹框不能拖拽到页面外部。

具体方法是,获取当前窗口的宽高和弹框的宽高,然后在移动时判断当前位置是否超出边界,如果超出则将弹框的位置设置为边界值。

另外,在全屏状态下需要禁用双击头部的拖拽事件,并在恢复原始大小后重新启用。

代码示例:

const moveDown = (e) => { const disX = e.clientX - dialogHeaderEl.offsetLeft; const disY = e.clientY - dialogHeaderEl.offsetTop; const winWidth = document.documentElement.clientWidth; const winHeight = document.documentElement.clientHeight; const maxWidth = winWidth - dragDom.offsetWidth; const maxHeight = winHeight - dragDom.offsetHeight; let styL, styT;

if (sty.left.includes('%')) { styL = +winWidth * (+sty.left.replace(/%/g, '') / 100); styT = +winHeight * (+sty.top.replace(/%/g, '') / 100); } else { styL = +sty.left.replace(/\px/g, ''); styT = +sty.top.replace(/\px/g, ''); }

document.onmousemove = function (e) { let l = e.clientX - disX; let t = e.clientY - disY;

if (l < 0) {
  l = 0;
} else if (l > maxWidth) {
  l = maxWidth;
}

if (t < 0) {
  t = 0;
} else if (t > maxHeight) {
  t = maxHeight;
}

dragDom.style.left = `${l + styL}px`;
dragDom.style.top = `${t + styT}px`;

};

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

dialogHeaderEl.onmousedown = moveDown;

dialogHeaderEl.ondblclick = (e) => { if (isFullScreen) { // 全屏状态下禁用拖拽事件 dialogHeaderEl.onmousedown = null;

// 设置新的宽高和位置
nowHight = dragDom.clientHeight;
nowWidth = dragDom.clientWidth;
nowMarginTop = dragDom.style.marginTop;
dragDom.style.height = '100%';
dragDom.style.width = '100%';
dragDom.style.marginTop = 0;
isFullScreen = false;

} else { // 恢复原始大小和位置 dragDom.style.height = ${nowHight}px; dragDom.style.width = ${nowWidth}px; dragDom.style.marginTop = nowMarginTop; isFullScreen = true;

// 重新启用拖拽事件
dialogHeaderEl.onmousedown = moveDown;

} };

Vue 弹框拖拽功能实现及边界限制

原文地址: https://www.cveoy.top/t/topic/oKN9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录