SmartNavigation.js

Your GPS, but cooler.

SmartNavigation.js is a powerful, accessible, and secure JavaScript library for creating dynamic navigation menus. It provides a comprehensive set of tools for building interactive navigation systems with support for nested menus, accordion behavior, keyboard navigation, and more.

Pro Tip: SmartNavigation.js is built with security in mind, featuring built-in sanitization for URLs and HTML content, making it resistant to XSS attacks.

Installation

Include the SmartNavigation.js script in your HTML file:

<script src="path/to/smartNavigation.js"></script>

Basic initialization

// Initialize with default options
const nav = new Navigation('#navigation');

// Or with custom options
const nav = new Navigation('#navigation', {
    accordion: true,
    slideUpSpeed: 300,
    slideDownSpeed: 300,
    debug: false,
    maxDepth: 10
});

HTML Structure

<nav id="navigation">
    <ul>
        <li>
            <a href="#">Parent Item</a>
            <ul>
                <li><a href="page1.html">Child Item 1</a></li>
                <li><a href="page2.html">Child Item 2</a></li>
                <li>
                    <a href="#">Child Item 3</a>
                    <ul>
                        <li><a href="subpage1.html">Grandchild Item 1</a></li>
                        <li><a href="subpage2.html">Grandchild Item 2</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li><a href="about.html">About</a></li>
        <li><a href="contact.html">Contact</a></li>
    </ul>
</nav>
Important: The navigation element must contain a <ul> element as its child. Each menu item should be an <li> element containing an <a> element.

Configuration Options

SmartNavigation.js offers extensive configuration options to customize its behavior:

Option Default Value Description Type
accordion true When enabled, only one submenu at the same level can be open at a time. boolean
slideUpSpeed 200 Duration in milliseconds for the submenu collapse animation. number
slideDownSpeed 200 Duration in milliseconds for the submenu expand animation. number
closedSign '<i class="sa sa-chevron-down"></i>' HTML for the icon displayed next to closed submenus. string
openedSign '<i class="sa sa-chevron-up"></i>' HTML for the icon displayed next to opened submenus. string
initClass 'js-nav-built' CSS class added to the navigation element after initialization. string
debug false When enabled, logs detailed information about the navigation's operations to the console. boolean
instanceId auto-generated Unique identifier for the navigation instance, used in debug logs and data attributes. string
maxDepth 10 Maximum nesting depth allowed for submenus to prevent excessive nesting. number
sanitize true When enabled, sanitizes URLs and HTML content to prevent XSS attacks. boolean
animationTiming 'easeOutExpo' Timing function for animations. Can be any valid CSS timing function. string
debounceTime 0 Time in milliseconds to debounce click events to prevent rapid repeated clicks. number
onError null Callback function that is called when an error occurs. Function|null
showMore.enabled true When enabled, adds a "Show more" toggle for submenus with many items. boolean
showMore.itemsToShow 4 Number of items to show before collapsing the rest behind a "Show more" toggle. number
showMore.minItemsForToggle 2 Minimum number of hidden items required to show the "Show more" toggle. number
showMore.moreText 'Show {count} more' Text for the "Show more" toggle, where {count} is replaced with the number of hidden items. string
showMore.lessText 'Show less' Text for the "Show less" toggle when hidden items are visible. string

Advanced Configuration Example

Here's an example of how to configure SmartNavigation with advanced options:

const nav = new Navigation('#navigation', {
    accordion: true,
    slideUpSpeed: 300,
    slideDownSpeed: 300,
    closedSign: '<i class="fa fa-plus"></i>',
    openedSign: '<i class="fa fa-minus"></i>',
    initClass: 'nav-initialized',
    debug: true,
    instanceId: 'main-navigation',
    maxDepth: 5,
    sanitize: true,
    animationTiming: 'ease-in-out',
    debounceTime: 100,
    onError: function(error) {
        console.error('Navigation error:', error);
    },
    showMore: {
        enabled: true,
        itemsToShow: 5,
        minItemsForToggle: 3,
        moreText: 'View {count} more items',
        lessText: 'Collapse items'
    }
});

API Methods

SmartNavigation.js exposes several methods for programmatic control:

// Get an existing navigation instance
const nav = Navigation.getInstance('#navigation');

// Initialize multiple navigation elements at once
const navs = Navigation.initAll('.navigation', options);

// Initialize navigation on DOM content loaded
Navigation.initOnLoad(options);

// Destroy all navigation instances
Navigation.destroyAll();

Instance Methods

// Create a new menu item
const parentItem = nav.createMenuItem({
    text: 'Parent Menu',
    url: '#',
    hasSubmenu: true
});

// Create a child menu item
const childItem = nav.createMenuItem({
    text: 'Child Menu',
    url: 'https://example.com',
    parent: parentItem
});

// Update an existing menu item
nav.updateMenuItem(childItem, {
    text: 'Updated Text',
    url: 'https://newurl.com'
});

