input表单输入限制
const trigger = (el, type) => { const event = new Event(type) el.dispatchEvent(event)}// 输入限制const inputLimit = { bind: function (el, binding, vnode) { const type = binding.value || 'number'; const input = el.getElementsByTagName('input')[0] const regMap = { number: () => { let newString = String(input.value); console.log(newString, type); input.value = newString.replace(/[^\d]/g, '') trigger(input, "input") }, zh: () => { // 只能输入中文 let newString = String(input.value); input.value = newString.replace(/[^\u4E00-\u9FA5]/g, '') trigger(input, "input") }, integer: () => { let newString = String(input.value); newString = newString.replace(/[^\d]/g, '') newString = Number(newString) input.value = newString trigger(input, "input") }, } const handle = regMap[type] input.addEventListener('keyup', handle) input.addEventListener('blur', handle) el.$bindInput = input el.$bindInput.handle = handle }, unbind: function (el) { el.$bindInput.removeEventListener('keyup', el.$bindInput.handle) el.$bindInput.removeEventListener('blur', el.$bindInput.handle) }}export default inputLimit
图片懒加载
const LazyLoad = { // 初始化 init(el, val, def) { el.setAttribute("data-src", val); el.setAttribute("src", def); }, // 利用IntersectionObserver监听el observe(el) { var io = new IntersectionObserver((entries) => { const realSrc = el.dataset.src; if (entries[0].isIntersecting) { if (realSrc) { el.src = realSrc; el.removeAttribute("data-src"); } } }); io.observe(el); }, // 监听scroll事件 listenerScroll(el) { const handler = LazyLoad.throttle(LazyLoad.load, 300); LazyLoad.load(el); window.addEventListener("scroll", () => { handler(el); }); }, // 加载真实图片 load(el) { const windowHeight = document.documentElement.clientHeight; const elTop = el.getBoundingClientRect().top; const elBtm = el.getBoundingClientRect().bottom; const realSrc = el.dataset.src; if (elTop - windowHeight < 0 && elBtm > 0) { if (realSrc) { el.src = realSrc; el.removeAttribute("data-src"); } } }, // 节流 throttle(fn, delay) { let timer; let prevTime; return function (...args) { const currTime = Date.now(); const context = this; if (!prevTime) prevTime = currTime; clearTimeout(timer); if (currTime - prevTime > delay) { prevTime = currTime; fn.apply(context, args); clearTimeout(timer); return; } timer = setTimeout(function () { prevTime = Date.now(); timer = null; fn.apply(context, args); }, delay); }; },};const LazyLoadDirective = { bind(el, binding) { const oldValue = binding.oldValue; if (!oldValue) { const defaultSrc = require('./loading.gif'); LazyLoad.init(el, binding.value, defaultSrc); } }, update(el, binding) { const oldValue = binding.oldValue; if (!oldValue) { const defaultSrc = require('./loading.gif'); LazyLoad.init(el, binding.value, defaultSrc); } }, inserted(el) { if (IntersectionObserver) { LazyLoad.observe(el); } else { LazyLoad.listenerScroll(el); } },}export default LazyLoadDirective;
简易防重点击
const preventReClick = { inserted: function (el, binding) { el.addEventListener("click", () => { if (!el.disabled) { el.disabled = true; setTimeout(() => { el.disabled = false; }, binding.value || 3000); // 传入绑定值使用,默认3000毫秒内不可重复触发 } }); },};export default preventReClick;
简易文字水印
const addWaterMarker = (str, parentNode, font, textColor) => { // 水印文字,父元素,字体,文字颜色 let can = document.createElement("canvas"); parentNode.appendChild(can); can.width = 200; can.height = 150; can.style.display = "none"; let cans = can.getContext("2d"); cans.rotate((-20 * Math.PI) / 180); cans.font = font || "16px Microsoft JhengHei"; cans.fillStyle = textColor || "rgba(180, 180, 180, 0.3)"; cans.textAlign = "left"; cans.textBaseline = "Middle"; cans.fillText(str, can.width / 10, can.height / 2); parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")";};const waterMarker = { bind: function (el, binding) { addWaterMarker( binding.value.text, el, binding.value.font, binding.value.textColor ); },};export default waterMarker;
拖拽指令
function extractHandle (handle) { return handle && handle.$el || handle;}function getPosWithBoundaries (elementRect, boundingRect, left, top, boundingRectMargin) { if (boundingRectMargin === void 0) { boundingRectMargin = {}; } let adjustedPos = { left: left, top: top }; let height = elementRect.height, width = elementRect.width; let topRect = top, bottomRect = top + height, leftRect = left, rightRect = left + width; let marginTop = boundingRectMargin.top || 0, marginBottom = boundingRectMargin.bottom || 0, marginLeft = boundingRectMargin.left || 0, marginRight = boundingRectMargin.right || 0; let topBoundary = boundingRect.top + marginTop, bottomBoundary = boundingRect.bottom - marginBottom, leftBoundary = boundingRect.left + marginLeft, rightBoundary = boundingRect.right - marginRight; if (topRect < topBoundary) { adjustedPos.top = topBoundary; } else if (bottomRect > bottomBoundary) { adjustedPos.top = bottomBoundary - height; } if (leftRect < leftBoundary) { adjustedPos.left = leftBoundary; } else if (rightRect > rightBoundary) { adjustedPos.left = rightBoundary - width; } return adjustedPos;}const draggable = (Vue) => { Vue.directive('draggable', { update: function (el, binding) { if (binding.value && binding.value.stopDragging) { return; } let handler = (binding.value && binding.value.handle && extractHandle(binding.value.handle)) || el; if (binding && binding.value && binding.value.resetInitialPos) { initializeState(); handlePositionChanged(); } if (!handler.getAttribute("draggable")) { el.removeEventListener("mousedown", el["listener"], false); handler.addEventListener("mousedown", mouseDown, false); handler.setAttribute("draggable", "true"); el["listener"] = mouseDown; initializeState(); handlePositionChanged(); } function mouseMove (event) { event.preventDefault(); let stopDragging = binding.value && binding.value.stopDragging; if (stopDragging) { return; } let state = getState(); if (!state.startDragPosition || !state.initialMousePos) { initializeState(event); state = getState(); } let dx = event.clientX - state.initialMousePos.left; let dy = event.clientY - state.initialMousePos.top; let currentDragPosition = { left: state.startDragPosition.left + dx, top: state.startDragPosition.top + dy }; // console.log(state.initialMousePos.top); let boundingRect = getBoundingRect(); let elementRect = el.getBoundingClientRect(); if (boundingRect && elementRect) { currentDragPosition = getPosWithBoundaries(elementRect, boundingRect, currentDragPosition.left, currentDragPosition.top, binding.value.boundingRectMargin); } // 鼠标拖拽边界判断 if (currentDragPosition.top < 0) { currentDragPosition.top = 0; } else if (currentDragPosition.top > window.innerHeight - 80) { currentDragPosition.top = window.innerHeight - 80; } if (currentDragPosition.left < 286 - elementRect.width) { currentDragPosition.left = 286 - elementRect.width; } else if (currentDragPosition.left > window.innerWidth - 80) { currentDragPosition.left = window.innerWidth - 80; } // if (elementRect.right >= 0 && elementRect.bottom >= 740 // && event.clientX > 0 && event.clientY > 0 // && elementRect.top <= window.innerHeight && event.clientY < window.innerHeight // && elementRect.left <= window.innerWidth && event.clientX < window.innerWidth) // { // } setState({ currentDragPosition: currentDragPosition }); updateElementStyle(); handlePositionChanged(event); } function getBoundingRect () { if (!binding.value) { return; } return binding.value.boundingRect || binding.value.boundingElement && binding.value.boundingElement.getBoundingClientRect(); } function updateElementStyle () { let state = getState(); if (!state.currentDragPosition) { return; } el.style.position = "fixed"; el.style.left = state.currentDragPosition.left + "px"; el.style.top = state.currentDragPosition.top + "px"; el.style.transform = ''; } function mouseUp () { let currentRectPosition = getRectPosition(); setState({ initialMousePos: undefined, startDragPosition: currentRectPosition, currentDragPosition: currentRectPosition }); document.removeEventListener("mousemove", mouseMove, false); document.removeEventListener("mouseup", mouseUp, false); } function mouseDown (event) { setState({ initialMousePos: getInitialMousePosition(event) }); handlePositionChanged(event); document.addEventListener("mousemove", mouseMove, false); document.addEventListener("mouseup", mouseUp, false); } function getInitialMousePosition (event) { return event && { left: event.clientX, top: event.clientY }; } function getRectPosition () { let clientRect = el.getBoundingClientRect(); if (!clientRect.height || !clientRect.width) { return; } return { left: clientRect.left, top: clientRect.top }; } function initializeState (event) { let state = getState(); let initialRectPositionFromBinding = binding && binding.value && binding.value.initialPosition; let initialRectPositionFromState = state.initialPosition; let startingDragPosition = getRectPosition(); let initialPosition = initialRectPositionFromBinding || initialRectPositionFromState || startingDragPosition; setState({ initialPosition: initialPosition, startDragPosition: initialPosition, currentDragPosition: initialPosition, initialMousePos: getInitialMousePosition(event) }); updateElementStyle(); setPositionToCenter(); } function setState (partialState) { let prevState = getState(); let state = Object.assign({}, prevState, partialState); handler.setAttribute("draggable-state", JSON.stringify(state)); } function handlePositionChanged (event) { let state = getState(); let posDiff = { x: 0, y: 0 }; if (state.currentDragPosition && state.startDragPosition) { posDiff.x = state.currentDragPosition.left - state.startDragPosition.left; posDiff.y = state.currentDragPosition.top - state.startDragPosition.top; } let currentPosition = state.currentDragPosition && Object.assign({}, state.currentDragPosition); binding.value && binding.value.onPositionChange && state && binding.value.onPositionChange(posDiff, currentPosition, event); } function getState () { return JSON.parse(handler.getAttribute("draggable-state")) || {}; } function setPositionToCenter () { el.style.left = '50%'; el.style.top = '50%'; el.style.transform = 'translate(-50%, -50%)'; } el.timer = null; window.addEventListener('resize', () => { clearTimeout(el.timer); el.timer = setTimeout( () => { setPositionToCenter(); },500); }, false); } });};export default draggable;