@fesjs/fes-design
Version:
fes-design for PC
152 lines (146 loc) • 4.38 kB
JavaScript
import { camelize } from '@vue/shared';
/* istanbul ignore next */
function hasClass(el, cls) {
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);
}
return ` ${el.className} `.indexOf(` ${cls} `) > -1;
}
/* istanbul ignore next */
function addClass(el, cls) {
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 */
function removeClass(el, cls) {
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 = curClass.trim();
}
}
/* istanbul ignore next */
// Here I want to use the type CSSProperties, but the definition for CSSProperties
// has { [index: number]: string } in its type annotation, which does not satisfy the method
// camelize(s: string)
// Same as the return type
const getStyle = function (element, styleName) {
if (!element || !styleName) {
return '';
}
styleName = camelize(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
const style = element.style[styleName];
if (style) {
return style;
}
const computed = document.defaultView.getComputedStyle(element, '');
return computed ? computed[styleName] : '';
} catch (e) {
return element.style[styleName];
}
};
let scrollBarWidth;
function getScrollBarWidth() {
var _outer$parentNode;
if (scrollBarWidth || scrollBarWidth === 0) {
return scrollBarWidth;
}
const outer = document.createElement('div');
outer.className = 'el-scrollbar__wrap';
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.position = 'absolute';
outer.style.top = '-9999px';
document.body.appendChild(outer);
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
(_outer$parentNode = outer.parentNode) === null || _outer$parentNode === void 0 || _outer$parentNode.removeChild(outer);
scrollBarWidth = widthNoScroll - widthWithScroll;
return scrollBarWidth;
}
function isHtmlElement(el) {
return el && el.nodeType === Node.ELEMENT_NODE;
}
function isScroll(el, isVertical) {
const hasDirection = isVertical !== null && isVertical !== void 0 ? isVertical : '';
const overflow = hasDirection ? isVertical ? getStyle(el, 'overflow-y') : getStyle(el, 'overflow-x') : getStyle(el, 'overflow');
return overflow.match(/(scroll|auto|overlay)/);
}
function getScrollContainer(el, isVertical) {
let parent = el;
while (parent) {
if ([window, document, document.documentElement].includes(parent)) {
return window;
}
if (isScroll(parent, isVertical)) {
return parent;
}
parent = parent.parentNode;
}
return parent;
}
function isInContainer(el, container) {
// 仅适用从右往左进入视口和从下往上进入视口
if (!el || !container) {
return false;
}
const elRect = el.getBoundingClientRect();
let containerRect;
if (container instanceof Element) {
containerRect = container.getBoundingClientRect();
} else {
containerRect = {
top: 0,
right: window.innerWidth,
bottom: window.innerHeight,
left: 0
};
}
return elRect.top < containerRect.bottom && elRect.bottom > containerRect.top && elRect.right > containerRect.left && elRect.left < containerRect.right;
}
export { addClass, getScrollBarWidth, getScrollContainer, getStyle, hasClass, isHtmlElement, isInContainer, isScroll, removeClass };