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

jQuery下拉菜单遇表单自动填充提示时消失的问题求助

解决jQuery巨型菜单中表单自动填充提示导致菜单消失的问题

我完全懂你遇到的这个糟心问题——当用户在菜单内嵌的表单输入框选择浏览器自动填充的用户名时,整个下拉菜单直接消失了。这确实是因为浏览器的自动填充提示不属于菜单DOM结构的一部分,当你点击/悬停选择提示时,会触发document上的点击事件,而原代码里这个事件会直接隐藏所有菜单。

先拆解原代码里的几个关键问题:

  1. 选择器语法错误:所有$("mega-menu")都应该是$(".mega-menu")(类选择器必须加.),否则事件绑定根本不会生效。
  2. document点击事件逻辑太粗暴:只要点击菜单外的任何元素就隐藏菜单,但自动填充提示虽然在菜单外,却和菜单内的表单交互直接相关。
  3. 菜单显示/隐藏逻辑不完善:依赖原生hover事件,没有处理鼠标离开菜单但进入自动填充提示的过渡场景。

具体解决方案

我们需要调整菜单的显示/隐藏逻辑,增加延迟缓冲机制,同时优化document点击事件的判断条件,确保用户和自动填充提示交互时菜单不会消失。

步骤1:修正选择器错误

把所有缺少.的mega-menu选择器补上,比如:

// 原错误代码
$("mega-menu > ul").before(...)
// 修正后
$(".mega-menu > ul").before(...)

步骤2:替换hover事件为mouseenter/mouseleave+延迟定时器

给菜单增加一个“缓冲期”,当鼠标离开菜单时不立即隐藏,给用户足够时间移动到自动填充提示上:

// 全局变量存储隐藏定时器
let menuHideTimer;

// 鼠标进入菜单时显示下拉并清除定时器
$(".mega-menu > ul > li").on('mouseenter', function(e) {
  if ($(window).width() > 943) {
    clearTimeout(menuHideTimer);
    $(this).children("ul").stop(true, false).fadeIn(150);
  }
});

// 鼠标离开菜单时延迟隐藏
$(".mega-menu > ul > li").on('mouseleave', function(e) {
  if ($(window).width() > 943) {
    menuHideTimer = setTimeout(() => {
      $(this).children("ul").stop(true, false).fadeOut(150);
    }, 300); // 300毫秒的缓冲时间足够用户操作自动填充提示
  }
});

步骤3:优化document点击事件的判断逻辑

修改document点击事件,只有当点击的元素既不在菜单内,也不是浏览器自动填充元素,且菜单内没有聚焦的输入框时,才隐藏菜单:

$(document).click(function(event) {
  if ($(window).width() > 943) {
    // 检查点击目标是否在菜单内
    const isInsideMenu = $(event.target).closest('.mega-menu').length > 0;
    // 检查是否是浏览器自动填充元素(兼容主流浏览器的选择器)
    const isAutocompleteElement = $(event.target).closest('div.private-autocomplete, #password-prompt, .autocomplete-suggestions').length > 0;
    // 检查菜单内是否有聚焦的输入框
    const hasFocusedInput = $('.mega-menu input:focus').length > 0;

    // 只有三个条件都不满足时才隐藏菜单
    if (!isInsideMenu && !isAutocompleteElement && !hasFocusedInput) {
      $('.mega-menu > ul > li').children("ul").fadeOut(150);
    }
  }
});

步骤4:给表单输入框绑定focus/blur事件

当输入框聚焦时保持菜单显示,失去焦点时再延迟隐藏:

$('.mega-menu input').on('focus', function() {
  clearTimeout(menuHideTimer);
});

$('.mega-menu input').on('blur', function() {
  if ($(window).width() > 943) {
    menuHideTimer = setTimeout(() => {
      $('.mega-menu > ul > li').children("ul").fadeOut(150);
    }, 300);
  }
});

完整修正后的代码

"use strict";

// 修正选择器,添加.
$('.mega-menu > ul > li:has( > ul)').addClass('menu-dropdown-icon');
$('.mega-menu > ul > li > ul:not(:has(ul))').addClass('normal-sub');
$(".mega-menu > ul").before("<a href=\"#\" class=\"mega-menu-mobile\">Navigation</a>");

// 允许菜单内的点击事件冒泡被阻止
$(".mega-menu").click(function(event) {
  console.log('clicked inside menu');
  event.stopPropagation();
});

// 全局定时器变量
let menuHideTimer;

// 鼠标进入显示菜单
$(".mega-menu > ul > li").on('mouseenter', function(e) {
  if ($(window).width() > 943) {
    clearTimeout(menuHideTimer);
    $(this).children("ul").stop(true, false).fadeIn(150);
  }
});

// 鼠标离开延迟隐藏菜单
$(".mega-menu > ul > li").on('mouseleave', function(e) {
  if ($(window).width() > 943) {
    menuHideTimer = setTimeout(() => {
      $(this).children("ul").stop(true, false).fadeOut(150);
    }, 300);
  }
});

// 移动端点击切换菜单
$(".mega-menu > ul > li").click(function() {
  console.log('clicking')
  if ($(window).width() <= 943) {
    $(this).children("ul").fadeToggle(150);
  }
});

// 优化后的document点击事件
$(document).click(function(event) {
  console.log('clicked outside');
  if ($(window).width() > 943) {
    const isInsideMenu = $(event.target).closest('.mega-menu').length > 0;
    const isAutocompleteElement = $(event.target).closest('div.private-autocomplete, #password-prompt, .autocomplete-suggestions').length > 0;
    const hasFocusedInput = $('.mega-menu input:focus').length > 0;

    if (!isInsideMenu && !isAutocompleteElement && !hasFocusedInput) {
      $('.mega-menu > ul > li').children("ul").fadeOut(150);
    }
  }
});

// 表单输入框的focus/blur处理
$('.mega-menu input').on('focus', function() {
  clearTimeout(menuHideTimer);
});

$('.mega-menu input').on('blur', function() {
  if ($(window).width() > 943) {
    menuHideTimer = setTimeout(() => {
      $('.mega-menu > ul > li').children("ul").fadeOut(150);
    }, 300);
  }
});

这个方案的核心是通过延迟隐藏和更精准的事件判断,给用户和自动填充提示交互的空间,同时修正了原代码的选择器错误,确保所有事件都能正确触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:58