3

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

有没有办法让菜单根据它是否会超出 div 的范围来放大或缩小?

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

请注意“Salzburg”子菜单如何超出黑色 DIV 的范围?如果它太长,我希望它长大,如果有足够的空间,我希望它长大。

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

谢谢!

4

2 回答 2

1

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

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

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

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

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

更新

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

  1. 关闭动画(以避免丑陋的故障)
  2. 添加一个观察者,它会持续监控即将打开的元素
  3. 如果打开,应用位置修正

无论如何,如果您考虑到这一步,您不妨覆盖 jquery ui 组件的默认定位,并注意您将无法轻松更新库。更新:或者试试Rudy Garcia 的版本,如果可行的话

演示

演示代码:  

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
});
于 2013-04-22T16:42:28.057 回答
1

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

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

您可以使用 position 选项以您想要的方式定位元素。

这将改变位置,使它们在框内,但是您将希望动态访问最后一个以为其提供所需的位置,因为下面的代码会将所有菜单项更改为向上移动 50。

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

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

显然,jquery UI 已经考虑到了这一点,并提供了“在”选项以确保您的元素保持在您选择的另一个元素内。

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

$( "#menu" ).menu({ position: {within: '#menuContainer' } });
于 2013-04-22T18:52:28.040 回答