UNPKG

@fesjs/fes-design

Version:
152 lines (146 loc) 4.38 kB
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 };