jQuery子菜单:li项目仍在切换

4

我已经尝试了几个小时,因为我对jQuery本身还很陌生,而且我绝对还是一个初学者,所以我真的需要一些帮助。我试图创建一个带有子菜单的导航。一切都按预期工作,但我错过了停止子菜单列表项切换的方法。

HTML:

<nav>
      <ul id="site-nav">
        <li><a href="#">Main Nav Item 1</a></li>
        <li><a href="#">Main Nav Item 2 (with submenu)</a>
          <ul>
            <li><a href="#">Submenu Item 1</a></li>
            <li><a href="#">Submenu Item 2</a></li>
            <li><a href="#">Submenu Item 3</a></li>
          </ul>
        </li>
        <li><a href="#">Main Nav Item 3 (with submenu)</a>
          <ul>
            <li><a href="#">Submenu Item 1</a></li>
            <li><a href="#">Submenu Item 2</a></li>
          </ul>
        </li>
        <li><a href="#">Main Nav Item 4</a></li>
        <li><a href="#">Main Nav Item 5</a></li>
      </ul>
    </nav>

JQuery(子菜单部分):

$(document).ready(function() {

  var subnavArrow = ['<div id="subnavArrow"></div>'];
      subpull     = $('header nav ul li');
      submenu     = $('header nav ul li ul');
      submenuitems = $('header nav ul li ul li');

  subpull.has('ul').prepend(subnavArrow);

  $('header nav ul li').has('ul').click(function() {
    $(this).children('ul').toggle('slow');
  });

});

如果您不明白我的意思,我会尽可能详细地解释一下:
我想每次单击“主导航项2”时打开其子项。这个功能正常工作,我也可以将其关闭,但是如果我单击“主导航项2”的某个子菜单项,它将关闭“主导航项2”的子菜单。

在jsfiddle中添加你的代码 - Lalji Tadhani
@LaljiTadhani 为什么他要这样做呢?所有需要的代码都在问题中了。 - Roko C. Buljan
4个回答

3

您可以检查您是否点击了锚点div元素,如下:

$(document).ready(function() {

  var subnavArrow = ['<div id="subnavArrow"></div>'];
  subpull = $('header nav ul li');
  submenu = $('header nav ul li ul');
  submenuitems = $('header nav ul li ul li');

  subpull.has('ul').prepend(subnavArrow);

  $('header nav ul li').has('ul').click(function(e) {
    if ($(e.target).closest('li').is(this)) {
      $(this).children('ul').toggle('slow');
    }
  });

});
#subnavArrow:after {
  content: '<<'
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
  <nav>
    <ul id="site-nav">
      <li><a href="#">Main Nav Item 1</a>
      </li>
      <li><a href="#">Main Nav Item 2 (with submenu)</a>
        <ul>
          <li><a href="#">Submenu Item 1</a>
          </li>
          <li><a href="#">Submenu Item 2</a>
          </li>
          <li><a href="#">Submenu Item 3</a>
          </li>
        </ul>
      </li>
      <li><a href="#">Main Nav Item 3 (with submenu)</a>
        <ul>
          <li><a href="#">Submenu Item 1</a>
          </li>
          <li><a href="#">Submenu Item 2</a>
          </li>
        </ul>
      </li>
      <li><a href="#">Main Nav Item 4</a>
      </li>
      <li><a href="#">Main Nav Item 5</a>
      </li>
    </ul>
  </nav>
</header>


它按预期工作,谢谢你,但是你能解释一下你添加的带有e.target的那行代码吗?有没有地方可以查找更详细的信息或者在哪些情况下我应该/需要使用它(除了在这个特定菜单上)? - ricosauney
1
@ricosauney e.target 指触发点击事件的元素 - 您可以在 https://developer.mozilla.org/en-US/docs/Web/API/Event/target 和 https://api.jquery.com/event.target/ 上阅读更多信息。 - Arun P Johny

2
  • 不要追加 #ID 元素,ID 应该是唯一的。使用类 .subnavArrow 代替。
  • 在 jQuery 中,将 #site-nav 称为父元素。
  • 如果您将使用更多嵌套的 li>ul,请使用 Event.stopPropagation()
  • 始终将您的 var 赋值给变量,或者使用逗号进行连接。

$(function() { // DOM ready

  var $LIsub = $("#site-nav li:has(ul)");

  $LIsub.children("a").append('<span class="subnavArrow"/>');
  
  $LIsub.click(function(e) {
    e.stopPropagation();
    $(this).find('> ul').slideToggle('slow');
  });

});
#site-nav li ul{
  display:none;
}
.subnavArrow:after{
  content:"\25BC"
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
  <nav>
    <ul id="site-nav">
      <li><a href="#">Main Nav Item 1</a></li>
      <li><a href="#">Main Nav Item 2</a>
        <ul>
          <li><a href="#">Submenu Item 1</a></li>
          <li><a href="#">Submenu Item 2</a></li>
          <li><a href="#">Submenu Item 3</a></li>
        </ul>
      </li>
      <li><a href="#">Main Nav Item 3</a>
        <ul>
          <li><a href="#">Submenu Item 1</a></li>
          <li><a href="#">Submenu Item 2</a></li>
        </ul>
      </li>
      <li><a href="#">Main Nav Item 4</a></li>
      <li><a href="#">Main Nav Item 5</a></li>
    </ul>
  </nav>
</header>


1
您的代码问题在于,当您单击子菜单<li>时,单击事件会向父级<li>传播,并触发隐藏<ul>的函数。
解决方案是将您的点击监听器中的.has('ul')部分移动到回调函数内部:
$(document).ready(function() {

    var subnavArrow = ['<div id="subnavArrow"></div>'];
    subpull = $('header nav ul li');
    submenu = $('header nav ul li ul');
    submenuitems = $('header nav ul li ul li');

    subpull.has('ul').prepend(subnavArrow);

    $('header nav ul li').click(function(e) {
        e.stopPropagation();
        if ($(this).has('ul')) {
            $(this).children('ul').toggle('slow');
        }
    });

});

这样,监听器也会监听子菜单上的点击事件,并且你可以使用 e.stopPropagation(); 来防止事件冒泡到父级元素。
你可以在这个 JSFiddle 上看到这个解决方案:https://jsfiddle.net/9ejpLmLf/

0
Very simple code
=============================
<pre>
$(document).ready(function() {

  var subnavArrow = ['<div id="subnavArrow"></div>'];
      subpull     = $('header nav ul li');
      submenu     = $('header nav ul li ul');
      submenuitems = $('header nav ul li ul li');

  subpull.has('ul').prepend(subnavArrow);

  $('header nav ul li a').click(function() {
    $(this).siblings('ul').toggle('slow');
  });

});
</pre>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接