You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDSmoothmenu键盘箭头键失效及长菜单超出页面问题求助

Hey there! Let's tackle those two ddsmoothmenu issues you're facing—keyboard arrow navigation not working, and long <li> lists overflowing the page. Here's how to fix both problems step by step:

Fixing ddsmoothmenu Keyboard Navigation & Overflow Issues

1. Adding Keyboard Arrow Key Support

DD Smooth Menu doesn't include native keyboard accessibility by default, so we'll add custom JavaScript to handle arrow key navigation, focus management, and activation.

Step 1: Ensure Focusable Elements

First, confirm all menu links (<a> tags) have tabindex="0" (they usually do by default, but double-check if any are missing). This makes them reachable via tab key.

Step 2: Implement Keyboard Navigation Script

Add this script after your ddsmoothmenu initialization code:

document.addEventListener('DOMContentLoaded', function() {
    const topLevelLinks = document.querySelectorAll('#divMenu > ul > li > a');
    let currentFocusIndex = -1;

    // Handle keydown events on top-level menu items
    topLevelLinks.forEach((link, index) => {
        link.addEventListener('keydown', function(e) {
            switch(e.key) {
                case 'ArrowRight':
                    e.preventDefault();
                    currentFocusIndex = (index + 1) % topLevelLinks.length;
                    topLevelLinks[currentFocusIndex].focus();
                    // Open submenu if it exists
                    openSubmenu(topLevelLinks[currentFocusIndex]);
                    break;
                case 'ArrowLeft':
                    e.preventDefault();
                    currentFocusIndex = (index - 1 + topLevelLinks.length) % topLevelLinks.length;
                    topLevelLinks[currentFocusIndex].focus();
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    // Open current submenu and focus first item
                    const submenu = this.parentElement.querySelector('ul');
                    if (submenu) {
                        submenu.style.display = 'block';
                        const firstSubLink = submenu.querySelector('li > a');
                        if (firstSubLink) firstSubLink.focus();
                    }
                    break;
                case 'Escape':
                    // Close all submenus and return focus to current top-level item
                    closeAllSubmenus();
                    this.focus();
                    break;
                case 'Enter':
                case ' ':
                    e.preventDefault();
                    // Trigger click action for the link
                    this.click();
                    break;
            }
        });
    });

    // Handle focus entering the menu container
    document.querySelector('#divMenu').addEventListener('focusin', function() {
        if (currentFocusIndex === -1) {
            currentFocusIndex = 0;
            topLevelLinks[0].focus();
        }
    });

    // Helper functions
    function openSubmenu(link) {
        closeAllSubmenus();
        const submenu = link.parentElement.querySelector('ul');
        if (submenu) submenu.style.display = 'block';
    }

    function closeAllSubmenus() {
        document.querySelectorAll('#divMenu ul ul').forEach(sub => sub.style.display = 'none');
    }
});

This script handles:

  • Left/Right arrows to navigate top-level menu items
  • Down arrow to open submenus and focus the first submenu item
  • Escape to close all submenus
  • Enter/Space to activate menu items

2. Fixing Overflowing Menu Items

When dropdowns extend beyond the viewport, we need to dynamically adjust their position to keep them visible. Here are two approaches:

Option 1: Modify the ddsmoothmenu Plugin Code

Find the section in ddsmoothmenu.js where submenus are positioned (look for code setting left or top styles). Add this logic to check viewport boundaries:

// For horizontal menus (orientation: 'h')
const viewportWidth = window.innerWidth;
const submenuWidth = submenu.offsetWidth;
const parentRight = parentItem.getBoundingClientRect().right;

// Flip dropdown to left if it would go off the right edge
if (parentRight + submenuWidth > viewportWidth) {
    submenu.style.left = `-${submenuWidth - parentItem.offsetWidth}px`;
} else {
    submenu.style.left = '0';
}

// For vertical menus (orientation: 'v')
const viewportHeight = window.innerHeight;
const submenuHeight = submenu.offsetHeight;
const parentBottom = parentItem.getBoundingClientRect().bottom;

// Flip dropdown upward if it would go off the bottom edge
if (parentBottom + submenuHeight > viewportHeight) {
    submenu.style.top = `-${submenuHeight}px`;
} else {
    submenu.style.top = '0';
}

Option 2: Add a Post-Initialization Script (No Plugin Modification)

If you don't want to edit the original plugin, add this script after your ddsmoothmenu init:

ddsmoothmenu.init({ 
    mainmenuid: "divMenu", 
    orientation: 'h', 
    classname: 'ddsmoothmenu', 
    contentsource: "markup",
    oninit: function() {
        adjustSubmenuPositions();
        // Re-adjust on window resize
        window.addEventListener('resize', adjustSubmenuPositions);
    }
});

function adjustSubmenuPositions() {
    const submenus = document.querySelectorAll('#divMenu ul ul');
    submenus.forEach(submenu => {
        const parent = submenu.parentElement;
        const parentRect = parent.getBoundingClientRect();
        const submenuRect = submenu.getBoundingClientRect();

        // Fix horizontal overflow
        if (parentRect.right + submenuRect.width > window.innerWidth) {
            submenu.style.left = `-${submenuRect.width - parent.offsetWidth}px`;
        } else {
            submenu.style.left = ''; // Reset to default
        }

        // Fix vertical overflow (if using vertical menu)
        if (parentRect.bottom + submenuRect.height > window.innerHeight) {
            submenu.style.top = `-${submenuRect.height}px`;
        } else {
            submenu.style.top = ''; // Reset to default
        }
    });
}

CSS Tweak to Prevent Clipping

Ensure submenus aren't clipped by parent elements:

.ddsmoothmenu ul ul {
    position: absolute;
    overflow: visible !important; /* Ensure submenus aren't hidden */
    /* Keep your existing styles */
}

Final Tips

  • Test keyboard navigation across all menu levels to ensure smooth behavior.
  • Adjust the overflow logic if your menu has custom margins/padding that affect positioning.
  • Check the ddsmoothmenu documentation—some versions have a built-in dropdownalign option you can use instead of custom code.

内容的提问来源于stack exchange,提问作者Ankur vijay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:44