如何使用jQuery将一个元素相对于另一个元素进行定位?

时间:2021-11-05 21:26:29

I have a hidden DIV which contains a toolbar-like menu.

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

I have a number of DIVs which are enabled to show the menu DIV when the mouse hovers over them.

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

Is there a built-in function which will move the menu DIV to the top right of the active (mouse hover) DIV? I'm looking for something like $(menu).position("topright", targetEl);

是否有一个内置的函数可以将菜单DIV移动到活动(鼠标悬停)DIV的右上角?我在找$(菜单)之类的东西。位置(“topright targetEl);

8 个解决方案

#1


195  

You can now use:

现在,您可以使用:

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

For fast positioning (jQuery UI/Position).

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

NOTE: This requires jQuery UI (not just jQuery).

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

You can download jQuery UI here.

您可以在这里下载jQuery UI。

#2


394  

tl;dr: (try it here)

tl;:博士(试试看)

If you have the following HTML:

如果您有以下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>

then you can use the following JavaScript code:

然后可以使用以下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();
});

But it doesn't work!

但它不工作!

This will work as long as the menu and the placeholder have the same offset parent. If they don't, and you don't have nested CSS rules that care where in the DOM the #menu element is, use:

只要菜单和占位符具有相同的偏移量父元素,这就可以工作。如果它们没有,并且你没有嵌套的CSS规则,那么在DOM中,#菜单元素是什么,使用:

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

just before the line that positions the #menu element.

就在放置#menu元素的行之前。

But it still doesn't work!

但还是不行!

You might have some weird layout that doesn't work with this approach. In that case, just use jQuery.ui's position plugin (as mentioned in an answer below), which handles every conceivable eventuality. Note that you'll have to show() the menu element before calling position({...}); the plugin can't position hidden elements.

你可能会有一些奇怪的布局,但这并不适用于这种方法。在这种情况下,只需使用jQuery。ui的位置插件(如下面的答案所示),它可以处理所有可能发生的事情。注意,在调用position({…})之前,必须先显示()菜单元素;插件无法定位隐藏的元素。

Update notes 3 years later in 2012:

3年后的2012年更新说明:

(The original solution is archived here for posterity)

(最初的解决方案是为后代存档的)

So, it turns out that the original method I had here was far from ideal. In particular, it would fail if:

所以,原来我这里用的方法并不理想。特别是,如果:

  • the menu's offset parent is not the placeholder's offset parent
  • 菜单的偏移父级不是占位符的偏移父级
  • the placeholder has a border/padding
  • 占位符具有边框/填充

Luckily, jQuery introduced methods (position() and outerWidth()) way back in 1.2.6 that make finding the right values in the latter case here a lot easier. For the former case, appending the menu element to the placeholder works (but will break CSS rules based on nesting).

幸运的是,jQuery早在1.2.6中就引入了方法(position()和outerWidth()),这使得在后一种情况下更容易找到正确的值。对于前一种情况,将菜单元素附加到占位符上是可行的(但是会违反基于嵌套的CSS规则)。

#3


13  

This is what worked for me in the end.

这就是最终对我起作用的地方。

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();
};

#4


6  

Here is a jQuery function I wrote that helps me position elements.

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

Here is an example usage:

这里有一个示例用法:

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

The code above aligns the bottom-right of #el1 with the top-right of #el2. ['cc', 'cc'] would center #el1 in #el2. Make sure that #el1 has the css of position: absolute and z-index: 10000 (or some really large number) to keep it on top.

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

The offset option allows you to nudge the coordinates by a specified number of pixels.

偏移选项允许您以指定的像素点推动坐标。

The source code is below:

源代码如下:

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'
  });

}

#5


3  

Why complicating too much? Solution is very simple

为什么太复杂?解决方案是非常简单的

css:

css:

.active-div{
position:relative;
}

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

jquery:

jquery:

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

It works even if,

它的工作原理,即使

  • Two divs placed anywhere else
  • 两个女主角放在别的地方
  • Browser Re-sized
  • 浏览器调整大小

#6


3  

You can use the jQuery plugin PositionCalculator

您可以使用jQuery plugin PositionCalculator。

That plugin has also included collision handling (flip), so the toolbar-like menu can be placed at a visible position.

这个插件还包含了碰撞处理(flip),所以工具栏式的菜单可以放在一个可见的位置。

