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

根据可用空间自动切换下拉子菜单展开方向

Fixing Dropdown Submenu Overflow: Dynamic Left/Right Expansion

Got it, let's tackle this dropdown overflow issue! The core problem here is that your .sub-menu-list-right is hardcoded to expand to the right (left: 100%), which causes it to go off-screen when the parent menu item is near the window's right edge. We'll fix this by dynamically checking available space and switching the submenu's direction as needed.

Step 1: Update Your CSS

First, let's add a CSS class to handle the left-expanding state. Keep your existing styles, but add this to support both directions:

/* Default right-expanding submenu */
.sub-menu-list-right {
  top: 0;
  left: 100%;
  /* Keep your existing styles (background, z-index, padding, etc.) */
}

/* New class for left-expanding submenu */
.sub-menu-list-right.sub-menu-left {
  left: auto;
  right: 100%;
}

This gives us a toggleable class to flip the submenu's direction without rewriting all existing styles.

Step 2: Add JavaScript to Detect Space and Adjust Position

We need to check the available space on the right side of the parent menu item when the user hovers over it. Here's how to integrate this into your existing JS code:

(function () {
  handleMenuItems();
  handleSubMenuPosition(); // Add this new function call

  // Your existing handleMenuItems function remains unchanged...
  function handleMenuItems() {
    var menuEl = document.querySelector(".menu"),
        userLinksList = menuEl && menuEl.querySelector(".user-links"),
        recentlyItemListEl = menuEl && menuEl.querySelector(".recently-visited-item"),
        favoriteItemListEl = menuEl && menuEl.querySelector(".favorites-item");

    if (userLinksList) {
      userLinksList.addEventListener("mouseover", function (evt) {
        var options = {
          url: "/api/userlinks",
          method: "GET",
          successCallback: onloadUserLinks
        };

        function onloadUserLinks(result) {
          if (!window.__RAPMD__) {
            window.__RAPMD__ = {};
          }
          window.__RAPMD__.lastUserLinks = result;
          createMenuList(result.RecentLinks, recentlyItemListEl, "No recently visited pages");
          createMenuList(result.Favorites, favoriteItemListEl, "No favorite pages");
        }

        if (!window.__RAPMD__ || !window.__RAPMD__.lastUserLinks) {
          ajax(options);
        }
      });

      userLinksList.addEventListener("mouseleave", function (evt) {
        if (!window.__RAPMD__) {
          return;
        }
        window.__RAPMD__.lastUserLinks = null;
      });
    }
  }

  // New function to handle dynamic submenu positioning
  function handleSubMenuPosition() {
    // Find all parent items that contain a right-facing submenu
    const parentMenuItems = document.querySelectorAll('.header-dropdown-item:has(.sub-menu-list-right)');

    parentMenuItems.forEach(parentItem => {
      const subMenu = parentItem.querySelector('.sub-menu-list-right');
      
      // Listen for hover to check space and adjust direction
      parentItem.addEventListener('mouseover', () => {
        // Temporarily show the submenu to get its width (since it's hidden by default)
        subMenu.style.display = 'block';
        
        // Calculate critical positions and dimensions
        const parentRect = parentItem.getBoundingClientRect();
        const subMenuWidth = subMenu.offsetWidth;
        const availableRightSpace = window.innerWidth - parentRect.right;
        
        // Toggle the left-expanding class based on available space
        if (availableRightSpace < subMenuWidth) {
          subMenu.classList.add('sub-menu-left');
        } else {
          subMenu.classList.remove('sub-menu-left');
        }
        
        // If your CSS uses a custom `shown()` mixin, replace the temporary display with that
        // Example: subMenu.classList.add('shown');
      });

      // Reset the class when hovering out to avoid state carryover
      parentItem.addEventListener('mouseleave', () => {
        subMenu.classList.remove('sub-menu-left');
      });
    });
  }

  // Your existing createMenuList and ajax functions remain unchanged...
  function createMenuList(items, menuItemEl, emptyListTitle) {
    if (!menuItemEl) {
      return;
    }
    var df = document.createDocumentFragment();
    (items.length ? items : [{ Title: emptyListTitle }]).forEach(function (item) {
      var li = document.createElement("li"),
          a = document.createElement("a");
      if (item.Url) {
        a.href = item.Url;
      } else {
        a.classList.add("empty-link-item");
      }
      a.innerHTML = item.Title;
      li.appendChild(a);
      df.appendChild(li);
    });
    menuItemEl.textContent = "";
    menuItemEl.appendChild(df);
  }

  function ajax(options) {
    var url = options.url,
        method = options.method,
        successCallback = options.successCallback,
        failureCallback = options.failureCallback,
        xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (xhr.status === 200 && successCallback) {
        var response = JSON.parse(xhr.responseText);
        successCallback(response);
      } else if (failureCallback) {
        failureCallback();
      }
    };
    xhr.send();
  }
})();

Key Details to Note:

  • Temporary Display: We briefly set display: block on the submenu to get its width because hidden elements (display: none) return 0 for offsetWidth. If your CSS uses visibility: hidden or opacity: 0 instead of display: none, you can skip this step.
  • Parent Positioning: Ensure your .header-dropdown-item has position: relative (which it looks like it does from your existing CSS) so the submenu's right: 100% is relative to the parent's edge.
  • State Reset: We remove the .sub-menu-left class on mouseleave to make sure the submenu behaves correctly if the user hovers again later.

Testing

Try hovering over menu items near the right edge of the window—your submenu should now flip to the left if there's not enough space. For items with plenty of room on the right, it'll keep expanding normally.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:34:06