单击后关闭悬停子菜单而不刷新页面

Posted

技术标签:

【中文标题】单击后关闭悬停子菜单而不刷新页面【英文标题】:Close hover submenu after click without page refresh 【发布时间】:2019-09-23 10:13:54 【问题描述】:

我有一个带有子菜单的导航菜单系统,如下例所示。在子菜单上(通过将鼠标悬停在“两级”上显示)是“仅执行 AJAX”选项。如果选择了该选项,将运行 ajax 例程,我希望下拉菜单立即再次隐藏(即,一旦单击该选项,子菜单就会消失)。

我尝试了 jQuery hide(),但这会永久禁用子菜单(即,将鼠标滑回菜单栏不会再次显示它)

我也尝试了hide(),然后是show(),但这使得即使将鼠标移开后子菜单仍然可见。

mouseleave()mouseout() 听起来很有希望,但无论我将它们应用于什么相关元素,它们似乎都没有做任何事情。

这是简化的代码:

$(function() 
  $('.ajax').click(function(event) 
    event.preventDefault(); //to keep from jumping to top of page
    //$(this).closest('ul').hide(); /* this breaks the menu */
    /* none of these do anything I can see */
    $(this).mouseleave();
    $(this).parent().mouseleave();
    $(this).parent().parent().mouseleave();
    $(this).trigger("mouseout");
    $(this).parent().trigger("mouseout");
    $(this).parent().parent().trigger("mouseout");
    $(this).trigger("mouseleave");
    $(this).parent().trigger("mouseleave");
    $(this).parent().parent().trigger("mouseleave");

    /* do stuff with AJAX */
  );
);
ul.nav 
  background-color:rgb(88,57,7);
  list-style-type: none;
  text-align: center;
  vertical-align: middle;
  min-height: 30px;
  position:sticky;
  top:0;

ul.nav li 
  display: inline-block;
  position: relative;

ul.nav-sub  /* second level menus */
  display: none;
  position: absolute;
  background-color:rgb(88,57,7);
  margin: -4px 0 0 15px;
  border: 1px solid LightSteelBlue;
  padding: 0;
  border-radius: 0;
  text-align: left;
  min-height: 0;

ul.nav li:hover ul 
  display: block;
  z-index:100;

ul.nav-sub li 
  display: block;

ul.nav a 
  display: block;
  color: LightSteelBlue;
  padding: 10px 15px;
  margin: 0;
  font-family: arial, helvetica, sans-serif;
  font-weight: bold;
  text-decoration: none;
  white-space:nowrap;

ul.nav a:hover 
  background-color: rgb(132,78,12);
  color: White;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<ul class="nav">
  <li><a href="file1.php" target="_top">Simple</a></li>
  <li>
    <a href="#">Two-level &#x25BC;</a>
    <ul class="nav-sub">
      <li><a href="file2.php" target="_top">Go to a page</a></li>
      <li><a class="ajax" href="#">Do AJAX only</a></li>
      <li><a href="file3.php">Go to another page</a></li>
    </ul>
  </li>
</ul>

在此处编写代码:https://codepen.io/OsakaWebbie/pen/yWLXeV

【问题讨论】:

【参考方案1】:

希望下面的回答对你有所帮助。我已将 ID 设置为菜单链接、子菜单和执行 AJAX 链接。我使用 moveover 事件显示菜单并使用 mouseout 事件将其隐藏

$(function() 
$("#twoLink, #subMenu").mouseover(function()
 $("#subMenu").show();
);

$("#twoLink, #subMenu").mouseout(function()
 $("#subMenu").hide();
);

 $("#doAjaxLink").click(function()
    $("#subMenu").hide();
  );
);
ul.nav 
  background-color:rgb(88,57,7);
  list-style-type: none;
  text-align: center;
  vertical-align: middle;
  min-height: 30px;
  position:sticky;
  top:0;

ul.nav li 
  display: inline-block;
  position: relative;

ul.nav-sub  /* second level menus */
  display: none;
  position: absolute;
  background-color:rgb(88,57,7);
  margin: -4px 0 0 15px;
  border: 1px solid LightSteelBlue;
  padding: 0;
  border-radius: 0;
  text-align: left;
  min-height: 0;

ul.nav li:hover ul 
  display: block;
  z-index:100;

ul.nav-sub li 
  display: block;

ul.nav a 
  display: block;
  color: LightSteelBlue;
  padding: 10px 15px;
  margin: 0;
  font-family: arial, helvetica, sans-serif;
  font-weight: bold;
  text-decoration: none;
  white-space:nowrap;

ul.nav a:hover 
  background-color: rgb(132,78,12);
  color: White;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<ul class="nav">
  <li><a href="file1.php" target="_top">Simple</a></li>
  <li>
    <a id="twoLink" href="#">Two-level &#x25BC;</a>
    <ul id="subMenu" class="nav-sub">
      <li><a href="file2.php" target="_top">Go to a page</a></li>
      <li><a id="doAjaxLink" class="ajax" href="#">Do AJAX only</a></li>
      <li><a href="file3.php">Go to another page</a></li>
    </ul>
  </li>
</ul>

【讨论】:

