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

时间:2019-05-05 16:14:53

标签: jquery html css hover

我有一个带有子菜单的导航菜单系统,如下例所示。在子菜单上(通过将鼠标悬停在“二级”上可以显示)选项“仅执行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>

此处的Codepen:https://codepen.io/OsakaWebbie/pen/yWLXeV

2 个答案:

答案 0 :(得分:0)

希望以下答案对您有所帮助。我已经将ID设置为菜单链接,子菜单和Do 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>

答案 1 :(得分:0)

我不愿意将自己的答案归功于自己,但是在获得对我有用的东西之前,我必须在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选择器的可选第二个参数:context。 $("ul",this)表示ul的{​​{1}}个后代,对此非常有效。

因此,解决方案是上一级子菜单的$(this)父级,然后在其中捕获<li>mouseenter。最终,它的特殊标记要少得多,因此将来对菜单结构的修改不太可能出现一两个类放错位置的错误。我唯一需要的其他类是顶部mouseleave上的class="hassub"。实际上,我什至没有在jQuery中引用类“ nav-sub”-我只需要CSS。我最初以为我只会将jQuery应用于具有AJAX链接的子菜单(因为CSS <li>可以很好地工作),但是让jQuery在所有子菜单上操作都更简单,因此CSS hover不再需要。这是代码,将标记扩展为更加实际:

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;
}*/