input表单输入限制

  1. const trigger = (el, type) => {
  2. const event = new Event(type)
  3. el.dispatchEvent(event)
  4. }
  5. // 输入限制
  6. const inputLimit = {
  7. bind: function (el, binding, vnode) {
  8. const type = binding.value || 'number';
  9. const input = el.getElementsByTagName('input')[0]
  10. const regMap = {
  11. number: () => {
  12. let newString = String(input.value);
  13. console.log(newString, type);
  14. input.value = newString.replace(/[^\d]/g, '')
  15. trigger(input, "input")
  16. },
  17. zh: () => {
  18. // 只能输入中文
  19. let newString = String(input.value);
  20. input.value = newString.replace(/[^\u4E00-\u9FA5]/g, '')
  21. trigger(input, "input")
  22. },
  23. integer: () => {
  24. let newString = String(input.value);
  25. newString = newString.replace(/[^\d]/g, '')
  26. newString = Number(newString)
  27. input.value = newString
  28. trigger(input, "input")
  29. },
  30. }
  31. const handle = regMap[type]
  32. input.addEventListener('keyup', handle)
  33. input.addEventListener('blur', handle)
  34. el.$bindInput = input
  35. el.$bindInput.handle = handle
  36. },
  37. unbind: function (el) {
  38. el.$bindInput.removeEventListener('keyup', el.$bindInput.handle)
  39. el.$bindInput.removeEventListener('blur', el.$bindInput.handle)
  40. }
  41. }
  42. export default inputLimit

图片懒加载

  1. const LazyLoad = {
  2. // 初始化
  3. init(el, val, def) {
  4. el.setAttribute("data-src", val);
  5. el.setAttribute("src", def);
  6. },
  7. // 利用IntersectionObserver监听el
  8. observe(el) {
  9. var io = new IntersectionObserver((entries) => {
  10. const realSrc = el.dataset.src;
  11. if (entries[0].isIntersecting) {
  12. if (realSrc) {
  13. el.src = realSrc;
  14. el.removeAttribute("data-src");
  15. }
  16. }
  17. });
  18. io.observe(el);
  19. },
  20. // 监听scroll事件
  21. listenerScroll(el) {
  22. const handler = LazyLoad.throttle(LazyLoad.load, 300);
  23. LazyLoad.load(el);
  24. window.addEventListener("scroll", () => {
  25. handler(el);
  26. });
  27. },
  28. // 加载真实图片
  29. load(el) {
  30. const windowHeight = document.documentElement.clientHeight;
  31. const elTop = el.getBoundingClientRect().top;
  32. const elBtm = el.getBoundingClientRect().bottom;
  33. const realSrc = el.dataset.src;
  34. if (elTop - windowHeight < 0 && elBtm > 0) {
  35. if (realSrc) {
  36. el.src = realSrc;
  37. el.removeAttribute("data-src");
  38. }
  39. }
  40. },
  41. // 节流
  42. throttle(fn, delay) {
  43. let timer;
  44. let prevTime;
  45. return function (...args) {
  46. const currTime = Date.now();
  47. const context = this;
  48. if (!prevTime) prevTime = currTime;
  49. clearTimeout(timer);
  50. if (currTime - prevTime > delay) {
  51. prevTime = currTime;
  52. fn.apply(context, args);
  53. clearTimeout(timer);
  54. return;
  55. }
  56. timer = setTimeout(function () {
  57. prevTime = Date.now();
  58. timer = null;
  59. fn.apply(context, args);
  60. }, delay);
  61. };
  62. },
  63. };
  64. const LazyLoadDirective = {
  65. bind(el, binding) {
  66. const oldValue = binding.oldValue;
  67. if (!oldValue) {
  68. const defaultSrc = require('./loading.gif');
  69. LazyLoad.init(el, binding.value, defaultSrc);
  70. }
  71. },
  72. update(el, binding) {
  73. const oldValue = binding.oldValue;
  74. if (!oldValue) {
  75. const defaultSrc = require('./loading.gif');
  76. LazyLoad.init(el, binding.value, defaultSrc);
  77. }
  78. },
  79. inserted(el) {
  80. if (IntersectionObserver) {
  81. LazyLoad.observe(el);
  82. } else {
  83. LazyLoad.listenerScroll(el);
  84. }
  85. },
  86. }
  87. export default LazyLoadDirective;

简易防重点击

  1. const preventReClick = {
  2. inserted: function (el, binding) {
  3. el.addEventListener("click", () => {
  4. if (!el.disabled) {
  5. el.disabled = true;
  6. setTimeout(() => {
  7. el.disabled = false;
  8. }, binding.value || 3000); // 传入绑定值使用,默认3000毫秒内不可重复触发
  9. }
  10. });
  11. },
  12. };
  13. export default preventReClick;

