@opensig/opendesign
Version:
221 lines (220 loc) • 7.56 kB
JavaScript
;
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;