Code Snippets

Mobile menu factory

export function createMobileMenu(
    bodyOpenClass,
    mobileMenuTogglers,
    mobileMenuLinks,
) {
    function _toggleMobileMenu() {
        const shouldOpen = !document.body.classList.contains(bodyOpenClass);

        const classListMethod = shouldOpen ? "add" : "remove";
        const tabIndex = shouldOpen ? 0 : -1;

        document.body.classList[classListMethod](bodyOpenClass);

        mobileMenuLinks.forEach((link) => (link.tabIndex = tabIndex));
    }

    function init() {
        mobileMenuTogglers.forEach((element) =>
            element.addEventListener("click", _toggleMobileMenu),
        );
    }

    return Object.freeze({
        init,
    });
}

This code snippet defines a factory function (a function used to create objects) for creating a mobile menu object. When the init function is run on the mobile menu object, click event handlers are setup for the supplied elements, which will do the following:

  • Toggle the body class (used for styling menu elements)
  • Toggle the ability to tab to links within the menu (improving accessibility)

This modular approach allows easy integration into other projects, promoting code reusability.

addGlobalEventListener Function

export function addGlobalEventListener(type, selector, callback) {
    document.addEventListener(type, (e) => {
        if (e.target.closest(selector)) callback(e);
    });
}

This function, addGlobalEventListener, is a utility to add event listeners globally to the document, but only trigger the callback when events originate from elements that match a specific CSS selector.

  • type: The type of event to listen for (e.g., 'click', 'mouseover').
  • selector: A CSS selector string used to filter events based on the originating element.
  • callback: The function to execute when the event occurs on an element that matches the selector.

The function works by attaching an event listener to the entire document. Inside the event listener, it checks if the event's target element, or any of its ancestors, matches the provided selector. If a match is found, the callback function is executed.

This approach is particularly useful for handling events on elements that are dynamically added to the page, as the event listener is attached to a permanent element (the document) rather than the dynamic elements themselves.

Storage module

const STORAGE_KEY_USERS = "USERS";
const STORAGE_KEY_ACTIVE_USER_ID = "ACTIVE_USER_ID";

function get(key) {
    return JSON.parse(localStorage.getItem(key));
}

function set(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
}

function getUsers() {
    return get(STORAGE_KEY_USERS);
}

function setUsers(users) {
    set(STORAGE_KEY_USERS, users);
}

function getActiveUser() {
    return get(STORAGE_KEY_ACTIVE_USER_ID);
}

function setActiveUser(activeUser) {
    set(STORAGE_KEY_ACTIVE_USER_ID, activeUser);
}

export default {
    getUsers,
    setUsers,
    getActiveUser,
    setActiveUser,
};

This code snippet demonstrates a practical approach to manage user data in web applications using the Web Storage API's localStorage. It consists of utility functions for handling operations like retrieving and storing user information and the active user's ID. The snippet is particularly useful for applications that require client-side state management without a backend database.

Key Features:

  • Storage Keys: Uses constants STORAGE_KEY_USERS and STORAGE_KEY_ACTIVE_USER_ID as keys for localStorage.
  • get and set Functions: Abstracts localStorage operations for parsing and stringifying JavaScript objects.
  • User Management Functions:
    • getUsers and setUsers for handling the users' list.
    • getActiveUser and setActiveUser for managing the active user ID.
  • Modular Export: Functions are exported as a module for easy reuse across the application.