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});
modal.open();
};
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;
this.close();
}
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: '',
...scrollBehavior,
};
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)
element.style.overflow = this.scrollBehavior.defaultValue;
else if (value === SCROLL_STATE.DISABLE) element.style.overflow = '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() {
this.$modal?.classList.add(this.openClass);
this.changeScrollBehavior(SCROLL_STATE.DISABLE);
this.addEventListeners();
}
close() {
this.$modal?.classList.remove(this.openClass);
this.changeScrollBehavior(SCROLL_STATE.ENABLE);
this.removeEventListeners();
}
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)