我不能使用 ID - 我不仅拥有多种类型的东西,而且我将整个菜单标记复制到第二个移动容器中(我知道我应该想出一个更好的方法,但这是以后的战斗)。但我明白你的意思:你看不到任何使用实际 CSS 悬停动作的方法,所以你手动显示和隐藏。如果我让你的想法在我的真实代码中工作,悬停 CSS 是否必要?我目前正在尝试使用 DOM 层次结构和类来实现它,但我无法正确选择选择器 - 我会继续尝试。【参考方案2】:

我不想把答案归功于自己,但在得到对我有用的东西之前,我必须在 Golda 的回答之后做更多的研究,而且我的解决方案可能对以后阅读本文的其他人有用。我的真实菜单具有所有类型元素的倍数,甚至整个导航菜单标记都是重复的,所以我不能使用 ID。除了需要用 JS 替换 CSS 的 hover 伪元素功能的一般推断之外,我最终没有使用 Golda 的代码。

我学到的东西:

mouseentermouseleave 是比 mouseovermouseout 更好的事件,因为当鼠标在子菜单上的项目之间移动时,mouseovermouseout 会在混乱中继续触发(甚至有时不触发)如果我动作太快!)。 [Golda 的答案确实适用于mouseover/mouseout,只要它们在每个子菜单中被两个元素捕获并且 ID 被分配给所有东西。我花了几个小时寻找合适的 jQuery 选择器来对 DOM 层次结构和类做同样的事情,但无济于事。] mouseover/mouseoutmouseenter/mouseleave 之间区别的一个很好的解释是:https://javascript.info/mousemove-mouseover-mouseout-mouseenter-mouseleave 我了解了 jQuery 选择器的可选第二个参数:上下文。 $("ul",this) 表示 $(this)ul 后代,非常适合此操作。

所以解决方案是升级到子菜单的&lt;li&gt; 父级,并在那里捕获mouseentermouseleave。这最终得到的特殊标记要少得多,因此将来对菜单结构的修改不太可能因一两个放错的类而出现错误。我唯一需要的额外课程是顶部的class="hassub" &lt;li&gt;。事实上,我什至没有在 jQuery 中引用类“nav-sub”——我仍然只需要它用于 CSS。我最初以为我只会将 jQuery 应用于具有 AJAX 链接的子菜单(因为 CSS hover 没有它也可以正常工作),但是让 jQuery 对所有子菜单进行操作更简单,因此不再需要 CSS ul.nav li:hover ul display: block; .这是代码,标记扩展得更真实一点:

$(function() 
  $(".hassub").mouseenter(function()  $("ul",this).show(); );
  $(".hassub").mouseleave(function()  $("ul",this).hide(); );
  
  $('.ajaxlink').click(function()  $(this).closest('ul').hide(); );
);
ul.nav 
  background-color:rgb(88,57,7);
  list-style-type: none;
  text-align: center;
  vertical-align: middle;
  min-height: 30px;
  position:sticky;
  top:0;

ul.nav li 
  display: inline-block;
  position: relative;

ul.nav-sub 
  display: none;
  position: absolute;
  background-color:rgb(88,57,7);
  margin: -4px 0 0 15px;
  border: 1px solid LightSteelBlue;
  padding: 0;
  border-radius: 0;
  text-align: left;
  min-height: 0;
  z-index:100;

ul.nav-sub li 
  display: block;

ul.nav a 
  display: block;
  color: LightSteelBlue;
  padding: 10px 15px;
  margin: 0;
  font-family: arial, helvetica, sans-serif;
  font-weight: bold;
  text-decoration: none;
  white-space:nowrap;

ul.nav a:hover 
  background-color: rgb(132,78,12);
  color: White;

/*ul.nav li:hover ul 
display: block;
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<ul class="nav">
  <li><a href="file1.php">solo page</a></li>
  <li class="hassub">
    <a href="#">submenu1 (mixed) &#x25BC;</a>
    <ul class="nav-sub">
      <li><a href="file2.php">page 1a</a></li>
      <li><a href="file3.php">page 1b</a></li>
      <li><a class="ajaxlink" href="#">ajax 1-1</a></li>
      <li><a href="file2.php">page 1c</a></li>
      <li><a href="file3.php">page 1d</a></li>
    </ul>
  </li>
  <li class="hassub">
    <a href="#">submenu2 (only pages) &#x25BC;</a>
    <ul class="nav-sub">
      <li><a href="file2.php">page 2a</a></li>
      <li><a href="file3.php">page 2b</a></li>
    </ul>
  </li>
  <li id="hassub3" class="hassub">
    <a href="#">submenu3 (only ajax) &#x25BC;</a>
    <ul id="sub3" class="nav-sub">
      <li><a class="ajaxlink" href="#">ajax 3-1</a></li>
      <li><a class="ajaxlink" href="#">ajax 3-2</a></li>
    </ul>
  </li>
</ul>

【讨论】:

以上是关于单击后关闭悬停子菜单而不刷新页面的主要内容,如果未能解决你的问题,请参考以下文章

关闭子页面后父页面中的Gridview不刷新 - ASP.NET WEB APP

JS子页面自动关闭后刷新父页面

怎么实现父窗口打开子窗口,子窗口关闭后自动刷新父窗口?

子页面提交后刷新父页面问题

JS弹窗提交关闭后,刷新父页面 在线等 急!!!

子窗口关闭,父窗口如何刷新