DEV Community

Cover image for Create a JavaScript library. Implement Scroll Lock
Alex Shulaev
Alex Shulaev

Posted on

Create a JavaScript library. Implement Scroll Lock

The basic functionality is implemented, the dev build is working, it's time to expand the general functionality. In this part, I'll add new methods for opening and closing modal windows and work on the scroll behavior.

Add new methods

Earlier, we implemented the init method that initialized all modal windows according to the markup.

 * Open modal window by selector
 * @param {string} selector - Modal window selector
 * @param {ConfigType} config - Modal window configuration
const open = (selector: string, config?: ConfigType) => {
    const options = config || {};
    modal = new Modal({...options, selector});;

The open method has one required parameter, the modal window selector that needs to be opened, and the second parameter is the config. This method creates a new instance of the modal window with the passed selector.

 * Close modal
 * @param {string} selector - Modal window selector
const close = (selector?: string) => {
    if (!modal) return;
    selector ? modal.closeBySelector(selector) : modal.close();

The close method has one optional parameter - a selector. If there are no previously opened modal windows, this function will end its work. If the selector is not passed, the last opened modal window will be closed; if the selector is explicitly passed, the new method closeBySelector will be called. In the Modal class, we implement the closeBySelector method.

 * Close modal window by selector
 * @param {string} selector - Modal window selector to close
closeBySelector(selector: string) {
    const element = document.querySelector<HTMLElement>(selector);
    if (!element) return;
    this.$modal = element;

We are looking for an element by the selector. For the found element, call the close method. If the item is not found, the function will stop its work.

Scroll behavior

Modal windows are more convenient to use when the scroll of the main part of the site is blocked. However, this behavior cannot be strictly defined, since some of the modal windows can be informational and in this case, they should not block the scroll.

Let's expand the modal class configuration. It'll be an object of the following type

export type ConfigType = {
    scrollBehavior?: {
        isDisabled?: boolean;
        container?: string;
        defaultValue?: string;

Define the default value for scrollBehavior

this.scrollBehavior = {
    isDisabled: true,
    container: 'body',
    defaultValue: '',

By default, we'll block the scroll for the body tag. The scroll behavior method will look like this.

 * Change scroll behavior
 * @param {string} value - Scroll state value
changeScrollBehavior(value: 'disable' | 'enable') {
    if (!this.scrollBehavior.isDisabled) return;
    const element = document.querySelector<HTMLElement>(this.scrollBehavior.container);
    if (!element) return;
    if (value === SCROLL_STATE.ENABLE) = this.scrollBehavior.defaultValue;
    else if (value === SCROLL_STATE.DISABLE) = 'hidden';

The method takes one parameter to determine the state of the scroll (there may be one of two options: disable or enable). If isDisabled is false or container is not there, the function should not do anything. Further, depending on the state, we change the overflow value of the element.

I recommend putting any text data into constants to avoid possible typos when using.

export const SCROLL_STATE = {
    DISABLE: 'disable',
    ENABLE: 'enable',
} as const;

The function is ready, add a call to the open and close methods.

open() {

close() {

To check, you can set the height of the body and then open the modal window. When the body tag has style="overflow: hidden;" the content under the modal window should stop scrolling. And after closing the modal window, everything should return to its original state

Thanks for reading! Some improvements to the library are ready, but more improvements are coming. Join me if you are interested. See you soon 👋

Top comments (0)