// Move a menu item to a new parent
nav.moveMenuItem(childItem, anotherParent);

// Remove a menu item
nav.removeMenuItem(childItem);

// Toggle all submenus open or closed
nav.toggleAll(true);  // Open all
nav.toggleAll(false); // Close all

// Close all open submenus
nav.closeAllSubmenus();

// Focus a specific menu item
nav.focusItem(menuItem);

// Destroy the navigation instance
nav.destroy();

Accessibility Features

SmartNavigation.js is built with accessibility in mind, providing:

  • ARIA attributes: Automatically adds appropriate ARIA roles, states, and properties
  • Keyboard navigation: Full keyboard support for navigating the menu
  • Focus management: Proper focus handling for screen readers
  • Semantic markup: Uses proper HTML structure for navigation
// Keyboard navigation support
// Enter/Space: Toggle submenu
// Escape: Close submenu and return focus to parent
// Arrow Down/Up: Navigate between menu items
// Tab: Navigate through focusable elements
Pro Tip: The navigation automatically adds aria-expanded and aria-haspopup attributes to menu items with submenus, making them accessible to screen readers.

Security Features

SmartNavigation.js includes several security features to protect against common vulnerabilities:

HTML Sanitization

// Sanitizes HTML content to prevent XSS attacks
const sanitizedHTML = Navigation.sanitizeHTML(htmlString);

// Removes potentially dangerous attributes and scripts
// Strips event handlers (onclick, onmouseover, etc.)
// Prevents script injection

URL Validation

// Validates URLs to prevent javascript: protocol and other unsafe URLs
const isValid = Navigation.isValidUrl(url);

// Checks for:
// - Valid URL format
// - Prevents javascript: URLs
// - Prevents data: URLs
// - Prevents other potentially dangerous protocols
Important: Always keep the sanitize option enabled in production environments to protect against XSS attacks.

Show More Feature

The "Show More" feature helps manage large navigation menus by collapsing excess items:

// Configure the Show More feature
const nav = new Navigation('#navigation', {
    showMore: {
        enabled: true,           // Enable the feature
        itemsToShow: 4,          // Show first 4 items
        minItemsForToggle: 2,    // Only show toggle if at least 2 items are hidden
        moreText: 'Show {count} more items',  // Text for the toggle (expanded)
        lessText: 'Show fewer items'          // Text when collapsed
    }
});

The Show More feature automatically:

  • Identifies non-parent items (items without submenus) to collapse
  • Keeps parent items (with submenus) always visible
  • Adds a toggle button to show/hide the collapsed items
  • Automatically expands if any hidden item is active
Pro Tip: The Show More feature is particularly useful for mobile navigation where space is limited, helping to keep the most important navigation items visible.

Event Handling

SmartNavigation.js uses secure event handling to manage user interactions:

// Click event handling
element.addEventListener('mousedown', nav.handleClick, { passive: true });

// Keyboard event handling
element.addEventListener('keydown', nav.handleKeydown);

// Debounced event handling to prevent rapid repeated clicks
const debouncedHandler = nav.debounce(function() {
    // Handler code
}, 100);

The navigation responds to the following events:

  • mousedown: Toggles submenus when clicking on parent items
  • keydown: Handles keyboard navigation and accessibility
  • transitionend: Manages animation completion for smooth transitions

Animation System

SmartNavigation.js includes a sophisticated animation system for smooth transitions:

// Animate height of an element
nav.animateHeight(element, 'down', callback);  // Expand
nav.animateHeight(element, 'up', callback);    // Collapse

// Animation options
const nav = new Navigation('#navigation', {
    slideUpSpeed: 300,           // Collapse animation duration
    slideDownSpeed: 300,         // Expand animation duration
    animationTiming: 'ease-in-out'  // CSS timing function
});

The animation system:

  • Uses CSS transitions for smooth, hardware-accelerated animations
  • Properly measures and animates content height
  • Handles animation completion with callbacks
  • Prevents animation conflicts with state tracking

Best Practices

  • Keep your navigation structure reasonably flat (avoid excessive nesting)
  • Use the maxDepth option to prevent performance issues from deep nesting
  • Enable the showMore feature for large menus to improve usability
  • Use the debug option during development to troubleshoot issues
  • Always keep the sanitize option enabled in production
  • Use semantic HTML structure for your navigation
Pro Tip: For large applications, use Navigation.initAll() to initialize multiple navigation components with the same configuration.

Troubleshooting

Common Issues:
  • Navigation not initializing? Check that your HTML structure includes a <ul> element inside the navigation container.
  • Submenus not expanding? Ensure your HTML structure is correct with proper nesting of <li> and <ul> elements.
  • Animation issues? Try adjusting the slideUpSpeed and slideDownSpeed options, or check for CSS conflicts.
  • Security errors? Make sure URLs are valid and HTML content is safe when using createMenuItem or updateMenuItem.
  • Performance issues? Reduce the depth of your navigation structure or increase the debounceTime to prevent rapid interactions.