@qntm-code/utils
Version:
A collection of useful utility functions with associated TypeScript types. All functions have been unit tested.
55 lines (54 loc) • 2.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isVisible = void 0;
const viewport_details_1 = require("viewport-details");
const index_js_1 = require("./index.js");
/**
* Return whether an element is practically visible, considering things like dimensions of 0, opacity, ``visibility: hidden`` and
* ``overflow: hidden``, and whether the item is scrolled off screen
*/
function isVisible(element) {
const rect = element.getBoundingClientRect();
const style = window.getComputedStyle(element);
if (!elementVisible(rect, style)) {
return false;
}
for (const ancestor of (0, index_js_1.getAncestors)(element)) {
const ancestorStyle = window.getComputedStyle(ancestor);
const ancestorRect = ancestor.getBoundingClientRect();
if (!elementVisible(ancestorRect, ancestorStyle, true)) {
return false;
}
if ((ancestorRect.width === 0 || ancestorRect.height === 0) && ancestorStyle.overflow === 'hidden') {
// Zero-sized ancestors don’t make descendants hidden unless the descendant has ``overflow: hidden``
return false;
}
}
return true;
}
exports.isVisible = isVisible;
/**
* Generic internal function for common checks
*/
function elementVisible(rect, style, skipDimensionsCheck = false) {
if (!skipDimensionsCheck && (rect.width === 0 || rect.height === 0)) {
return false;
}
if (style.visibility === 'hidden') {
return false;
}
if (style.opacity === '0') {
return false;
}
// Check if the element is irrevocably off-screen
if ((rect.width === 0 ? rect.x + rect.width < 0 : rect.x + rect.width <= 0) ||
(rect.height === 0 ? rect.y + rect.height < 0 : rect.y + rect.height <= 0)) {
return false;
}
const viewportDetails = (0, viewport_details_1.getViewportDetails)();
if ((rect.width === 0 ? rect.x > viewportDetails.width : rect.x >= viewportDetails.width) ||
(rect.height === 0 ? rect.y > viewportDetails.height : rect.y >= viewportDetails.height)) {
return false;
}
return true;
}