单击以关闭移动设备上的jQuery下拉菜单,同时保留其他行为

Click to close jQuery dropdown menu on mobile devices while retaining other behavior

本文关键字:下拉菜单 保留 其他 jQuery 移动 单击      更新时间:2023-09-26

我有一个非常简单的jQuery下拉菜单,其中包含通常的ul/li列表排列的链接。下拉列表的代码如下所示:

$('body').ready(function() {
      if(screen.width <= 720) {
          $('.dropdown').hover(function() { $(this).find('.subMenu').toggle(); });
          $('.dropdown').click(function() { if( $('this').css('display') != 'none') {
              $('this').toggle();
              }
          });
      }
      else
      {
          $('.dropdown').hover(
              function() { $(this).stop(true,true).find('.subMenu').slideDown("fast"); },
              function() { $(this).stop(true,true).find('.subMenu').hide(); } 
          );
      }
  });

在移动设备上(忽略 720 宽度,它现在仅用于测试),我想实现以下功能:

  • 用户点击带有下拉菜单的链接> 如果菜单已打开,请将其关闭

  • 用户点击链接,而另一个菜单已打开> 关闭上一个菜单,打开当前菜单

  • 用户点击页面上的其他位置>关闭所有打开的菜单

我发现悬停功能实际上处理 #2 和 #3,但我无法弄清楚如何让 #1 工作。我相当确定我知道为什么这种特殊的尝试

$('.dropdown').click(function() { if( $('this').css('display') != 'none') {
      $('this').toggle();
      }
});

失败。我猜点击(或点击,在这种情况下)触发悬停事件,该事件似乎优先,因此显示菜单,而不是隐藏它。

如何在移动设备上使其正常工作?

编辑:我正在使用jQuery v1.7.2

HTML列表结构如下,以防它帮助某人(删节版):

    <div id="navbar">
      <ul>
        <li class="dropdown"><a href="#">Link A</a></li>
        <li class="dropdown"><a href="#">Link B</a>
          <ul class="subMenu">
            <li><a href="#">Link 1</a></li>
            <li><a href="#">Link 2</a></li>
          </ul>
        </li>
      </ul>
    </div>

如果您使用 jq 1.7+,请尝试此演示 这里 http://jsfiddle.net/SCN5T/3/

$(function(){
    $(document).mousedown(function(){
         $('.dropdown .active').removeClass('active').children('ul').hide();
    })
    $('.dropdown').on('mousedown','.subMenu', function(e){
        e.stopPropagation();
        var elem = $(this);
        if(elem.is('.active')) {
            elem.children('ul').slideUp(150);
            elem.removeClass('active');
        } else {
             $('.dropdown .active').removeClass('active').children('ul').hide();
            elem.addClass('active').children('ul').slideDown(150);
        }
    });
    $('.subMenu').on('mousedown','ul', function(e){
        e.stopPropagation();
        alert('menu item clicked');
    });       
})

if( $('this').css('display') != 'none') 可以替换为 if($('this').is(':hidden'))

您可以使用 .siblings() 关闭其他菜单...看不到 HTML 代码来判断选择器的确切外观。

作为选项,您可以添加一些类来检查是否有其他打开的菜单......

  $('.dropdown').hover(function() { 
      $('.openedMenu .subMenu').hide().removeClass('openedMenu');
      $(this).find('.subMenu').toggle(); 
      $(this).addClass('openedMenu');
  });
  $('.dropdown').click(function() { 
      if( $('this').is(':hidden')) {
          $('this').toggle();
      }
  });

我只在 1 个移动 Web 项目中工作过,但我在点击事件方面也遇到了问题。我使用的是jQuery移动框架。解决方法是使用包含在jQm中的"tap"事件而不是click。由于我猜您没有使用jQuery移动版,因此我发现了这个插件,可以帮助您创建"点击"事件:http://aanandprasad.com/articles/jquery-tappable/

以下代码解决了我的特定问题:

$('html').mousedown(function() {
    $('.subMenu').hide();
    });
$('#navbar').mousedown(function(event) {
    event.stopPropagation();
    });
$('.dropdown').mousedown(function() {
    var ele = $(this).find('.subMenu');
    $('#navbar').find('.subMenu').each(function(index) { if(!$(this).is(ele)) $(this).hide(); } );
    ele.toggle();
    });

我遵循的基本思想是在收到鼠标按下事件时找到子菜单并隐藏它们,除非该元素是用户单击的菜单。然后,切换开关显示或隐藏菜单。 事件传播部分和 body/html 隐藏部分来自 acrashik 的答案,对 $('html') 的更改来自这个答案。