jQueryを使用して、ある要素を別の要素に相対的に配置する方法は?


354

ツールバーのようなメニューを含む非表示のDIVがあります。

マウスを上に置いたときにメニューDIVを表示できるようにするDIVがいくつかあります。

メニューDIVをアクティブな(マウスホバー)DIVの右上に移動する組み込み関数はありますか?私はのようなものを探しています$(menu).position("topright", targetEl);


1
で見てstackoverflow.com/questions/8400876/...発生する可能性がありますどのように多くのアドレスより多くの問題
Toskan

「質問にタイトルに「タグ」を含める必要がありますか?」を参照してください、コンセンサスが「いいえ、彼らはすべきではない」です!
Andreas Niedermair 2015年

@paulはい、スタイルに若干の違いがあります。この質問の最初のタイトルはjQuery:始まりましたが、これは推奨されません。通常、質問の追加のタグ付けが原因で、接頭辞が役に立たなくなります。タイトルにテクノロジーが必要な場合は、接頭辞だけでなく実際の文でキャプチャする必要があります。それがタグの目的だからです。
Andreas Niedermair 2015年

回答:


203

注:これにはjQuery UI(jQueryだけでなく)が必要です。

あなたは今使うことができます:

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

高速位置決め(jQuery UI / Position)。

ここからjQuery UIダウンロードできます


1
私はpositonプラグインを使用しようとしましたが、何らかの理由でそれを機能させることができません:(
Salman A

また、私のために動作しません。これを使用して、ボディの上に単純な単色のdivを配置しようとすると、左上に17ピクセルずれます。
ナスジェフ2011

46
この回答は、jQueryだけでなく、jQueryUIにも依存することに注意してください。それがあなたのカップルのために働いていない理由を説明するかもしれません。
btubbs 2011年

398

tl; dr:(ここでお試しください

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

しかし、それはうまくいきません!

これは、メニューとプレースホルダーのオフセットの親が同じである限り機能します。そうではなく、#menu要素がDOMのどこにあるかを気にするネストされたCSSルールがない場合は、次のようにします。

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

#menu要素を配置する行の直前。

しかし、それでも動作しません!

このアプローチでは機能しない奇妙なレイアウトがあるかもしれません。その場合は、考えられるすべての結果を処理するjQuery.uiの位置プラグイン(以下の回答で説明)を使用するだけです。をshow()呼び出す前にmenu要素が必要になることに注意してくださいposition({...})。プラグインは非表示の要素を配置できません。

2012年の3年後のノートの更新:

(元のソリューションは後世のためにここにアーカイブされています

ですから、私がここで使用した元の方法は理想からかけ離れていることがわかります。特に、次の場合に失敗します。

  • メニューのオフセットの親は、プレースホルダーのオフセットの親ではありません
  • プレースホルダーにはボーダー/パディングがあります

幸い、jQuery は1.2.6でメソッド(position()およびouterWidth())を導入し、後者の場合に適切な値を簡単に見つけることができるようになりました。前者の場合、appendメニュー要素をプレースホルダーに接続すると機能します(ただし、ネストに基づくCSSルールに違反します)。


168
おっとこれはおかしいです:私は先日これをしなければなりませんでした、どうすればいいのか思い出せず、ググってみて...この答え!SOFが大好きです。
Jacob

17
Heh-同じことが起こった-何かをする方法を思い出せず、Stack Overflowで自分の答えを見つけた。
Herb Caudill、

16
メニューのdivスタイルは、display:hiddenではなく、display:noneを使用する必要があると思います。
Gabe

6
これは、メニューのコンテナーに位置:相対(または継承以外の何か)がある場合は正しく機能しません。これは、位置:絶対がそれをキーオフし、.offsetがページの左上をキーオフするためです。
マイククーパー

3
メニューの配置に応じて、jQueryの.offset()を.position()のドロップイン置換として使用できます。api.jquery.com/offset
Danny C

16

これは結局私にとってうまくいったものです。

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

6

これが、要素の配置に役立つ、私が作成したjQuery関数です。

次に使用例を示します。

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

上記のコードは、#el1の右下を#el2の右上に揃えます。['cc'、 'cc']は#el1を#el2の中央に配置します。#el1が位置のCSSを持っていることを確認してください:絶対値とZ-インデックス: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'
  });

}

3

なぜ複雑すぎるのですか?解決策は非常に簡単です

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

それが機能しても

  • 他の場所に配置された2つのdiv
  • ブラウザのサイズ変更

ieのプレースホルダーをエミュレートしてinput(
tibalt

これは、兄弟である2つの要素を整列させたい場合や、非常に一般的な完全に無関係の場合でも機能しません。
oriadam

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/


コンソールは未定義のラインのための機能ではありません書き込みます?VAR POS = $ .PositionCalculator({あなたが問題を解決する助けをしてくださいすることができます
アレクサンドル・Belov

@AlexandrBelov:おそらく、プラグインをロードしていません。使用する前に、プラグインPositionCalculatorのjsファイルをロードする必要があります。
TLindig 2015

2

このようなもの?

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

2

これは私にとってはうまくいきます:

var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.