首页 文章

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

提问于
浏览
349

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

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

是否有内置功能将菜单DIV移动到活动(鼠标悬停)DIV的右上角?我在寻找像 $(menu).position("topright", targetEl); 这样的东西

8 回答

  • 3

    这对我有用:

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

    NOTE: 这需要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 .

  • 395

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

    But it doesn't work!

    只要菜单和占位符具有相同的偏移父级,这将起作用 . 如果他们没有嵌套的CSS规则来关注 #menu 元素在DOM中的位置,请使用:

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

    就在定位 #menu 元素的行之前 .

    But it still doesn't work!

    您可能有一些奇怪的布局无法使用此方法 . 在这种情况下,只需使用jQuery.ui's position plugin(如下面_2561919中所述),它可以处理所有可能的可能性 . 请注意,在调用 position({...}) 之前,您必须 show() 菜单元素;插件无法定位隐藏元素 .

    Update notes 3 years later in 2012:

    (原始解决方案已存档here供后代使用)

    所以,事实证明我在这里的原始方法远非理想 . 特别是,如果:

    • 菜单's offset parent is not the placeholder' s偏移父级

    • 占位符有边框/填充

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

  • 14

    这最终对我有用 .

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

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

    以下是一个示例用法:

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

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

    偏移选项允许您按指定的像素数微移坐标 .

    源代码如下:

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

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

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

    It works even if,

    • 两个div放在其他地方

    • 浏览器重新调整大小

  • 3

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

  • 6

    像这样的东西?

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

相关问题