【问题标题】: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

【问题讨论】:

    标签: jquery html css hover


    【解决方案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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 2017-07-20
      • 2019-02-25
      • 2013-05-01
      • 2021-03-27
      相关资源
      最近更新 更多