在移动设备上定位jQuery下拉菜单,使其完全显示在屏幕上。

3

我有一个基本的jQuery下拉菜单,并在手机上进行测试。

遇到的一个问题是,右侧的子菜单有时会超出屏幕边缘,因为其中一个或多个项目中的文本太长。用户当然可以向右滚动一点,但这不是一个很好的解决方案。有一个类似的问题here,但我无法让提出的答案起作用(而且由于我仍然完全不了解JS / jQuery,所以我徘徊不前)。

一般的想法似乎是获取当前子菜单的左位置+宽度(确保首先显示它们,然后再隐藏它们或在用户点击菜单时显示它们并将它们移动),然后查看该值是否大于屏幕宽度。如果是,则应将其向左移动差值。然而,我的尝试似乎对元素没有任何影响,菜单仍然部分地出现在屏幕外。目前,我有以下代码(在body加载后运行):

var menus = $('#navbar').find('.subMenu');
menus.show();
menus.each(function(index) {
  var offsetMenu = $(this).offset();
  var diff = screen.width - ($(this).outerWidth + offsetMenu.left);
  if(diff < 0) {
    $(this).offset({top:offsetMenu.top, left:offsetMenu + diff});
  }
  });
menus.hide();

jQuery的版本为1.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>

我该怎么让它起作用?
编辑:这是相关的CSS。
#navbar ul.subMenu {
    position:absolute;
    display:none;
    background-color:#FFAF1E;
}
#navbar ul.subMenu li {
    clear:both;
}
#navbar a {
    text-decoration:none;
    color:#0C1F6E;
    display:block;
    padding-right:10px;
    padding-left:10px;
}
3个回答

2
我终于成功实现了以下内容:
function adjustSubMenus()
  {
      var menus = $('#navbar').find('.subMenu');
      menus.each(function(){
          $(this).css("left","");
          adjustSingleMenu($(this))
          } );
  }
  function adjustSingleMenu(element)
  {
      element.show();
      var thisMenuWidth = element.outerWidth();
      var thisMenuPos = element.offset();
      var diff = (thisMenuWidth + thisMenuPos.left) - window.outerWidth;
      if(diff > 0) {
          element.css("left", function() { return thisMenuPos.left - diff; });
      }
      element.hide();
  }
  $('body').ready(function() {
      $(window).resize(adjustSubMenus());
      if(window.outerWidth <= 720) {
          $('html').mousedown(function() {
              $('#navbar').find('.subMenu').each(function(index) { 
                if($(this).is(":visible") ) {
                    $(this).css("left","");
                    $(this).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).is(":visible") ) {
                    $(this).css("left","");
                    $(this).hide(); 
                    }
              } );
              if(ele.is(":visible")) {
                  ele.css("left","");
                  ele.hide();
              }
              else {
                  adjustSingleMenu(ele);
                  ele.show();                 
              }
              });
      }
      else
      {
          $('.dropdown').hover(
              function() { $(this).find('.subMenu').stop(true,true).slideDown("fast"); },
              function() { $(this).find('.subMenu').stop(true,true).hide(); } 
          );
      }
  });

唯一的小问题是,如果在更改手机方向时您有一个打开的菜单,则菜单可能会出现在屏幕外。关闭并重新打开菜单即可解决此问题。其他所有功能都完美无缺。

1
你可以尝试创建仅适用于移动设备的CSS(绑定到CSS类名),然后在检测到窄屏幕或移动设备时,将CSS类添加到你的元素中。
JavaScript:
if (is_mobile)
{
    $(".subMenu").addClass('mobile');
}

CSS:

/* CSS */
.mobile { width:100%; left:0 !important; position:absolute; }

如果可能的话,我更愿意重新定位元素。 - Gemini14

1

这个函数不应该检查子菜单的宽度加上其左偏移量,然后如果大于屏幕宽度,则将左值设置为0,宽度设置为屏幕宽度吗?

例如:

    var menus = $('#navbar').find('.subMenu'),
        screenWidth = $(window).width();
        //screenWidth = screen.width; //I assume this calculates the screens width properly
    menus.show();
    menus.each(function(index) {
      var thisMenu = $(this),
          thisMenuWidth = thisMenu.outerWidth(),
          thisMenuLeft = thisMenu.offset().left;
      if(screenWidth < (thisMenuWidth + thisMenuLeft)) {
        thisMenu
            .width(screenWidth)
            .css({ //could replace this with .addClass("yourClass") and add this styling to that "yourClass" instead
             "left": "0", 
             "position": "absolute"
            });
      }
      });
    menus.hide();

更新:

我以为screen.width是你已经为移动设备设计的一些特殊计算。我现在已经更改了这行代码。上面的代码应该可以工作。我看到你已经有一个解决方案,但那并不能修复菜单的宽度。如果菜单比屏幕宽,上述方法将修复其宽度。


很遗憾,它没有起作用。将元素浮动到右侧是否会调整它,使其完全保持在屏幕内? - Gemini14

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