@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
45 lines (44 loc) • 1.93 kB
JavaScript
import { isElement, getNodeName, getParentNode } from '../api';
/**
* Get the list of all scroll parents, up the list of ancestors until we get to the top window object.
* @param element - element for which you want to get the list of all scroll parents
* @param root - element which element considered a final scrollable parent target (optional, defaults to element.ownerDocument?.body)
*/
export function getListScrollParents(element, root) {
var _a;
const limitNode = root || ((_a = element.ownerDocument) === null || _a === void 0 ? void 0 : _a.body);
const scrollParent = getScrollParent(element, limitNode);
if (!scrollParent)
return [];
const isScrollableTarget = scrollParent === limitNode;
if (isScrollableTarget)
return isScrollable(scrollParent) ? [scrollParent] : [];
return [scrollParent].concat(getListScrollParents(getParentNode(scrollParent), limitNode));
}
export function getScrollParent(node, root) {
var _a;
if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
return (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.body;
}
if (isElement(node) && isScrollable(node))
return node;
if (node === root)
return;
return getScrollParent(getParentNode(node), root);
}
/**
* Check that element is scroll parent.
* @param element - element for checking
* */
export function isScrollable(element) {
// Firefox wants us to check `-x` and `-y` variations as well
const { overflow, overflowX, overflowY } = getComputedStyle(element);
return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
}
/**
* Get the element that is the viewport for the specified element.
* @param node - element for which to get the viewport
*/
export function getViewportForEl(node) {
return getListScrollParents(node).find((el) => el.scrollHeight !== el.clientHeight);
}