Check if an element is visible
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** isVisible | |
* | |
* Determines whether an element is visible within the (specified, or Window) viewport. Executes the callback based | |
* on that result. The callback is called with two parameters: a boolean that's true if the element is visible, along | |
* with the element's bounding box, including 'pageY' and 'pageX' which contain the element's position as relative to | |
* the whole document. Useful for scrolling into view. | |
* | |
* The viewport can be omitted, specified partially or completely. | |
* | |
* Usage: isVisible(myElement, callback, {viewport object}); | |
* | |
* @param {Element} element - The element to check | |
* @param {Function} callback - The callback function to execute when done checking | |
* @param {Object} viewport - The viewport object (optional) - falls back to the window if not provided | |
* @param {number} viewport.top - The top position of the viewport (optional) | |
* @param {number} viewport.bottom - The bottom position of the viewport (optional) | |
* @param {number} viewport.left - The left position of the viewport (optional) | |
* @param {number} viewport.right - The right position of the viewport (optional) | |
* | |
*/ | |
export function isVisible(element, callback, viewport = {}) { | |
if (!(element instanceof Element)) { | |
throw new TypeError('Not a valid node'); | |
} | |
if (typeof element.getBoundingClientRect === 'function') { | |
const rect = element.getBoundingClientRect(); | |
const scrollTop = window.pageYOffset || document.documentElement.scrollTop; | |
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; | |
const clientTop = document.documentElement.clientTop; | |
const clientLeft = document.documentElement.clientLeft; | |
rect.pageY = rect.top + scrollTop - clientTop; | |
rect.pageX = rect.left + scrollLeft - clientLeft; | |
viewport = { | |
top: typeof viewport.top !== 'undefined' ? viewport.top : 0, | |
bottom: typeof viewport.bottom !== 'undefined' ? viewport.bottom : window.innerHeight || document.documentElement.clientHeight, | |
left: typeof viewport.left !== 'undefined' ? viewport.left : 0, | |
right: typeof viewport.right !== 'undefined' ? viewport.right : window.innerWidth || document.documentElement.clientWidth, | |
}; | |
const vis = ( | |
(rect.height > 0 || rect.width > 0) && | |
rect.bottom < viewport.bottom && | |
rect.right < viewport.right && | |
rect.top > viewport.top && | |
rect.left > viewport.left | |
); | |
if (typeof callback === 'function') { | |
callback.call(this, vis, rect); | |
} | |
} else { | |
//console.error('Can\'t check visibility for', typeof this, this); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment