You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
7.1 KiB

8 months ago
  1. // import Vue from 'vue';
  2. //
  3. // // v-dialogDrag: 弹窗拖拽属性
  4. // Vue.directive('drag', {
  5. // bind(el, binding, vnode, oldVnode) {
  6. // const dialogHeaderEl = el.querySelector('.el-dialog__header');
  7. // const dragDom = el.querySelector('.el-dialog');
  8. //
  9. // dialogHeaderEl.style.cssText += ';cursor:move;'
  10. // dragDom.style.cssText += ';top:0px;'
  11. //
  12. // // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
  13. // const sty = (() => {
  14. // if (window.document.currentStyle) {
  15. // return (dom, attr) => dom.currentStyle[attr];
  16. // } else {
  17. // return (dom, attr) => getComputedStyle(dom, false)[attr];
  18. // }
  19. // })()
  20. //
  21. // dialogHeaderEl.onmousedown = (e) => {
  22. // // 鼠标按下,计算当前元素距离可视区的距离
  23. // const disX = e.clientX - dialogHeaderEl.offsetLeft;
  24. // const disY = e.clientY - dialogHeaderEl.offsetTop;
  25. //
  26. // const screenWidth = document.body.clientWidth; // body当前宽度
  27. // const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)
  28. //
  29. // const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
  30. // const dragDomheight = dragDom.offsetHeight; // 对话框高度
  31. //
  32. // const minDragDomLeft = dragDom.offsetLeft;
  33. // const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
  34. //
  35. // const minDragDomTop = dragDom.offsetTop;
  36. // const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
  37. //
  38. //
  39. // // 获取到的值带px 正则匹配替换
  40. // let styL = sty(dragDom, 'left');
  41. // let styT = sty(dragDom, 'top');
  42. //
  43. // // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
  44. // if (styL.includes('%')) {
  45. // styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
  46. // styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
  47. // } else {
  48. // styL = +styL.replace(/\px/g, '');
  49. // styT = +styT.replace(/\px/g, '');
  50. // };
  51. //
  52. // document.onmousemove = function (e) {
  53. // // 通过事件委托,计算移动的距离
  54. // let left = e.clientX - disX;
  55. // let top = e.clientY - disY;
  56. //
  57. // // 边界处理
  58. // if (-(left) > minDragDomLeft) {
  59. // left = -(minDragDomLeft);
  60. // } else if (left > maxDragDomLeft) {
  61. // left = maxDragDomLeft;
  62. // }
  63. //
  64. // if (-(top) > minDragDomTop) {
  65. // top = -(minDragDomTop);
  66. // } else if (top > maxDragDomTop) {
  67. // top = maxDragDomTop;
  68. // }
  69. //
  70. // // 移动当前元素
  71. // dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
  72. // };
  73. //
  74. // document.onmouseup = function (e) {
  75. // document.onmousemove = null;
  76. // document.onmouseup = null;
  77. // };
  78. // }
  79. // }
  80. // })
  81. import Vue from 'vue';
  82. // v-dialogDrag: 弹窗拖拽属性
  83. Vue.directive('drag', {
  84. bind(el, binding, vnode, oldVnode) {
  85. const dialogHeaderEl = el.querySelector('.el-dialog__header');
  86. const dragDom = el.querySelector('.el-dialog');
  87. dialogHeaderEl.style.cssText += ';cursor:move;'
  88. dragDom.style.cssText += ';top:0px;'
  89. // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
  90. const sty = (() => {
  91. if (window.document.currentStyle) {
  92. return (dom, attr) => dom.currentStyle[attr];
  93. } else {
  94. return (dom, attr) => getComputedStyle(dom, false)[attr];
  95. }
  96. })()
  97. dialogHeaderEl.onmousedown = (e) => {
  98. // 获取鼠标按下时的坐标
  99. e.preventDefault();
  100. // 鼠标按下,计算当前元素距离可视区的距离
  101. const disX = e.clientX - dialogHeaderEl.offsetLeft;
  102. const disY = e.clientY - dialogHeaderEl.offsetTop;
  103. const screenWidth = document.body.clientWidth; // body当前宽度
  104. const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)
  105. const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
  106. const dragDomheight = dragDom.offsetHeight; // 对话框高度
  107. const minDragDomLeft = dragDom.offsetLeft;
  108. const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
  109. const minDragDomTop = dragDom.offsetTop;
  110. const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
  111. // 获取到的值带px 正则匹配替换
  112. let styL = sty(dragDom, 'left');
  113. let styT = sty(dragDom, 'top');
  114. // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
  115. if (styL.includes('%')) {
  116. styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
  117. styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
  118. } else {
  119. styL = +styL.replace(/\px/g, '');
  120. styT = +styT.replace(/\px/g, '');
  121. };
  122. document.onmousemove = function (e) {
  123. // 移动时禁止默认事件
  124. e.preventDefault();
  125. // 通过事件委托,计算移动的距离
  126. let left = e.clientX - disX;
  127. let top = e.clientY - disY;
  128. // 边界处理
  129. /* if (-(left) > minDragDomLeft) {
  130. left = -(minDragDomLeft);
  131. } else if (left > maxDragDomLeft) {
  132. left = maxDragDomLeft;
  133. }
  134. if (-(top) > minDragDomTop) {
  135. top = -(minDragDomTop);
  136. } else if (top > maxDragDomTop) {
  137. top = maxDragDomTop;
  138. }*/
  139. // 设置最大和最小可拖动范围
  140. const viewportWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  141. const viewportHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
  142. let minLeft = 0;
  143. let maxLeft = viewportWidth - dragDom.offsetWidth;
  144. let minTop = 0;
  145. let maxTop = viewportHeight - dragDom.offsetHeight;
  146. if (dragDom.offsetHeight > viewportHeight) {
  147. // 只有当内容过高时才放宽顶部限制
  148. minTop = Math.max(
  149. -(dragDom.offsetHeight - 100), // 至少保留 100px 高度可见
  150. -(dragDom.offsetHeight - viewportHeight)
  151. );
  152. maxTop = 0;
  153. }
  154. // 应用边界限制
  155. // left = Math.max(minLeft, Math.min(left, maxLeft));
  156. top = Math.max(minTop, Math.min(top, maxTop));
  157. // 应用新的边界限制
  158. // left = Math.max(minLeft, Math.min(left, maxLeft));
  159. top = Math.max(minTop, Math.min(top, maxTop));
  160. // 移动当前元素
  161. // dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
  162. dragDom.style.transform = `translate(${left + styL}px, ${top + styT}px)`;
  163. // 让拖动更平滑
  164. // dragDom.style.cssText += ';top:0px;position:relative;transition: transform 0.2s ease;';
  165. };
  166. document.onmouseup = function (e) {
  167. document.onmousemove = null;
  168. document.onmouseup = null;
  169. };
  170. }
  171. }
  172. })