jQuery菜单如何在Div中包含子菜单

时间:2013-04-22 15:23:49

标签: javascript jquery html jquery-ui menu

我正在尝试在网页上的div中创建一个“应用程序”。这不能超过某些尺寸(比方说:550px×280px)。我有一个菜单,每个项目至少有1-3个子菜单。问题是,虽然我知道子菜单不高于280px高,但子菜单通常会超出父div的界限(除了最后一个总是向上增长而不是向下增长)。

有没有办法让菜单增长或减少取决于它是否会超出div的范围?

这是一个JSFiddle:http://jsfiddle.net/3FqcG/

请注意“萨尔茨堡”子菜单如何超越黑色DIV的范围?如果有足够的空间,如果它太长而且太长,我希望它能够成长。

目前,我只是使用基本初始化:$( "#menu" ).menu();

谢谢!

3 个答案:

答案 0 :(得分:1)

我不相信你可以在CSS中做到这一点。

这给我们留下了javascript。基本思路是:

  1. 计算菜单的基线
  2. 如果它位于边界之外
    1. 向上移动菜单以更正位置
  3. 之后几乎幸福地生活

    但是,我们有一个主要问题:

    虽然我们捕获了元素的焦点,但我们不知道它的子菜单何时显示&定位。因此,尽管您的问题在技术上得到了解决,但到目前为止还不是理想的解决方案。

    <强>更新

    我能想到的最好的解决方法是:

    1. 关闭动画(以避免丑陋的故障)
    2. 添加一个能够持续监控即将打开的元素的观察者
    3. 如果打开,请应用位置校正
    4. 无论如何,如果你考虑到这么远,你也可以覆盖jquery ui组件的默认定位,注意你将无法轻松更新库。 更新:或尝试使用Rudy Garcia's version

      Demo

      演示代码:

      var BASE_OFFSET = $('#menuContainer').offset().top;
      var MAX_OFFSET = $('#menuContainer').height(); // get the offset of the container
      var whenVisible = function($el, callback){ //executes callback when $el is visible
          if($el.is(':visible')){ // if visible
              callback(); // execute callback
          }else{ // otherwise
              setTimeout(function(){whenVisible($el, callback);},10); // do the same check in 10 ms
          }
      };
      var fixPosition = function($menu){ // correct the position of the menu in respect to #menuContainer
          var h = $menu.outerHeight(true); // take the height of the menu
          var menuBottom = $menu.offset().top + h - BASE_OFFSET; // the baseline of the menu (taking into consideration the BASE_OFFSET)
          if(menuBottom > MAX_OFFSET){ // if this is outside the MAX height
              var diff = MAX_OFFSET - menuBottom; // calculate the difference
              var newTop = $menu.position().top + diff; // modify current positioning with the calculated diff value
              $menu.css('top', newTop + 'px'); // apply it to top (which is also used by jquery to position submenus
          }
          $.fx.off = false; // switch animations back on
      };
      $( "#menu" ).menu().on('menufocus', function(ev, ui){ // on the event menufocus
          var $ui = $(ui.item); //take the focused element
          var $menu = $ui.children('ul'); // take its related submenu
          if($menu.length === 0){ // if there is none 
              return; // just terminate
          }
          $.fx.off = true; // switch off jQuery effects (otherwise you'll have glitches)
          whenVisible($menu, function(){fixPosition($menu);}); // execute fixPosition when $menu is visible
      });
      

答案 1 :(得分:1)

您还可以查看此小部件的API:

http://api.jqueryui.com/menu/

您可以使用位置选项按要求定位元素。

这将改变位置,使它们在框内,但是你需要动态访问最后一个,以便给它你想要的位置,因为下面的代码将改变所有菜单项向上移动50。

$( "#menu" ).menu({ position: { my: "left top", at: "right+5 top-50" } });

此处还可找到完整的定位选项列表:http://api.jqueryui.com/position/

显然,jquery UI已经解决了这个问题,并且已经选择了“内部”以确保您的元素保留在您选择的另一个元素中。

因此,您的解决方案应该是:

$( "#menu" ).menu({ position: {within: '#menuContainer' } });

答案 2 :(得分:-1)

编辑样式:

#menuContainer {
    top:150px;
}

现场演示:http://jsfiddle.net/sk5Uj/