mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 16:46:19 +08:00
152 lines
4.2 KiB
TypeScript
152 lines
4.2 KiB
TypeScript
import { upperFirst } from 'lodash-es';
|
||
|
||
export interface ViewportOffsetResult {
|
||
left: number;
|
||
top: number;
|
||
right: number;
|
||
bottom: number;
|
||
rightIncludeBody: number;
|
||
bottomIncludeBody: number;
|
||
}
|
||
|
||
export function getBoundingClientRect(element: Element): DOMRect | number {
|
||
if (!element || !element.getBoundingClientRect) {
|
||
return 0;
|
||
}
|
||
return element.getBoundingClientRect();
|
||
}
|
||
const trim = function (string: string) {
|
||
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
|
||
};
|
||
/* istanbul ignore next */
|
||
export function hasClass(el: Element, cls: string) {
|
||
if (!el || !cls) return false;
|
||
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
|
||
if (el.classList) {
|
||
return el.classList.contains(cls);
|
||
} else {
|
||
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
|
||
}
|
||
}
|
||
/* istanbul ignore next */
|
||
export function addClass(el: Element, cls: string) {
|
||
if (!el) return;
|
||
let curClass = el.className;
|
||
const classes = (cls || '').split(' ');
|
||
|
||
for (let i = 0, j = classes.length; i < j; i++) {
|
||
const clsName = classes[i];
|
||
if (!clsName) continue;
|
||
|
||
if (el.classList) {
|
||
el.classList.add(clsName);
|
||
} else if (!hasClass(el, clsName)) {
|
||
curClass += ' ' + clsName;
|
||
}
|
||
}
|
||
if (!el.classList) {
|
||
el.className = curClass;
|
||
}
|
||
}
|
||
|
||
/* istanbul ignore next */
|
||
export function removeClass(el: Element, cls: string) {
|
||
if (!el || !cls) return;
|
||
const classes = cls.split(' ');
|
||
let curClass = ' ' + el.className + ' ';
|
||
|
||
for (let i = 0, j = classes.length; i < j; i++) {
|
||
const clsName = classes[i];
|
||
if (!clsName) continue;
|
||
|
||
if (el.classList) {
|
||
el.classList.remove(clsName);
|
||
} else if (hasClass(el, clsName)) {
|
||
curClass = curClass.replace(' ' + clsName + ' ', ' ');
|
||
}
|
||
}
|
||
if (!el.classList) {
|
||
el.className = trim(curClass);
|
||
}
|
||
}
|
||
/**
|
||
* 获取当前元素的left、top偏移
|
||
* left:元素最左侧距离文档左侧的距离
|
||
* top:元素最顶端距离文档顶端的距离
|
||
* right:元素最右侧距离文档右侧的距离
|
||
* bottom:元素最底端距离文档底端的距离
|
||
* rightIncludeBody:元素最左侧距离文档右侧的距离
|
||
* bottomIncludeBody:元素最底端距离文档最底部的距离
|
||
*
|
||
* @description:
|
||
*/
|
||
export function getViewportOffset(element: Element): ViewportOffsetResult {
|
||
const doc = document.documentElement;
|
||
|
||
const docScrollLeft = doc.scrollLeft;
|
||
const docScrollTop = doc.scrollTop;
|
||
const docClientLeft = doc.clientLeft;
|
||
const docClientTop = doc.clientTop;
|
||
|
||
const pageXOffset = window.pageXOffset;
|
||
const pageYOffset = window.pageYOffset;
|
||
|
||
const box = getBoundingClientRect(element);
|
||
|
||
const { left: retLeft, top: rectTop, width: rectWidth, height: rectHeight } = box as DOMRect;
|
||
|
||
const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0);
|
||
const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0);
|
||
const offsetLeft = retLeft + pageXOffset;
|
||
const offsetTop = rectTop + pageYOffset;
|
||
|
||
const left = offsetLeft - scrollLeft;
|
||
const top = offsetTop - scrollTop;
|
||
|
||
const clientWidth = window.document.documentElement.clientWidth;
|
||
const clientHeight = window.document.documentElement.clientHeight;
|
||
return {
|
||
left: left,
|
||
top: top,
|
||
right: clientWidth - rectWidth - left,
|
||
bottom: clientHeight - rectHeight - top,
|
||
rightIncludeBody: clientWidth - left,
|
||
bottomIncludeBody: clientHeight - top,
|
||
};
|
||
}
|
||
|
||
export function hackCss(attr: string, value: string) {
|
||
const prefix: string[] = ['webkit', 'Moz', 'ms', 'OT'];
|
||
|
||
const styleObj: any = {};
|
||
prefix.forEach((item) => {
|
||
styleObj[`${item}${upperFirst(attr)}`] = value;
|
||
});
|
||
return {
|
||
...styleObj,
|
||
[attr]: value,
|
||
};
|
||
}
|
||
|
||
/* istanbul ignore next */
|
||
export const on = function (
|
||
element: HTMLElement | Document | Window,
|
||
event: string,
|
||
handler: EventListenerOrEventListenerObject
|
||
): void {
|
||
if (element && event && handler) {
|
||
element.addEventListener(event, handler, false);
|
||
}
|
||
};
|
||
|
||
/* istanbul ignore next */
|
||
export const off = function (
|
||
element: HTMLElement | Document | Window,
|
||
event: string,
|
||
handler: Fn
|
||
): void {
|
||
if (element && event && handler) {
|
||
element.removeEventListener(event, handler, false);
|
||
}
|
||
};
|