与其在每次更改剪辑范围时都对每个菜单进行欺骗,为什么不采用 JIT 方法?
<body>
<div id="viewport-proxy" style="visibility:hidden;
position:absolute; height:100%; width:100%; margin:0; padding:0;
top:0; left: 0; right:0; bottom:0;"></div>
...
var w = window, d = document, e = d.documentElement;
var g = d.getElementsByTagName('body')[0];
function appHeight() {
var a = w.innerHeight || e.clientHeight || g.clientHeight;
var b = $("#viewport-proxy").height();
return a < b ? a : b;
};
$(".dropdown").on('show.bs.dropdown', function () {
var windowHeight = appHeight();
var rect = this.getBoundingClientRect();
if (rect.top > windowHeight) return;
var menuHeight = $(this).children('.dropdown-menu').height();
$(this).toggleClass("dropup",
((windowHeight - rect.bottom) < menuHeight) &&
(rect.top > menuHeight));
});
显然,您必须在菜单来来去去时管理事件绑定。在 Nathan 的答案演变为上述内容的 Durandal 应用程序中,每一行都有一个上下文菜单,表示一个数据。我在数据加载时创建绑定,将它们保存在视图模型中并在停用时销毁它们。我不需要在激活时重新创建它们,因为这会调用数据加载例程,从而创建绑定。
我还添加了这个:
$(window).on("scroll resize", function () { $(".dropdown.open").dropdown("toggle"); });
您将它放在 shell.js 中,以便它提前加载并影响所有视图。如果还不是很明显,它的作用是在窗口滚动或调整大小时关闭任何打开的下拉菜单。这符合 Windows 约定,并且在发生调整大小或滚动事件时无需重新计算定位。
注意 appHeight 函数。甚至 jQuery 也无法准确报告手机上的窗口高度,但 appHeight 在我迄今为止测试过的每个平台和浏览器(IE、Ch、FF 桌面、IE、Ch、Sa 移动)上都能正常工作。
在其当前版本中,它测量一个绝对定位的隐藏 div 集以填充视口。这适用于 Android Chrome 但不适用于 IE,而代码中显示的另一种方法适用于 IE 但不适用于 Android Chrome,因此我使用两者并使用较小的数字。
在我的 Durandal 应用程序中,该函数被实现为应用程序对象的高度方法,但为了简洁明了,我将示例代码展平。