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

动态菜单点击异常求助:无法触发Import From子菜单Device...选项

动态菜单交互问题排查

我遇到一个棘手问题,折腾一整天都没解决。场景是页面里的动态菜单:鼠标悬停顶部File菜单时显示一级菜单,但子菜单不会自动渲染;必须悬停Import From菜单才能调出子菜单,还要在它动态消失前点击Device...选项。我写了下面的代码但完全没用,求帮忙找问题。

原代码

var elements = document.querySelectorAll('.geItem');
for (var i = 0; i < elements.length; i++) {
  if (elements[i].innerHTML === 'File') {
    // 创建点击事件
    var event = new MouseEvent('click', {
      bubbles: true,
      cancelable: true,
      view: window
    });
    (elements[i] as any).click();
    
    setTimeout(() => {
      var menuItems = document.querySelectorAll('td.mxPopupMenuItem[align="left"]');
      var importFromMenu;
      for (var j = 0; j < menuItems.length; j++) {
        var menuItem = menuItems[j];
        if (menuItem.textContent.trim() === "Import from") {
          importFromMenu = menuItem;
          console.log('import from:');
          console.log(importFromMenu);
          (importFromMenu as any).click()
          break;
        }
      }
    }, 2000);
    break; // 只点击第一个匹配的元素
  }
}

菜单层级示意图

菜单层级示意图

页面相关HTML结构

<div class="mxPopupMenu geMenubarMenu" style="display: inline; z-index: 10006; left: 146.969px; top: 345.906px; overflow: hidden auto; max-height: 1300px;">
     <table class="mxPopupMenu">
          <tbody>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Open from</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><img src="data:image/gif;base64,R0lGODlhCQAJAIAAAP///zMzMyH5BAEAAAAALAAAAAAJAAkAAAIPhI8WebHsHopSOVgb26AAADs=" /></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Save</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><span style="color: gray;">Ctrl+S</span></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Rename...</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Import from</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><img src="data:image/gif;base64,R0lGODlhCQAJAIAAAP///zMzMyH5BAEAAAAALAAAAAAJAAkAAAIPhI8WebHsHopSOVgb26AAADs=" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Export as</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><img src="data:image/gif;base64,R0lGODlhCQAJAIAAAP///zMzMyH5BAEAAAAALAAAAAAJAAkAAAIPhI8WebHsHopSOVgb26AAADs=" /></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Embed</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><img src="data:image/gif;base64,R0lGODlhCQAJAIAAAP///zMzMyH5BAEAAAAALAAAAAAJAAkAAAIPhI8WebHsHopSOVgb26AAADs=" /></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">New Library</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><img src="data:image/gif;base64,R0lGODlhCQAJAIAAAP///zMzMyH5BAEAAAAALAAAAAAJAAkAAAIPhI8WebHsHopSOVgb26AAADs=" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Open Library from</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"><img src="data:image/gif;base64,R0lGODlhCQAJAIAAAP///zMzMyH5BAEAAAAALAAAAAAJAAkAAAIPhI8WebHsHopSOVgb26AAADs=" /></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Properties...</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"></td>
               </tr>
          </tbody>
     </table>
</div>

<div class="mxPopupMenu" style="position: absolute; display: inline; z-index: 10006; left: 385px; top: 537px; overflow: hidden auto; max-height: 1186px;">
     <table class="mxPopupMenu">
          <tbody>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Device...</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"></td>
               </tr>
               <tr>
                    <td class="mxPopupMenuIcon" style="padding: 0px;"></td>
                    <td colspan="2" style="padding: 0px;"><hr size="1" /></td>
               </tr>
               <tr class="mxPopupMenuItem">
                    <td class="mxPopupMenuIcon"></td>
                    <td class="mxPopupMenuItem" align="left">Dwp Library</td>
                    <td class="mxPopupMenuItem" style="padding-right: 6px; text-align: right;"></td>
               </tr>
          </tbody>
     </table>
</div>

问题排查与修复方案

1. 核心错误:用点击事件替代悬停触发

菜单的展开逻辑是鼠标悬停触发,不是点击。原代码调用click()可能会触发菜单关闭或其他无关逻辑,应该模拟mouseover和mouseenter事件。

2. Import From子菜单未处理

原代码只点击了Import From,但子菜单需要悬停才会渲染,而且要等子菜单渲染完成后再点击Device...,不能跳过悬停步骤。

3. 元素选择器精度不足

原选择器会同时选中一级菜单和子菜单的元素,建议通过父元素类区分:

  • 一级菜单:.geMenubarMenu td.mxPopupMenuItem[align="left"]
  • 子菜单:.mxPopupMenu:not(.geMenubarMenu) td.mxPopupMenuItem[align="left"]

4. 固定延迟不可靠

用固定setTimeout容易因为页面加载速度波动失效,改用MutationObserver监听子菜单节点变化更稳定。


修复后的完整代码

// 找到File菜单
const fileMenu = Array.from(document.querySelectorAll('.geItem'))
  .find(item => item.innerHTML === 'File');

if (fileMenu) {
  // 模拟鼠标悬停展开File菜单
  const hoverEvents = [
    new MouseEvent('mouseover', { bubbles: true, cancelable: true, view: window }),
    new MouseEvent('mouseenter', { bubbles: true, cancelable: true, view: window })
  ];
  hoverEvents.forEach(evt => fileMenu.dispatchEvent(evt));

  // 等待一级菜单渲染
  setTimeout(() => {
    // 找到Import from菜单
    const importFromMenu = Array.from(document.querySelectorAll('.geMenubarMenu td.mxPopupMenuItem[align="left"]'))
      .find(item => item.textContent.trim() === "Import from");
    
    if (importFromMenu) {
      // 模拟悬停展开子菜单
      hoverEvents.forEach(evt => importFromMenu.dispatchEvent(evt));

      // 监听子菜单出现,找到后点击Device...
      const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
          if (mutation.addedNodes.length) {
            const deviceItem = Array.from(document.querySelectorAll('.mxPopupMenu:not(.geMenubarMenu) td.mxPopupMenuItem[align="left"]'))
              .find(item => item.textContent.trim() === "Device...");
            if (deviceItem) {
              deviceItem.click();
              observer.disconnect(); // 完成后停止监听
            }
          }
        }
      });

      // 监听页面节点变化,范围可以缩小到菜单容器提升性能
      observer.observe(document.body, { childList: true, subtree: true });
    }
  }, 800); // 根据实际页面渲染速度调整延迟
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:02:05