dom_body-lock.js

import browsers from './browsers';

let scroll = 0;

/**
 * @module getScroller
 * @description Returns the scrolling element for the body. Edge uses document.documentElement while most others
 * use document.body.
 *
 * @since 1.0.0
 *
 * @requires browsers
 *
 * @return {HTMLElement} Either `document.documentElement` for edge or `document.body` for other browsers.
 *
 * @example
 * import { bodyLock } from  "@gravityforms/utils";
 *
 * const scroller = bodyLock.getScroller();
 * const scroll = scroller.scrollTop;
 *
 */
const getScroller = () => {
	const browser = browsers();
	return browser.ie || browser.firefox || ( browser.chrome && ! browser.edge )
		? document.documentElement
		: document.body;
};

/**
 * @module lock
 * @description Lock the body at a particular position and prevent scroll,
 * uses margin on the scroll element to simulate original scroll position if @param setOffset is passed
 * as true. Usually called when opening a modal or flyout, and you don't want the body scrolling behind the
 * item.
 *
 * @since 1.0.0
 *
 * @param {boolean} setOffset Whether to apply the margin offset.
 *
 * @requires getScroller
 *
 * @return {void}
 *
 * @example
 * import { bodyLock } from  "@gravityforms/utils";
 *
 * function Example() {
 *   bodyLock.lock();
 * }
 *
 */
const lock = ( setOffset = true ) => {
	const scroller = getScroller();
	const style = document.body.style;
	scroll = scroller.scrollTop;

	style.overflowY = 'scroll';
	style.position = 'fixed';
	style.width = '100%';
	if ( setOffset ) {
		style.marginTop = `-${ scroll }px`;
	}
};

/**
 * @module unlock
 * @description Unlock the body and return it to its actual scroll position. Usually called when closing
 * a modal or flyout.
 *
 * @since 1.0.0
 *
 * @requires getScroller
 *
 * @return {void}
 *
 * @example
 * import { bodyLock } from  "@gravityforms/utils";
 *
 * function Example() {
 *   bodyLock.unlock();
 * }
 *
 */
const unlock = () => {
	const scroller = getScroller();
	const style = document.body.style;

	style.overflowY = '';
	style.position = 'static';
	style.marginTop = '0px';
	style.width = '';

	scroller.scrollTop = scroll;
};

export { getScroller, lock, unlock };