我在这里建立了一个下拉菜单http://dev.driz.co.uk/jsonmenu/使用 JSON 动态构建菜单。这样做而不是将 HTML 放在页面本身中的原因是为了提高性能(只加载您需要的内容),这样我就可以将菜单放在表格之外。
我已经开始实现一种方法来根据菜单的高度和与窗口(浏览器窗口而不是可滚动容器)的接近程度来定位菜单。问题是当菜单的高度大于链接和视口(viewport)下方的空间时,它应该将菜单移动到上方,反之亦然。它的某些部分无法正常工作。
注意:定位是在插入 HTML 之后而不是在用户移动窗口等时在回调中完成的,这是因为如果用户滚动或类似的事情,菜单将被删除,所以这样做是没有意义的.
要求的代码:
$(document).ready(function () {
$('a.buildMenu').click(function (event) {
// Prevent normal behaviour
event.preventDefault();
// Stops it bubbling to the document
event.stopPropagation();
var link = $(this);
// If the menu already exists remove it and exit the request
if($(document).find('div#' + $(link).data('id')).length){
$('.buildMenu').removeClass('selected');
$('.menu').remove();
return false;
}
// Remove any other menus from the DOM
$('.buildMenu').removeClass('selected');
$('.menu').remove();
// Get the position of the link
var offset = link.offset();
var top = offset.top;
var left = offset.left;
var bottom = top + link.height();
var right = $(window).width() - link.width();
top = top + link.height();
bottom = bottom + link.height();
// Append the menu to the DOM in position
var menuInstance = $('<div class="menu loading">loading...</div>').appendTo('body').css({'position':'absolute','top':top,'left':left});
// Add the instance id
$(menuInstance).attr('id', $(link).data('id'));
// Add class of selected to clicked link
$(this).addClass('selected');
// Request JSON data
$.ajax({
url: 'menu.json',
timeout: 5000,
dataType: 'JSON',
success: function (data) {
// Build the menu
var ul = $("<ul/>").attr("id", data.menu.id).addClass(data.menu.class);
// For each menu item
$.each(data.menu.content.menuitem, function () {
var li = $("<li/>").appendTo(ul).addClass(this.liClass);
var anchor = $("<a/>").appendTo(li).attr("href", this.href).attr("title", this.title);
var span = $("<span/>").appendTo(anchor).addClass(this.icon).html(this.text)
});
// Remove the loading class and insert menu into instance
$(menuInstance).removeClass('loading').html(ul);
// If the menu is taller than the bottom space
if(menuInstance.height() > bottom) {
menuInstance.css({'top':'auto','bottom':bottom,'left':left});
}
// If the menu is taller than the top space
else if(menuInstance.height() > top) {
menuInstance.css({'top':top,'left':left});
}
// Default position...
else {
menuInstance.css({'top':top,'left':left});
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR, textStatus, errorThrown);
}
});
});
// Remove menu from DOM if anything except the menu is clicked
$(document).bind('click', function (event) {
var clicked = $(event.target);
if (!clicked.parents().hasClass('menu')) {
$('.buildMenu').removeClass('selected');
$('.menu').remove();
}
});
// Remove menu if user scrolls panel
$(window).bind('resize', function() {
$('.buildMenu').removeClass('selected');
$('.menu').remove();
});
$('div').bind('scroll', function() {
$('.buildMenu').removeClass('selected');
$('.menu').remove();
});
});
这是问题的屏幕截图(代码应该使该菜单出现在链接上方,因为它的高度大于链接下方的偏移空间)
最佳答案
看起来问题出在第 71-74 行。
// If the menu is taller than the bottom space
if(menuInstance.height() > bottom) {
menuInstance.css({'top':'auto','bottom':bottom,'left':left});
}
bottom
被计算为从窗口顶部到菜单链接底部的距离......你说的是“如果菜单高度大于那个”。
我认为您要检查的是菜单高度是否大于从菜单链接底部到窗口底部的距离。所以……
if(menuInstance.height() > ($(window).height() - bottom) )
这应该获取从链接底部到窗口底部的距离,并将其与菜单的高度进行比较。
然后您需要更正menuInstance
的位置。
'bottom': ($(window).height() - top) + link.height()
这是完整的代码...
// If the menu is taller than the bottom space
if (menuInstance.height() > ($(window).height() - bottom)) {
menuInstance.css({
'top': 'auto',
'bottom': ($(window).height() - top) + link.height(),
'left': left
});
}
关于jquery - 根据元素的高度和宽度在页面上定位元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9872735/