Javascript 仅在某些级别上防止默认设置

Javascript 仅在某些级别上防止默认设置,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我正在制作一个有子菜单的菜单。当我点击一个菜单项时,我使用的是阻止默认值,因为它是一个标签,但在子菜单级别,我不想阻止默认值。我还没有弄清楚如何使它工作,这样它就不会影响顶层 <div id="block-menu-block-2"> <ul class="menu"> <li> <a href="#">1</a> </li> <li> <a href="

我正在制作一个有子菜单的菜单。当我点击一个菜单项时,我使用的是阻止默认值,因为它是一个标签,但在子菜单级别,我不想阻止默认值。我还没有弄清楚如何使它工作,这样它就不会影响顶层

<div id="block-menu-block-2">
  <ul class="menu">
    <li>
      <a href="#">1</a>
    </li>
    <li>
      <a href="#">2</a>
      <ul class="menu">
        <li><a href="#">2.1</a></li>
        <li><a href="#">2.2</a></li>
        <li><a href="#">2.3</a></li>
        <li><a href="#">2.4</a></li>
      </ul>
    </li>
    <li>
      <a href="#">3</a>
      <ul class="menu">
        <li><a href="#">3.1</a></li>
        <li><a href="#">3.2</a></li>
        <li><a href="#">3.3</a></li>
        <li><a href="#">3.4</a></li>
      </ul>
    </li>
    <li>
      <a href="#">4</a>
    </li>
    <li>
      <a href="#">5</a>
    </li>
    <li>
      <a href="#">6</a>
      <ul class="menu">
        <li><a href="#">6.1</a></li>
      </ul>
    </li>
  </ul>  
</div>

这里有一个代码笔供参考:

您不能将类添加到子菜单触发器,例如
。子菜单触发器
,然后使用以下jQuery:

$(document).on('click', function(e) {
  if ($(e.target).hasClass('submenu-trigger')) e.preventDefault();
});

忽略所有其他菜单操作并将事件置于
标记上,您只需检查
是否有同级
,以及它是否阻止默认设置

$('#block-menu-block-2 a').click(function(e){
    if( $(this).siblings('ul').length ){
         e.preventDefault();
    }
    // menu manipulation code

});

添加了一些东西。换了些东西。无法从我的手机粘贴到codepen中,因此这可能不起作用。先编码,然后是单词墙

$('#block-menu-block-2 ul li').each (function () { 
    var $this = $(this);
    if ($this.find ('ul:first').length > 0) {
        $this.click (function () {
            if ($this.find ('ul:visible').length > 0) {
                $this.removeClass ('menuItemSelected').find ('ul').removeClass('menuItemSelected').hide ('blind');
            } else {
                $this.parent ().find ('ul li').hide ('blind');
                $this.parent ().find('.menuItemSelected').removeClass  ('menuItemSelected');
                $this.addClass ('menuItemSelected').find ('ul').show ('blind').addClass ('menuItemSelected');
            }
        }); 
    }
});
 $('#block-menu-block-2 > ul > li > a').click (function (e) {
    if ($(this).find ('ul:first').length > 0)
        e.preventDefault ();
});
真正的答案在于仅将preventDefault放在a标记上,并且仅当它是li标记的直接子级时,tjat是ul标记的直接子级,ul标记是块菜单的直接子级。请参见最后3行


下面的其余代码只应将click listener添加到包含ul标记的li标记中。尝试使用链接来限制创建的jQuery对象的数量。可能把事情搞砸了。您只需要从原来的位置删除preventDefault,然后再使用最后3行。

使用
$('block-menu-block-2>ul>li>a')
而不是
$('block-menu-block-2 ul-li')
没有意义阻止
  • 上的默认,没有默认。事件应该在
    @螺母上,不一定,事件向上而不是向下。如果
    没有阻塞和填充整个
  • 很容易单击
  • ,而不是
    @charlietfl My bad:),这将向每个项目添加一个处理程序,而不是使用事件委派。尽管以上不是委派事件。谢谢回答,但这仍然不是我需要的。问题是并非所有菜单项都有子菜单项,所以我需要在阻止默认设置之前进行检查。@Hansted我已经添加了检查
    $('#block-menu-block-2 ul li').each (function () { 
        var $this = $(this);
        if ($this.find ('ul:first').length > 0) {
            $this.click (function () {
                if ($this.find ('ul:visible').length > 0) {
                    $this.removeClass ('menuItemSelected').find ('ul').removeClass('menuItemSelected').hide ('blind');
                } else {
                    $this.parent ().find ('ul li').hide ('blind');
                    $this.parent ().find('.menuItemSelected').removeClass  ('menuItemSelected');
                    $this.addClass ('menuItemSelected').find ('ul').show ('blind').addClass ('menuItemSelected');
                }
            }); 
        }
    });
     $('#block-menu-block-2 > ul > li > a').click (function (e) {
        if ($(this).find ('ul:first').length > 0)
            e.preventDefault ();
    });