我正在尝试为我的网站构建可折叠/可扩展的菜单。我有一个版本,将鼠标悬停在一个类别上会导致子类别扩展,但我真正想要的是点击一个类别并让子类别展开并保持扩展,直到我点击页面上的任何其他位置。我想我已经接近了 - 我已经看了很多例子,我只是在努力将它们拼凑起来。
目前的情况是,当点击列表本身时,我可以让列表展开和折叠,但是当点击文档的其他地方时,我无法做任何事情。我意识到我还必须使用stopPropagation()做一些事情,但首先要做的事情......
使用Javascript:
function show_sub(cat){
cat.querySelector("ul").style.display = (cat.querySelector("ul").style.display == "block") ? "none" : "block";
};
$('body').on("click", function () {
$("#nav ul").style.display="none";
});
CSS:
#nav {
width: 120px;
border: black 1px solid;
}
#nav li > ul {
display:none;
}
HTML:
<ul id="nav">
<li id="cat1" onclick="show_sub(this)">Vegetables
<ul>
<li>Beans</li>
<li>Carrots</li>
<li>Greens</li>
<li>Onions</li>
</ul>
</li>
<li id="cat2" onclick="show_sub(this)">Fruit
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cantaloupe</li>
</ul>
</li>
</ul>
提前感谢您的耐心等待。我没有多少Javascript经验,而且我发现Stack Overflow非常有用,因为我知道如何对现有网站进行更改。但是,在从头开始创建任何东西时,我仍然在挣扎。
编辑:使用来自@JustinMorgan的解决方案,并添加了一行,以便一次只能看到一个子菜单:http://jsfiddle.net/nbavc5g7/2/
答案 0 :(得分:1)
你是对的,你需要stopPropagation
。扩展子列表的相同点击事件正在向上传播,body
上的点击处理程序立即再次隐藏它。
您还可以在几个地方简化代码。试试这个:
$('#nav > li').on('click', function(e) {
e.stopPropagation();
$('ul', this).show();
});
$('body').on("click", function () {
$("#nav ul").hide();
});
演示:http://jsfiddle.net/d60Lcq9j/1/
编辑:这是一个稍微复杂的版本,可让您通过第二次点击其标题关闭子菜单。此版本不会停止事件传播:
$('#nav li').on('click', function(e) {
if (e.target === this) {
$(this).children('ul').toggle();
}
});
$('body').on("click", function (e) {
var item = $(e.target).closest('#nav > li');
$('#nav > li')
.not(item)
.find('ul')
.hide();
});
答案 1 :(得分:0)
在body
元素的点击事件处理程序中,检查点击是来自导航li
还是来自页面上的任何其他位置,并相应地切换列表。
所以你的代码现在看起来像:
<强> HTML 强>
<body>
<ul id="nav">
<li id="cat1">Vegetables
<ul>
<li>Beans</li>
<li>Carrots</li>
<li>Greens</li>
<li>Onions</li>
</ul>
</li>
<li id="cat2">Fruit
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cantaloupe</li>
</ul>
</li>
</ul>
</body>
<强>的Javascript 强>
$('#nav li').on('click', function(e) {
$(this).find('ul').toggle();
});
$('body').on("click", function (e) {
if ($(e.target).closest('#nav li').length) {
$(e.target).closest('#nav li ul').toggle();
} else {
$('#nav li ul').hide();
}
});
CSS (正如@wonderwhy在评论中指出的那样)
#nav > li {
cursor: pointer;
}
#nav li > ul {
display: none;
cursor: default;
}
查看这个小提琴演示:http://jsfiddle.net/arnellebalane/x6ozq1La/9/
请注意:请不要在HTML文档中使用onclick
和类似属性。由于您使用的是jQuery,因此可以使用on()
方法在您的javascript脚本中不加干扰地附加事件处理程序。