单击后关闭悬停子菜单而不刷新页面
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 ▼</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 ▼</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 的代码。
我学到的东西:
mouseenter
和 mouseleave
是比 mouseover
和 mouseout
更好的事件,因为当鼠标在子菜单上的项目之间移动时,mouseover
和 mouseout
会在混乱中继续触发(甚至有时不触发)如果我动作太快!)。 [Golda 的答案确实适用于mouseover/mouseout
,只要它们在每个子菜单中被两个元素捕获并且 ID 被分配给所有东西。我花了几个小时寻找合适的 jQuery 选择器来对 DOM 层次结构和类做同样的事情,但无济于事。]
mouseover/mouseout
和 mouseenter/mouseleave
之间区别的一个很好的解释是:https://javascript.info/mousemove-mouseover-mouseout-mouseenter-mouseleave
我了解了 jQuery 选择器的可选第二个参数:上下文。 $("ul",this)
表示 $(this)
的 ul
后代,非常适合此操作。
所以解决方案是升级到子菜单的<li>
父级,并在那里捕获mouseenter
和mouseleave
。这最终得到的特殊标记要少得多,因此将来对菜单结构的修改不太可能因一两个放错的类而出现错误。我唯一需要的额外课程是顶部的class="hassub"
<li>
。事实上,我什至没有在 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) ▼</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) ▼</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) ▼</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>
【讨论】:
以上是关于单击后关闭悬停子菜单而不刷新页面的主要内容,如果未能解决你的问题,请参考以下文章