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;