$(文档).on("点击" ...如何在单击文档上的任何其他位置时折叠列表

时间:2014-08-21 14:09:43

标签: javascript html css

我正在尝试为我的网站构建可折叠/可扩展的菜单。我有一个版本,将鼠标悬停在一个类别上会导致子类别扩展,但我真正想要的是点击一个类别并让子类别展开并保持扩展,直到我点击页面上的任何其他位置。我想我已经接近了 - 我已经看了很多例子,我只是在努力将它们拼凑起来。

目前的情况是,当点击列表本身时,我可以让列表展开和折叠,但是当点击文档的其他地方时,我无法做任何事情。我意识到我还必须使用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>

link to jfiddle

提前感谢您的耐心等待。我没有多少Javascript经验,而且我发现Stack Overflow非常有用,因为我知道如何对现有网站进行更改。但是,在从头开始创建任何东西时,我仍然在挣扎。

编辑:使用来自@JustinMorgan的解决方案,并添加了一行,以便一次只能看到一个子菜单:http://jsfiddle.net/nbavc5g7/2/

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();
});

演示:http://jsfiddle.net/Luk35kb6/

答案 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脚本中不加干扰地附加事件处理程序。