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

如何修改菜单交互:桌面hover触发下拉,移动端click+外部点击关闭

响应式溢出菜单交互优化方案

需求说明

开发一款响应式菜单,可将溢出的菜单项包裹至下拉列表中,需调整交互逻辑:

  • 桌面端:将原点击触发下拉改为**鼠标悬停(mouseover)**触发
  • 移动端:保留点击触发逻辑,同时实现点击下拉按钮以外区域时自动关闭下拉菜单

修改后完整代码

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="menu-item">menu1</li>
  <li class="menu-item">menu2</li>
  <li class="menu-item">menu3</li>
  <li class="menu-item">menu4</li>
  <li class="menu-item">menu5</li>
  <li class="menu-item">menu6</li>
  <li class="menu-item">menu7</li>
  <li class="menu-item">menu8</li>
  <li class="menu-item">menu9</li>
  <li class="menu-item">menu10</li>
  <li class="menu-item">menu11</li>
  <li class="menu-item">menu12</li>
  <li class="menu-item">menu13</li>
  <li class="menu-item">menu14</li>
</ul>
<div class="click"></div>

CSS

ul {
  padding: 5px 40px 5px 5px;
  box-sizing: border-box;
  overflow: hidden;
  max-height: 55px;
  position: relative;
}

ul.show {
  overflow: visible;
}

li {
  display: inline-block;
  text-decoration: none;
  color: #000000;
  font-size: 20px;
  text-transform: capitalize;
  border: 1px solid black;
  margin: 10px 8px;
  list-style: none;
  position: relative;
}

li.drop {
  display: block;
  position: absolute;
  right: 0;
}

li:last-child::after {
  content: "";
  position: absolute;
  left: 102%;
  width: 100vw;
  top: -10px;
  bottom: -10px;
  background: #fff;
  z-index: 2;
}

li.drop::after {
  content: none;
}

.click {
  background: red;
  position: relative;
  width: 40px;
  height: 40px;
  margin-left: auto;
  margin-top: -65px;
  margin-right: 5px;
  cursor: pointer;
}

/* 设备分界媒体查询,可按需调整断点 */
@media (max-width: 768px) {
  .click {
    /* 可添加移动端专属样式增强识别性 */
  }
}

JavaScript

var h = 30;
var val = 0;
// 自定义移动端宽度断点
const MOBILE_BREAKPOINT = 768;

// 判断当前是否为移动端
function isMobile() {
  return window.innerWidth <= MOBILE_BREAKPOINT;
}

// 统一重置菜单状态
function resetMenu() {
  $('ul').removeClass('show');
  $('ul li.menu-item').removeClass('drop').css('top', '');
}

// 计算并渲染溢出菜单项
function showOverflowMenu() {
  val = 0;
  $('ul li.menu-item').each(function() {
    var of = $(this).offset().top - $('ul').offset().top;
    if (of > 20) {
      $(this).addClass('drop');
      $(this).css('top', `calc(100% + ${val}px)`);
      val += h;
    }
  });
  $('ul').addClass('show');
}

// 根据设备绑定对应交互事件
function bindEvents() {
  const $clickBtn = $('.click');
  const $menu = $('ul');

  // 先移除旧事件,避免重复绑定
  $clickBtn.off();
  $(document).off('click.menuClose');

  if (isMobile()) {
    // 移动端:点击触发切换
    $clickBtn.on('click', function(e) {
      e.stopPropagation();
      $menu.hasClass('show') ? resetMenu() : showOverflowMenu();
    });

    // 点击外部区域关闭菜单
    $(document).on('click.menuClose', function(e) {
      const isClickInsideMenu = $menu.is(e.target) || $menu.has(e.target).length > 0;
      const isClickOnBtn = $clickBtn.is(e.target);
      if (!isClickInsideMenu && !isClickOnBtn && $menu.hasClass('show')) {
        resetMenu();
      }
    });
  } else {
    // 桌面端:鼠标悬停触发显示,离开隐藏
    $clickBtn.on('mouseover', showOverflowMenu)
             .on('mouseout', resetMenu);
  }
}

// 页面初始化及窗口缩放适配
$(document).ready(function() {
  bindEvents();
  $(window).on('resize', function() {
    resetMenu();
    bindEvents();
  });
});

核心修改点说明

  • 设备区分:通过窗口宽度判断设备类型,可自定义断点适配不同需求
  • 桌面端交互:为下拉按钮绑定mouseover/mouseout事件,实现悬停显示、离开隐藏的逻辑
  • 移动端交互:保留点击触发,同时给全局绑定点击事件,判断点击区域不在菜单和按钮内时自动关闭下拉
  • 状态统一管理:封装resetMenu函数处理菜单重置逻辑,避免代码冗余
  • 窗口缩放适配:监听窗口大小变化,重新绑定事件并重置菜单,确保响应式切换正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 14:19:58