如何修复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 + '&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
相关产品推荐
相关产品推荐

