UNPKG

@opensig/opendesign

Version:

221 lines (220 loc) 7.56 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const easing = require("./easing.js"); const helper = require("./helper.js"); const is = require("./is.js"); function isDocument(val) { return val instanceof Document || (val == null ? void 0 : val.constructor.name) === "HTMLDocument"; } function isHtmlElement(el) { if (typeof HTMLElement === "object") { return el instanceof HTMLElement; } else if (el && typeof el === "object") { const ele = el; return (ele.nodeType === 1 || ele.nodeType === 9) && typeof ele.nodeName === "string"; } return false; } function getOffsetElement(el) { const offsetEl = el.offsetParent; if (offsetEl && offsetEl.tagName === "BODY") { const stylePosition = window.getComputedStyle(document.body).getPropertyValue("position"); if (stylePosition === "static") { return document.documentElement; } } return offsetEl; } function getScroll(el) { const rlt = { scrollLeft: 0, scrollTop: 0 }; if (!el) { return rlt; } if (is.isWindow(el)) { rlt.scrollLeft = window.scrollX; rlt.scrollTop = window.scrollY; } else if (isDocument(el)) { rlt.scrollLeft = el.documentElement.scrollLeft; rlt.scrollTop = el.documentElement.scrollTop; } else { rlt.scrollLeft = el.scrollLeft; rlt.scrollTop = el.scrollTop; } return rlt; } function getScrollParents(el) { const parents = []; let ele = el == null ? void 0 : el.parentElement; while (ele && ele !== document.documentElement) { const { offsetHeight, offsetWidth, scrollHeight, scrollWidth } = ele; if (offsetHeight < scrollHeight || offsetWidth < scrollWidth) { parents.push(ele); } ele = ele.parentElement; } return parents; } function findClosestElementWithClass(target, className, rootContainer) { if (!(target instanceof HTMLElement)) { return null; } let currentElement = target; while (currentElement && currentElement !== rootContainer) { if (currentElement.classList && currentElement.classList.contains(className)) { return currentElement; } currentElement = currentElement.parentElement; } return null; } function getElementSize(el) { return { width: el.innerWidth || el.clientWidth, height: el.innerHeight || el.clientHeight, offsetWidth: el.innerWidth || el.offsetWidth, offsetHeight: el.innerHeight || el.offsetHeight }; } function getElementRectByRAF(el) { return new Promise((resolve) => { const checkLayout = () => { const rect = el.getBoundingClientRect(); if (rect.width > 0 || rect.height > 0) { resolve(rect); } else { requestAnimationFrame(checkLayout); } }; requestAnimationFrame(checkLayout); }); } function getCssVariable(key, el) { const ele = el ? el : document.documentElement; return window.getComputedStyle(ele).getPropertyValue(key); } function supportTouch() { return "ontouchstart" in window; } let cancelScrollRAF = null; function scrollTo(y, opts) { const { container = window, duration = 450 } = opts; const { scrollTop } = getScroll(container); const startTime = Date.now(); if (is.isFunction(cancelScrollRAF)) { cancelScrollRAF(); cancelScrollRAF = null; } return new Promise((resolve) => { const frameFn = () => { const timeStamp = Date.now(); const time = timeStamp - startTime; const nextScrollTop = easing.easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration); if (is.isWindow(container)) { window.scrollTo({ left: window.scrollX, top: nextScrollTop, behavior: "instant" }); } else if (isDocument(container)) { container.documentElement.scrollTop = nextScrollTop; } else { container.scrollTop = nextScrollTop; } if (time < duration) { const fn = helper.throttleRAF(frameFn); cancelScrollRAF = fn.cancel; fn(); } else { helper.throttleRAF(resolve)(); } }; helper.throttleRAF(frameFn)(); }); } function isOverflown(element) { if (!element) { return false; } return element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight; } function checkElementOverflowHorizontal(options) { const { element, parentElement, threshold = 0 } = options; if (!(element instanceof HTMLElement)) { throw new Error("参数必须是有效的HTMLElement"); } const scrollParent = parentElement ? parentElement : getScrollParents(element)[0]; if (!scrollParent) { return { isOverflowLeft: false, isOverflowRight: false, overflowLeft: 0, overflowRight: 0 }; } const elementRect = element.getBoundingClientRect(); const parentRect = scrollParent.getBoundingClientRect(); const elementLeftRelativeToParent = elementRect.left - parentRect.left + scrollParent.scrollLeft; const elementRightRelativeToParent = elementLeftRelativeToParent + elementRect.width; const parentVisibleLeft = scrollParent.scrollLeft; const parentVisibleRight = scrollParent.scrollLeft + scrollParent.clientWidth; const overflowLeft = parentVisibleLeft - elementLeftRelativeToParent; const isOverflowLeft = overflowLeft > threshold; const overflowRight = elementRightRelativeToParent - parentVisibleRight; const isOverflowRight = overflowRight > threshold; return { isOverflowLeft, isOverflowRight, overflowLeft, overflowRight }; } function checkElementOverflowVertical(options) { const { element, parentElement, threshold = 0 } = options; if (!(element instanceof HTMLElement)) { throw new Error("参数必须是有效的HTMLElement"); } const scrollParent = parentElement ? parentElement : getScrollParents(element)[0]; if (!scrollParent) { return { isOverflowTop: false, isOverflowBottom: false, overflowTop: 0, overflowBottom: 0 }; } const elementRect = element.getBoundingClientRect(); const parentRect = scrollParent.getBoundingClientRect(); const elementTopRelativeToParent = elementRect.top - parentRect.top + scrollParent.scrollTop; const elementBottomRelativeToParent = elementTopRelativeToParent + elementRect.height; const parentVisibleTop = scrollParent.scrollTop; const parentVisibleBottom = scrollParent.scrollTop + scrollParent.clientHeight; const overflowTop = parentVisibleTop - elementTopRelativeToParent; const isOverflowTop = overflowTop > threshold; const overflowBottom = elementBottomRelativeToParent - parentVisibleBottom; const isOverflowBottom = overflowBottom > threshold; return { isOverflowTop, isOverflowBottom, overflowTop, overflowBottom }; } function checkElementOverflow(options) { return { ...checkElementOverflowHorizontal(options), ...checkElementOverflowVertical(options) }; } exports.checkElementOverflow = checkElementOverflow; exports.checkElementOverflowHorizontal = checkElementOverflowHorizontal; exports.checkElementOverflowVertical = checkElementOverflowVertical; exports.findClosestElementWithClass = findClosestElementWithClass; exports.getCssVariable = getCssVariable; exports.getElementRectByRAF = getElementRectByRAF; exports.getElementSize = getElementSize; exports.getOffsetElement = getOffsetElement; exports.getScroll = getScroll; exports.getScrollParents = getScrollParents; exports.isDocument = isDocument; exports.isHtmlElement = isHtmlElement; exports.isOverflown = isOverflown; exports.scrollTo = scrollTo; exports.supportTouch = supportTouch;