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

如何修复Metronic旧版菜单脚本中waitForKeyElements的无限循环问题?

我看你这脚本是遇到无限循环的坑了——用户名一直重复显示,哪怕设了bWaitOnce: true也没用对吧?大概率是因为你修改DOM之后,waitForKeyElements又检测到了目标元素,反复触发回调函数,形成了闭环。给你几个实用的修复方案:

方案1:添加全局标记+存在性检查,彻底阻止重复执行

在脚本里加一个全局标记,同时在回调里检查目标菜单是否已经存在,双保险避免重复生成元素:

// ==UserScript==
// @name Fix User Dropdown
// @description Fixes the user dropdown to match current version.
// @include mywebsite.com
// @version 2.0.1
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant GM_addStyle
// @grant GM.getValue
// ==/UserScript==

// 全局标记:如果已经修复过下拉菜单,直接退出脚本
if (window.hasFixedUserDropdown) return;
window.hasFixedUserDropdown = true;

waitForKeyElements(".topMenu1", addUserDropdown, true);

function addUserDropdown(jNode) {
    $('#greetingName').remove();
    var userSession = unsafeWindow.userSession;
    var userId = userSession.id;
    var firstName = userSession.firstName;
    var lastName = userSession.lastName;
    var fullName = firstName + ' ' + lastName;
    var accountId = userSession.accountId;

    // 先检查我们要加的菜单是否已经存在,存在就直接返回
    if ($('#userPersonalMenu').length > 0) return;

    $('.top-menu .nav').prepend(
        '<li class="dropdown dropdown-user dropdown-dark">' +
        '<a data-close-others="true" data-hover="dropdown" data-toggle="dropdown" class="dropdown-toggle username username-hide-mobile floatRight" href="#" style="padding:10px;border-right:1px solid #000;margin:5px;">' +
        fullName +
        '</a>' +
        '<ul id="userPersonalMenu" class="dropdown-menu dropdown-menu-default">' +
        '<li>' +
        '<a href="/user/editor?id=' + userId + '&amp;accountId=' + accountId + '" id="greetingNameLink">' +
        '<i class="icon-settings"></i> My Profile </a>' +
        '</li>' +
        '<li>' +
        '<a href="/logout">' +
        '<i class="icon-key"></i> Log Out </a>' +
        '</li>' +
        '</ul>' +
        '</li>');

    $('.dropdown-toggle').dropdownHover({});
    return null;
}

方案2:让waitForKeyElements执行一次就停止监听

根据waitForKeyElements的特性,回调函数返回false会移除当前选择器的监听,这样第一次处理完就不会再触发了:

function addUserDropdown(jNode) {
    // ... 这里保留你原有的所有逻辑 ...

    $('.dropdown-toggle').dropdownHover({});
    return false; // 返回false,通知waitForKeyElements停止监听".topMenu1"
}

补充说明

无限循环的核心原因是:你每次执行回调都会修改.top-menu .nav的DOM结构,而waitForKeyElements会监听DOM变化,一旦检测到新的.topMenu1元素(哪怕是原来的元素因为DOM变动被重新识别),就会再次触发回调,形成“修改DOM→触发回调→再修改DOM”的闭环。上面的方案要么从根源阻止重复执行,要么让监听在一次执行后终止,都能解决用户名重复显示的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:47:30