JQuery ile bir öğeyi diğerine göre nasıl konumlandırabilirim?


354

Araç çubuğu benzeri bir menü içeren gizli bir DIV var.

Fare üzerlerinin üzerine geldiğinde DIV menüsünü göstermek için etkinleştirilen bir dizi DIV var.

DIV menüsünü aktif (fare vurgulu) DIV'nin sağ üst kısmına taşıyacak yerleşik bir fonksiyon var mı? Gibi bir şey arıyorum$(menu).position("topright", targetEl);


1
meydana gelebilecek çok daha fazla sorunu ele alan stackoverflow.com/questions/8400876/… ' a göz atın
Toskan

Lütfen "Soruların başlıklarında" etiketler "bulunmalı mı?" , fikir birliği "hayır, yapmamalılar" olduğunda!
Andreas Niedermair

@paul Evet, tarzda ufak bir fark var. Bu sorunun ilk başlığı, teşvik edilmeyen jQuery: ile önekti . Genellikle, ön ekin işe yaramaz olmasını sağlayan sorunun ek etiketlenmesi nedeniyle. Eğer teknoloji başlığında gereklidir, bu yakalanan gereken gerçek , cümle değil, sadece bir önek - o etiketleri içindir budur çünkü.
Andreas Niedermair

Yanıtlar:


203

NOT: Bu jQuery UI gerektirir (sadece jQuery değil).

Artık şunları kullanabilirsiniz:

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

Hızlı konumlandırma için ( jQuery UI / Position ).

Sen edebilirsiniz Burada jQuery UI indir .


1
Positon eklentisi kullanmaya çalışıyorum ama bir nedenden dolayı işe yarayamıyorum :(
Salman A

Ayrıca benim için çalışmıyor. Bunu, gövdenin üzerine basit, düz renkli bir div yerleştirmek için kullanmaya çalışmak sol üst köşeye 17 piksel kapanmasına neden oldu.
Patlıcan Jeff

46
Bu cevabın sadece jQuery'ye değil, jQueryUI'ye bağlı olduğunu unutmayın. Neden birkaçınız için işe yaramadığını açıklayabilir.
11:12

398

tl; dr: ( burada deneyin )

Aşağıdaki HTML'niz varsa:

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

aşağıdaki JavaScript kodunu kullanabilirsiniz:

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

Ama işe yaramıyor!

Bu, menü ve yer tutucu aynı ofset üst öğesine sahip olduğu sürece çalışır. Bunlar yoksa ve #menuöğenin DOM'sinde nerede olduğunu önemseyen iç içe CSS kurallarınız yoksa şunları kullanın:

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

#menuöğeyi konumlandıran çizgiden hemen önce .

Ama yine de çalışmıyor!

Bu yaklaşımla çalışmayan garip bir düzeniniz olabilir. Bu durumda, akla gelebilecek her olasılığı ele alan jQuery.ui'nin pozisyon eklentisini ( aşağıdaki cevapta belirtildiği gibi) kullanmanız yeterlidir . show()Aramadan önce menü öğesine ihtiyacınız olduğunu unutmayın position({...}); eklenti gizli öğeleri konumlandıramaz.

2012'de 3 yıl sonra notları güncelleyin:

(Orijinal çözüm burada gelecek nesiller için arşivlenmiştir )

Yani, burada sahip olduğum orijinal yöntemin idealden uzak olduğu ortaya çıktı. Özellikle, aşağıdaki durumlarda başarısız olur:

  • menünün ofset ebeveyni yer tutucunun ofset ebeveyni değil
  • yer tutucunun bir kenarlığı / dolgusu var

Neyse ki, jQuery, 1.2.6'da buradaki ikinci durumda doğru değerleri bulmayı çok daha kolay hale getiren yöntemler ( position()ve outerWidth()) geri getirdi . Önceki durum appendiçin, menü öğesini yer tutucuya eklemek çalışır (ancak iç içe geçmeye dayalı CSS kurallarını kırar).


168
Whoa bu garip: Geçen gün bunu yapmak zorundaydım, nasıl olduğunu hatırlayamadım, googledim ve bu cevabı aldım! SOF'u sevmeliyim.
Jacob

17
Heh - başıma aynı şey geldi - bir şeyi nasıl yapacağımı hatırlayamadım ve Stack Overflow'da kendi cevabımı buldum.
Herb Caudill

16
Menü div stilinizin display: hidden yerine display: none kullanması gerektiğini düşünüyorum.
Gabe

6
Menünün kapsayıcısı konum: göreli (veya devralma dışında bir şey) olduğunda bu düzgün çalışmaz, çünkü konum: mutlak bunu kapatacaktır ve .offset sayfanın sol üst köşesinden çıkacaktır.
Mike Cooper

3
Menünüzün nasıl konumlandığına bağlı olarak jQuery'nin .offset () yöntemi, .position () için bir açılır yedek olarak kullanılabilir. api.jquery.com/offset
Danny C

16

Sonunda benim için işe yarayan buydu.

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

İşte öğeleri konumlandırmama yardımcı yazdığım bir jQuery işlevi.

İşte bir örnek kullanım:

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

Yukarıdaki kod, # el1 öğesinin sağ alt köşesini # el2 öğesinin sağ üst köşesiyle hizalar. ['cc', 'cc'] # el1'i # el2 içinde ortalar. # El1'in css konumunda olduğundan emin olun: mutlak ve z-endeksi: 10000 (veya gerçekten çok büyük bir sayı).

Ofset seçeneği, koordinatları belirli sayıda pikselle dürtmenizi sağlar.

Kaynak kodu aşağıdadır:

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

Neden çok karmaşık? Çözüm çok basit

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

Olsa bile çalışır,

  • Başka bir yere yerleştirilmiş iki div
  • Tarayıcı Yeniden Boyutlandırıldı

ie için yer tutucuyu taklit etmek ve giriş yukarıda göstermek istiyorsanız bu yöntem işe yaramaz (
tibalt

Kardeş olan veya hatta tamamen ilgisiz olan iki öğeyi hizalamak istediğimde bu işe yaramaz, ki bu çok yaygındır.
oriadam

3

JQuery eklentisi PositionCalculator'ı kullanabilirsiniz

Bu eklenti ayrıca çarpışma yönetimi (flip) içeriyor, bu nedenle araç çubuğu benzeri menü görünür bir konuma yerleştirilebilir.

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

bu işaretleme için:

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

İşte keman: http://jsfiddle.net/QrrpB/1657/


Konsol, Tanımlanmamış satır için bir işlev olmadığını yazıyor: var pos = $ .PositionCalculator ({Lütfen sorunun çözülmesine yardımcı olabilir misiniz?
Alexandr Belov

@AlexandrBelov: Sanırım eklentiyi yüklemediniz. Kullanmadan önce PositionCalculator eklentisinin js dosyasını yüklemelisiniz.
TLindig

2

Böyle bir şey mi?

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

2

Bu benim için çalışıyor:

var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.