$(".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"
    });
});

for that markup:

的标记:

<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>

Here is the fiddle: http://jsfiddle.net/QrrpB/1657/

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

#7


2  

Something like this?

是这样的吗?

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

#8


2  

This works for me:

这工作对我来说:

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

#1


195  

You can now use:

现在,您可以使用:

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

For fast positioning (jQuery UI/Position).

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

NOTE: This requires jQuery UI (not just jQuery).

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

You can download jQuery UI here.

您可以在这里下载jQuery UI。

#2


394  

tl;dr: (try it here)

tl;:博士(试试看)

If you have the following HTML:

如果您有以下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>

then you can use the following JavaScript code:

然后可以使用以下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();
});

But it doesn't work!

但它不工作!

This will work as long as the menu and the placeholder have the same offset parent. If they don't, and you don't have nested CSS rules that care where in the DOM the #menu element is, use:

只要菜单和占位符具有相同的偏移量父元素,这就可以工作。如果它们没有,并且你没有嵌套的CSS规则,那么在DOM中,#菜单元素是什么,使用:

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

just before the line that positions the #menu element.

就在放置#menu元素的行之前。

But it still doesn't work!

但还是不行!

You might have some weird layout that doesn't work with this approach. In that case, just use jQuery.ui's position plugin (as mentioned in an answer below), which handles every conceivable eventuality. Note that you'll have to show() the menu element before calling position({...}); the plugin can't position hidden elements.

你可能会有一些奇怪的布局,但这并不适用于这种方法。在这种情况下,只需使用jQuery。ui的位置插件(如下面的答案所示),它可以处理所有可能发生的事情。注意,在调用position({…})之前,必须先显示()菜单元素;插件无法定位隐藏的元素。

Update notes 3 years later in 2012:

3年后的2012年更新说明:

(The original solution is archived here for posterity)

(最初的解决方案是为后代存档的)

So, it turns out that the original method I had here was far from ideal. In particular, it would fail if:

所以,原来我这里用的方法并不理想。特别是,如果:

  • the menu's offset parent is not the placeholder's offset parent
  • 菜单的偏移父级不是占位符的偏移父级
  • the placeholder has a border/padding
  • 占位符具有边框/填充

Luckily, jQuery introduced methods (position() and outerWidth()) way back in 1.2.6 that make finding the right values in the latter case here a lot easier. For the former case, appending the menu element to the placeholder works (but will break CSS rules based on nesting).

幸运的是,jQuery早在1.2.6中就引入了方法(position()和outerWidth()),这使得在后一种情况下更容易找到正确的值。对于前一种情况,将菜单元素附加到占位符上是可行的(但是会违反基于嵌套的CSS规则)。

#3


13  

This is what worked for me in the end.

这就是最终对我起作用的地方。

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();
};

#4


6  

Here is a jQuery function I wrote that helps me position elements.

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

Here is an example usage:

这里有一个示例用法:

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

The code above aligns the bottom-right of #el1 with the top-right of #el2. ['cc', 'cc'] would center #el1 in #el2. Make sure that #el1 has the css of position: absolute and z-index: 10000 (or some really large number) to keep it on top.

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

The offset option allows you to nudge the coordinates by a specified number of pixels.

偏移选项允许您以指定的像素点推动坐标。

The source code is below:

源代码如下:

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'
  });

}

#5


3  

Why complicating too much? Solution is very simple

为什么太复杂?解决方案是非常简单的

css:

css:

.active-div{
position:relative;
}

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

jquery:

jquery:

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

It works even if,

它的工作原理,即使

  • Two divs placed anywhere else
  • 两个女主角放在别的地方
  • Browser Re-sized
  • 浏览器调整大小

#6


3  

You can use the jQuery plugin PositionCalculator

您可以使用jQuery plugin PositionCalculator。

That plugin has also included collision handling (flip), so the toolbar-like menu can be placed at a visible position.

这个插件还包含了碰撞处理(flip),所以工具栏式的菜单可以放在一个可见的位置。

$(".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"
    });
});

for that markup:

的标记:

<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>

Here is the fiddle: http://jsfiddle.net/QrrpB/1657/

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

#7


2  

Something like this?

是这样的吗?

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

#8


2  

This works for me:

这工作对我来说:

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