【发布时间】:2012-12-06 04:35:26
【问题描述】:
我必须构建一个由点击触发的小下拉系统。我已经设法处理“点击退出 div”问题(感谢 this 之前发布的问题)。
我可以隐藏 current 下拉菜单,点击另一个下拉菜单的触发器或点击 dropdown 本身的外部。那么问题来了:
- 点击当前下拉菜单的触发器没用;当其他事情正常工作时,下拉菜单不会消失
- 点击内部当前下拉菜单(例如:.divider 项目),导致下拉菜单消失
所以,这里是 html 代码(假设我在标题中有多个下拉菜单)
...
<div id="header" class="navbar">
<div class="line">
<a href="#" class="logo">Site Name</a>
<ul class="nav right">
<li>
<a href="#" class="has-drop">Item 1</span>
<ul class="dropdown-menu">
<li><a href="#">Action A</a></li>
<li><a href="#">Action B</a></li>
<li><a href="#">Action C</a></li>
<li class="divider"></li>
<li><span>Inline note</span></li>
</ul>
</li>
<li>
<a class="has-drop" href="#">Item 2</a>
<ul class="dropdown-menu">
<li><a href="#">Action D</a></li>
<li><a href="#">Action E</a></li>
<li><a href="#">Action F</a></li>
<li class="divider"></li>
<li><a href="#">Action G</a></li>
</ul>
</li>
</ul>
</div>
</div> <!-- end #header -->
...
这实际上是我正在使用的 JS 代码,在一个专用文件中
$(document).ready(function(){
$("html").on({
click: function(e) {
$(".dropdown-menu.opened").toggleClass("opened");
}
});
$(".nav > li > a").on({
click: function(e){
e.stopPropagation();
$(".dropdown-menu.opened").toggleClass("opened"); // should close each .dropdowns before opening the current one
$(e.target).siblings(".dropdown-menu").toggleClass("opened");
}
});
});
为什么当我重新点击它的触发器时下拉菜单没有隐藏?因为在$(".nav > li > a").on() 内部实际上做同样的事情?
另外,有一种方法可以防止下拉菜单在单击其中的一些子项时隐藏自身?但也许这与另一个问题更相关,我不知道。
最后但并非最不重要的一点:您认为这是完成整个事情的正确方法吗?
提前谢谢大家
编辑:感谢@Beetroot-Beetroot 我设法解决了这个问题,所以这是当前的工作代码 $(document).ready(function(){
$("html").on("click", function(e) {
$(".dropdown-menu.opened").removeClass("opened");
});
$(".nav").find("li :first-child").on("click", function(e) {
e.preventDefault();
e.stopPropagation();
var $thisMenu = $(this).siblings(".dropdown-menu").toggleClass("opened");
$(".dropdown-menu").not($thisMenu).removeClass("opened");
});
});
“秘密”是 .not() 的巧妙使用,我现在对此更加了解。
我刚刚将目标(可以<a> 或<span>)更改为更通用的目标。不确定长期的表现,但肯定是一个很好的起点。
来自
$(".nav").find("a.has-drop").on(...
到
$(".nav").find("li :first-child").on(...
还有,这里
$(this).closest(".nav").find(".dropdown-menu").not(... 我让它像这样更通用 $(".dropdown-menu").not(... 那是因为我想隐藏 所有 打开的下拉菜单。以前的行为是只考虑一种目标和一个原点区域(例如:也许我需要这些下拉菜单以及标题和某种工具栏内的内容)。
编辑 2:@Beetroot-Beetroot 再次帮助了我。正如他所建议的那样,当我在 jsFiddle 中移植当前代码时,突然解决方案本身就出现了。所以现在$("html").on("click", ... 部分看起来像这样
$("html").on("click", function(e) {
if ( $(e.target).hasClass("dropdown-menu") || $(e.target).parents(".dropdown-menu").length ) {
// do nothing, basically
} else {
$(".dropdown-menu.opened").removeClass("opened");
}
});
基本上,我只是观察来自$("html") 的点击是否与下拉菜单的宽度有关。如果是,什么也不做。如果不是,那么这确实意味着我点击了任何但而不是下拉菜单所在的位置。
【问题讨论】:
标签: jquery css user-interface drop-down-menu frameworks