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

Posted

技术标签:

【中文标题】如何使用 jQuery 相对于另一个元素定位一个元素?【英文标题】:How to position one element relative to another with jQuery? 【发布时间】:2010-09-14 13:22:45 【问题描述】:

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

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

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

【问题讨论】:

看看***.com/questions/8400876/…,它解决了可能发生的更多问题 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”! @paul 是的,风格略有不同。此问题的初始标题以 jQuery: 为前缀,不鼓励这样做。通常,由于问题的附加标记,这使得前缀无用。如果标题中需要技术,则应在真实句子中捕获它,而不仅仅是前缀-因为这就是标签的用途。 【参考方案1】:

tl;dr:(试试here)

如果您有以下 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's position plugin(如下面的answer 所述),它可以处理所有可能发生的事件。请注意,在调用 position(...) 之前,您必须先 show() 菜单元素;插件无法定位隐藏元素。

3 年后的 2012 年更新说明:

(原解决方案存档here供后人使用)

所以,原来我在这里的原始方法远非理想。特别是,如果出现以下情况,它将失败:

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

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

【讨论】:

哇,这太奇怪了:前几天我不得不这样做,不记得怎么做了,用谷歌搜索得到......这个答案!一定要爱 SOF。 嘿 - 我也遇到过同样的事情 - 不记得该怎么做,在 Stack Overflow 上找到了我自己的答案。 我认为你的菜单 div 样式应该使用 display:none 而不是 display:hidden。 当菜单的容器具有 position: relative (或继承之外的任何内容)时,这将无法正常工作,因为 position: absolute 将关闭它,而 .offset 将关闭顶部-页面左侧。 根据您的菜单的定位方式,jQuery 的 .offset() 可以用作 .position() 的替代品。api.jquery.com/offset【参考方案2】:

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

您现在可以使用:

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

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

你可以download jQuery UI here。

【讨论】:

我一直在尝试使用 positon 插件,但由于某种原因我无法让它工作:( 对我也不起作用。尝试使用它在 body 上方放置一个简单的纯色 div 导致它在左上角偏移 17 个像素。 请注意,这个答案取决于 jQueryUI,而不仅仅是 jQuery。可能会解释为什么它不适合你们中的几个人。 无响应 :(【参考方案3】:

这最终对我有用。

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

这是我编写的一个 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'
  );


【讨论】:

【参考方案5】:

为什么要复杂化太多?解决方法很简单

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 放置在其他任何地方 浏览器调整大小

【讨论】:

如果我想模拟 ie 的占位符并将其显示在输入上方( 当我想对齐两个兄弟甚至完全不相关的元素时,这不起作用,这很常见。【参考方案6】:

你可以使用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/

【讨论】:

控制台写 Undefined is not a function for the line: var pos = $.PositionCalculator( 你能帮忙解决这个问题吗? @AlexandrBelov:我猜,你没有加载插件。在使用它之前,你必须加载插件PositionCalculator的js文件。【参考方案7】:

这样的?

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

【讨论】:

【参考方案8】:

这对我有用:

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

【讨论】:

以上是关于如何使用 jQuery 相对于另一个元素定位一个元素?的主要内容,如果未能解决你的问题,请参考以下文章

让一个元素相对于父元素固定定位

如何查找已动态创建且存在于另一个元素中的选择下拉列表的值和 ID

如何相对于另一个组件布局组件?

iOS - 如何相对于另一个添加一个 UIButton?

如何在顺风中相对于另一个 div 设置绝对位置?

如何使position:fixed;相对于父元素定位