如何定位一个元素相对于另一个与jQuery?

我有一个隐藏的DIV,其中包含一个类似工具栏的菜单。

我有许多DIV,当鼠标悬停在它们上面时,它们可以显示菜单DIV。

是否有一个内置函数,将菜单DIV移动到活动(鼠标悬停)DIV的右上方?我正在寻找类似$(menu).position("topright", targetEl);的东西

434899 次浏览

tl;博士:(试试在这里)

如果你有以下HTML:

<div id="menu" style="display: none;">
<!-- menu stuff in here -->
<ul><li>Menu item</li></ul>
</div>


<div class="parent">Hover over me to show the menu here</div>

然后你可以使用下面的JavaScript代码:

$(".parent").mouseover(function() {
// .position() uses position relative to the offset parent,
var pos = $(this).position();


// .outerWidth() takes into account border and padding.
var width = $(this).outerWidth();


//show the menu directly over the placeholder
$("#menu").css({
position: "absolute",
top: pos.top + "px",
left: (pos.left + width) + "px"
}).show();
});

但是不管用!

这将工作,只要菜单和占位符有相同的偏移父。如果它们没有,并且你没有嵌套的CSS规则来关心#menu元素在DOM中的位置,则使用:

$(this).append($("#menu"));

位于#menu元素所在行之前。

但是还是不行!

你可能有一些奇怪的布局不适合这种方法。在这种情况下,只需使用jQuery。Ui的位置插件(在下面的回答中提到),它处理所有可能的情况。注意,在调用position({...})之前,你必须show()菜单元素;插件不能定位隐藏的元素。

3年后的2012年更新说明:

(原来的解决方案存档在这里为子孙后代)

所以,原来的方法并不理想。特别是,在以下情况下,它会失败:

  • 菜单的偏移父级不是占位符的偏移父级
  • 占位符有边框/填充

幸运的是,jQuery早在1.2.6中就引入了方法(position()outerWidth()),这使得在后一种情况下更容易找到正确的值。对于前一种情况,appending menu元素到占位符是有效的(但会破坏基于嵌套的CSS规则)。

像这样的东西?

$(menu).css("top", targetE1.y + "px");
$(menu).css("left", targetE1.x - widthOfMenu + "px");

这就是最后对我有用的方法。

var showMenu = function(el, menu) {
//get the position of the placeholder element
var pos = $(el).offset();
var eWidth = $(el).outerWidth();
var mWidth = $(menu).outerWidth();
var left = (pos.left + eWidth - mWidth) + "px";
var top = 3+pos.top + "px";
//show the menu directly over the placeholder
$(menu).css( {
position: 'absolute',
zIndex: 5000,
left: left,
top: top
} );


$(menu).hide().fadeIn();
};

这对我来说很管用:

var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});

这是我写的一个jQuery函数,它可以帮助我定位元素。

下面是一个用法示例:

$(document).ready(function() {
$('#el1').position('#el2', {
anchor: ['br', 'tr'],
offset: [-5, 5]
});
});

上面的代码将#el1的右下与#el2的右上对齐。['cc', 'cc']将#el1置于#el2的中间。确保#el1具有position: absolute和z-index: 10000(或一些非常大的数字)的css来保持它在顶部。

偏移选项允许您将坐标微调到指定的像素数。

源代码如下:

jQuery.fn.getBox = function() {
return {
left: $(this).offset().left,
top: $(this).offset().top,
width: $(this).outerWidth(),
height: $(this).outerHeight()
};
}


jQuery.fn.position = function(target, options) {
var anchorOffsets = {t: 0, l: 0, c: 0.5, b: 1, r: 1};
var defaults = {
anchor: ['tl', 'tl'],
animate: false,
offset: [0, 0]
};
options = $.extend(defaults, options);


var targetBox = $(target).getBox();
var sourceBox = $(this).getBox();


//origin is at the top-left of the target element
var left = targetBox.left;
var top = targetBox.top;


//alignment with respect to source
top -= anchorOffsets[options.anchor[0].charAt(0)] * sourceBox.height;
left -= anchorOffsets[options.anchor[0].charAt(1)] * sourceBox.width;


//alignment with respect to target
top += anchorOffsets[options.anchor[1].charAt(0)] * targetBox.height;
left += anchorOffsets[options.anchor[1].charAt(1)] * targetBox.width;


//add offset to final coordinates
left += options.offset[0];
top += options.offset[1];


$(this).css({
left: left + 'px',
top: top + 'px'
});


}

注意:这需要jQuery UI(不仅仅是jQuery)。

你现在可以使用:

$("#my_div").position({
my:        "left top",
at:        "left bottom",
of:        this, // or $("#otherdiv")
collision: "fit"
});

用于快速定位(jQuery UI/Position)。

你可以下载jQuery UI

为什么这么复杂?解决方法很简单

css:

.active-div{
position:relative;
}


.menu-div{
position:absolute;
top:0;
right:0;
display:none;
}

jquery:

$(function(){
$(".active-div").hover(function(){
$(".menu-div").prependTo(".active-div").show();
},function(){$(".menu-div").hide();
})

即使,

  • 其他任何地方都有两个div
  • 浏览器调整大小

你可以使用jQuery插件PositionCalculator

该插件还包括碰撞处理(翻转),因此类似工具栏的菜单可以放置在可见的位置。

$(".placeholder").on('mouseover', function() {
var $menu = $("#menu").show();// result for hidden element would be incorrect
var pos = $.PositionCalculator( {
target: this,
targetAt: "top right",
item: $menu,
itemAt: "top left",
flip: "both"
}).calculate();


$menu.css({
top: parseInt($menu.css('top')) + pos.moveBy.y + "px",
left: parseInt($menu.css('left')) + pos.moveBy.x + "px"
});
});

对于该标记:

<ul class="popup" id="menu">
<li>Menu item</li>
<li>Menu item</li>
<li>Menu item</li>
</ul>


<div class="placeholder">placeholder 1</div>
<div class="placeholder">placeholder 2</div>

这是小提琴:http://jsfiddle.net/QrrpB/1657/