directives.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import Vue from 'vue';
  2. Vue.directive('drag', (el, binding) => {
  3. const oDiv = el // 当前元素
  4. const minTop = oDiv.getAttribute('drag-min-top')
  5. const drawBox = document.getElementById("drawBox");
  6. const ifMoveSizeArea = 20
  7. oDiv.onmousedown = e => {
  8. let target = oDiv
  9. if(e.button == 2){
  10. while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
  11. target = target.parentElement
  12. }
  13. document.onselectstart = () => {
  14. return false
  15. }
  16. if (!target.getAttribute('init_x')) {
  17. target.setAttribute('init_x', target.offsetLeft)
  18. target.setAttribute('init_y', target.offsetTop)
  19. }
  20. const newE = e;
  21. const initX = parseInt(target.getAttribute('init_x'))
  22. const initY = parseInt(target.getAttribute('init_y'))
  23. // 鼠标按下,计算当前元素距离可视区的距离
  24. // 获取div元素的坐标点
  25. let drawRect = el.getBoundingClientRect();
  26. let init_x = e.clientX - drawRect.x;
  27. let init_y = e.clientY - drawRect.y;
  28. const drawRect_x = drawRect.x;
  29. const drawRect_y = drawRect.y;
  30. const disX = e.clientX - (target.offsetLeft >= 0 ? target.offsetLeft : 0)
  31. const disY = e.clientY - (target.offsetTop >= 0 ? target.offsetTop : 0)
  32. let l_type = 'none';
  33. let t_type = 'none';
  34. document.onmousemove = e => {
  35. if(e.preventDefault){
  36. e.preventDefault()
  37. } else {
  38. e.returnValue = false
  39. }
  40. // 通过事件委托,计算移动的距离
  41. // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
  42. let l = (e.clientX - disX) - (drawRect.x > drawRect_x ? parseInt(drawRect.x - drawRect_x) : 0);
  43. let t = (e.clientY - disY) - (drawRect.y > drawRect_y ? parseInt(drawRect.y - drawRect_y) : 0);
  44. const { marginTop: mt, marginLeft: ml } = window.getComputedStyle(target)
  45. // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
  46. // target.style.left = l - parseInt(ml) + 'px'
  47. // target.style.top = t + 'px'
  48. let div = document.getElementById("drawDiv");
  49. if(!div){
  50. div = document.createElement("div");
  51. div.id = "drawDiv";
  52. div.className = "innerDiv";
  53. div.style.border = "1px dashed red";
  54. div.style.borderRadius = "5px";
  55. div.style.top = init_x + 'px';
  56. div.style.left = init_y + 'px';
  57. div.style.position = "absolute";
  58. drawBox.append(div);
  59. }
  60. if(l < 0 && l_type != 'right') {
  61. div.style.right = (oDiv.offsetWidth - init_x) + 'px';
  62. div.style.removeProperty('left');
  63. l_type = 'right';
  64. } else if (l > 0 && l_type != 'left') {
  65. div.style.left = init_x + 'px';
  66. div.style.removeProperty('right');
  67. l_type = 'left';
  68. } else {
  69. l_type = 'none';
  70. }
  71. if(t < 0 && t_type != 'bottom') {
  72. div.style.bottom = (oDiv.offsetHeight - init_y) + 'px';
  73. div.style.removeProperty('top');
  74. t_type = 'bottom';
  75. } else if (t > 0 && t_type != 'top') {
  76. div.style.top = init_y + 'px';
  77. div.style.removeProperty('bottom');
  78. t_type = 'top';
  79. } else {
  80. t_type = 'none';
  81. }
  82. div.style.width = Math.abs(l) + 'px';
  83. div.style.height = Math.abs(t) + 'px';
  84. }
  85. document.onmouseup = e => {
  86. // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
  87. const l = e.clientX - disX
  88. const t = e.clientY - disY
  89. let drawDialog = document.getElementById("draw-dialog-type");
  90. drawDialog.style.top = '60px';
  91. drawDialog.style.right = '0px';
  92. drawDialog.style.display = "block";
  93. document.onmousemove = null
  94. document.onmouseup = null
  95. document.onselectstart = null
  96. }
  97. } else {
  98. while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
  99. target = target.parentElement
  100. }
  101. document.onselectstart = () => {
  102. return false
  103. }
  104. if (!target.getAttribute('init_x')) {
  105. target.setAttribute('init_x', target.offsetLeft)
  106. target.setAttribute('init_y', target.offsetTop)
  107. }
  108. const initX = parseInt(target.getAttribute('init_x'))
  109. const initY = parseInt(target.getAttribute('init_y'))
  110. // 鼠标按下,计算当前元素距离可视区的距离
  111. const disX = e.clientX - target.offsetLeft
  112. const disY = e.clientY - target.offsetTop
  113. document.onmousemove = e => {
  114. if(e.preventDefault){
  115. e.preventDefault()
  116. } else {
  117. e.returnValue = false
  118. }
  119. // 通过事件委托,计算移动的距离
  120. // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
  121. const l = e.clientX - disX
  122. const t = e.clientY - disY
  123. const { marginTop: mt, marginLeft: ml } = window.getComputedStyle(target)
  124. // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
  125. target.style.left = l - parseInt(ml) + 'px'
  126. target.style.top = t + 'px'
  127. if (Math.abs(l - initX) > ifMoveSizeArea || Math.abs(t - initY) > ifMoveSizeArea) {
  128. target.setAttribute('dragged', '')
  129. } else {
  130. target.removeAttribute('dragged')
  131. }
  132. }
  133. document.onmouseup = e => {
  134. document.onmousemove = null
  135. document.onmouseup = null
  136. document.onselectstart = null
  137. }
  138. }
  139. // return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
  140. return false
  141. }
  142. })