简易文字水印

  1. const addWaterMarker = (str, parentNode, font, textColor) => {
  2. // 水印文字,父元素,字体,文字颜色
  3. let can = document.createElement("canvas");
  4. parentNode.appendChild(can);
  5. can.width = 200;
  6. can.height = 150;
  7. can.style.display = "none";
  8. let cans = can.getContext("2d");
  9. cans.rotate((-20 * Math.PI) / 180);
  10. cans.font = font || "16px Microsoft JhengHei";
  11. cans.fillStyle = textColor || "rgba(180, 180, 180, 0.3)";
  12. cans.textAlign = "left";
  13. cans.textBaseline = "Middle";
  14. cans.fillText(str, can.width / 10, can.height / 2);
  15. parentNode.style.backgroundImage =
  16. "url(" + can.toDataURL("image/png") + ")";
  17. };
  18. const waterMarker = {
  19. bind: function (el, binding) {
  20. addWaterMarker(
  21. binding.value.text,
  22. el,
  23. binding.value.font,
  24. binding.value.textColor
  25. );
  26. },
  27. };
  28. export default waterMarker;

拖拽指令

  1. function extractHandle (handle) {
  2. return handle && handle.$el || handle;
  3. }
  4. function getPosWithBoundaries (elementRect, boundingRect, left, top, boundingRectMargin) {
  5. if (boundingRectMargin === void 0) {
  6. boundingRectMargin = {};
  7. }
  8. let adjustedPos = {
  9. left: left,
  10. top: top
  11. };
  12. let height = elementRect.height,
  13. width = elementRect.width;
  14. let topRect = top,
  15. bottomRect = top + height,
  16. leftRect = left,
  17. rightRect = left + width;
  18. let marginTop = boundingRectMargin.top || 0,
  19. marginBottom = boundingRectMargin.bottom || 0,
  20. marginLeft = boundingRectMargin.left || 0,
  21. marginRight = boundingRectMargin.right || 0;
  22. let topBoundary = boundingRect.top + marginTop,
  23. bottomBoundary = boundingRect.bottom - marginBottom,
  24. leftBoundary = boundingRect.left + marginLeft,
  25. rightBoundary = boundingRect.right - marginRight;
  26. if (topRect < topBoundary) {
  27. adjustedPos.top = topBoundary;
  28. } else if (bottomRect > bottomBoundary) {
  29. adjustedPos.top = bottomBoundary - height;
  30. }
  31. if (leftRect < leftBoundary) {
  32. adjustedPos.left = leftBoundary;
  33. } else if (rightRect > rightBoundary) {
  34. adjustedPos.left = rightBoundary - width;
  35. }
  36. return adjustedPos;
  37. }
  38. const draggable = (Vue) => {
  39. Vue.directive('draggable', {
  40. update: function (el, binding) {
  41. if (binding.value && binding.value.stopDragging) {
  42. return;
  43. }
  44. let handler = (binding.value && binding.value.handle && extractHandle(binding.value.handle)) || el;
  45. if (binding && binding.value && binding.value.resetInitialPos) {
  46. initializeState();
  47. handlePositionChanged();
  48. }
  49. if (!handler.getAttribute("draggable")) {
  50. el.removeEventListener("mousedown", el["listener"], false);
  51. handler.addEventListener("mousedown", mouseDown, false);
  52. handler.setAttribute("draggable", "true");
  53. el["listener"] = mouseDown;
  54. initializeState();
  55. handlePositionChanged();
  56. }
  57. function mouseMove (event) {
  58. event.preventDefault();
  59. let stopDragging = binding.value && binding.value.stopDragging;
  60. if (stopDragging) {
  61. return;
  62. }
  63. let state = getState();
  64. if (!state.startDragPosition || !state.initialMousePos) {
  65. initializeState(event);
  66. state = getState();
  67. }
  68. let dx = event.clientX - state.initialMousePos.left;
  69. let dy = event.clientY - state.initialMousePos.top;
  70. let currentDragPosition = {
  71. left: state.startDragPosition.left + dx,
  72. top: state.startDragPosition.top + dy
  73. };
  74. // console.log(state.initialMousePos.top);
  75. let boundingRect = getBoundingRect();
  76. let elementRect = el.getBoundingClientRect();
  77. if (boundingRect && elementRect) {
  78. currentDragPosition = getPosWithBoundaries(elementRect, boundingRect, currentDragPosition.left, currentDragPosition.top, binding.value.boundingRectMargin);
  79. }
  80. // 鼠标拖拽边界判断
  81. if (currentDragPosition.top < 0) {
  82. currentDragPosition.top = 0;
  83. } else if (currentDragPosition.top > window.innerHeight - 80) {
  84. currentDragPosition.top = window.innerHeight - 80;
  85. }
  86. if (currentDragPosition.left < 286 - elementRect.width) {
  87. currentDragPosition.left = 286 - elementRect.width;
  88. } else if (currentDragPosition.left > window.innerWidth - 80) {
  89. currentDragPosition.left = window.innerWidth - 80;
  90. }
  91. // if (elementRect.right >= 0 && elementRect.bottom >= 740
  92. // && event.clientX > 0 && event.clientY > 0
  93. // && elementRect.top <= window.innerHeight && event.clientY < window.innerHeight
  94. // && elementRect.left <= window.innerWidth && event.clientX < window.innerWidth)
  95. // {
  96. // }
  97. setState({
  98. currentDragPosition: currentDragPosition
  99. });
  100. updateElementStyle();
  101. handlePositionChanged(event);
  102. }
  103. function getBoundingRect () {
  104. if (!binding.value) {
  105. return;
  106. }
  107. return binding.value.boundingRect ||
  108. binding.value.boundingElement &&
  109. binding.value.boundingElement.getBoundingClientRect();
  110. }
  111. function updateElementStyle () {
  112. let state = getState();
  113. if (!state.currentDragPosition) {
  114. return;
  115. }
  116. el.style.position = "fixed";
  117. el.style.left = state.currentDragPosition.left + "px";
  118. el.style.top = state.currentDragPosition.top + "px";
  119. el.style.transform = '';
  120. }
  121. function mouseUp () {
  122. let currentRectPosition = getRectPosition();
  123. setState({
  124. initialMousePos: undefined,
  125. startDragPosition: currentRectPosition,
  126. currentDragPosition: currentRectPosition
  127. });
  128. document.removeEventListener("mousemove", mouseMove, false);
  129. document.removeEventListener("mouseup", mouseUp, false);
  130. }
  131. function mouseDown (event) {
  132. setState({
  133. initialMousePos: getInitialMousePosition(event)
  134. });
  135. handlePositionChanged(event);
  136. document.addEventListener("mousemove", mouseMove, false);
  137. document.addEventListener("mouseup", mouseUp, false);
  138. }
  139. function getInitialMousePosition (event) {
  140. return event && {
  141. left: event.clientX,
  142. top: event.clientY
  143. };
  144. }
  145. function getRectPosition () {
  146. let clientRect = el.getBoundingClientRect();
  147. if (!clientRect.height || !clientRect.width) {
  148. return;
  149. }
  150. return {
  151. left: clientRect.left,
  152. top: clientRect.top
  153. };
  154. }
  155. function initializeState (event) {
  156. let state = getState();
  157. let initialRectPositionFromBinding = binding && binding.value && binding.value.initialPosition;
  158. let initialRectPositionFromState = state.initialPosition;
  159. let startingDragPosition = getRectPosition();
  160. let initialPosition = initialRectPositionFromBinding || initialRectPositionFromState || startingDragPosition;
  161. setState({
  162. initialPosition: initialPosition,
  163. startDragPosition: initialPosition,
  164. currentDragPosition: initialPosition,
  165. initialMousePos: getInitialMousePosition(event)
  166. });
  167. updateElementStyle();
  168. setPositionToCenter();
  169. }
  170. function setState (partialState) {
  171. let prevState = getState();
  172. let state = Object.assign({}, prevState, partialState);
  173. handler.setAttribute("draggable-state", JSON.stringify(state));
  174. }
  175. function handlePositionChanged (event) {
  176. let state = getState();
  177. let posDiff = {
  178. x: 0,
  179. y: 0
  180. };
  181. if (state.currentDragPosition && state.startDragPosition) {
  182. posDiff.x = state.currentDragPosition.left - state.startDragPosition.left;
  183. posDiff.y = state.currentDragPosition.top - state.startDragPosition.top;
  184. }
  185. let currentPosition = state.currentDragPosition && Object.assign({}, state.currentDragPosition);
  186. binding.value && binding.value.onPositionChange && state && binding.value.onPositionChange(posDiff, currentPosition, event);
  187. }
  188. function getState () {
  189. return JSON.parse(handler.getAttribute("draggable-state")) || {};
  190. }
  191. function setPositionToCenter () {
  192. el.style.left = '50%';
  193. el.style.top = '50%';
  194. el.style.transform = 'translate(-50%, -50%)';
  195. }
  196. el.timer = null;
  197. window.addEventListener('resize', () => {
  198. clearTimeout(el.timer);
  199. el.timer = setTimeout( () => {
  200. setPositionToCenter();
  201. },500);
  202. }, false);
  203. }
  204. });
  205. };
  206. export default draggable;