Como posicionar um elemento em relação a outro com jQuery?

Eu tenho um DIV oculto que contém um menu semelhante a uma barra de ferramentas.

Eu tenho um número de DIVs que estão habilitados para mostrar o menu DIV quando o mouse passa sobre eles.

Existe uma function incorporada que irá mover o menu DIV para o canto superior direito do DIV ativo (focagem do mouse)? Eu estou procurando por algo como $(menu).position("topright", targetEl);

Agora você pode usar:

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

Para posicionamento rápido ( jQuery UI / Position ).

NOTA: Isso requer o jQuery UI (não apenas o jQuery).

Você pode baixar o jQuery UI aqui .

tl; dr: (experimente aqui )

Se você tem o seguinte HTML:

  
Hover over me to show the menu here

então você pode usar o seguinte código 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(); }); 

Mas isso não funciona!

Isso funcionará desde que o menu e o espaço reservado tenham o mesmo pai de deslocamento. Se não tiverem, e você não tiver regras CSS aninhadas que importam onde o elemento #menu está no DOM, use:

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

logo antes da linha que posiciona o elemento #menu .

Mas ainda não funciona!

Você pode ter algum layout estranho que não funciona com essa abordagem. Nesse caso, basta usar o plugin de posição do jQuery.ui (como mencionado em uma resposta abaixo), que lida com todas as eventualidades imagináveis. Note que você terá que show() o elemento menu antes de chamar a position({...}) ; o plugin não consegue posicionar elementos ocultos.

Atualize as notas 3 anos depois em 2012:

(A solução original é arquivada aqui para a posteridade)

Então, o método original que eu tinha aqui estava longe de ser ideal. Em particular, falharia se:

  • o pai de deslocamento do menu não é o pai de deslocamento do espaço reservado
  • o espaço reservado tem uma borda / preenchimento

Felizmente, o jQuery introduziu os methods ( position() e outerWidth() ) em 1.2.6 que tornam muito mais fácil encontrar os valores corretos no último caso. Para o primeiro caso, append o elemento menu ao placeholder funciona (mas irá quebrar as regras CSS baseadas no aninhamento).

Isso é o que funcionou para mim no final.

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

Aqui está uma function jQuery que eu escrevi que me ajuda a posicionar elementos.

Aqui está um exemplo de uso:

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

O código acima alinha o canto inferior direito de # el1 com o canto superior direito de # el2. [‘cc’, ‘cc’] centralizam # el1 em # el2. Certifique-se de que # el1 tenha o css da posição: absolute e z-index: 10000 (ou algum número realmente grande) para mantê-lo no topo.

A opção de deslocamento permite que você desloque as coordenadas por um número especificado de pixels.

O código fonte está abaixo:

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

Por que complicar demais? A solução é muito simples

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

Funciona mesmo se

  • Dois divs colocados em outro lugar
  • Navegador Re-sized

Você pode usar o plugin PositionCalculator do jQuery

Esse plugin também incluiu o manuseio de colisão (flip), para que o menu semelhante a uma barra de ferramentas possa ser colocado em uma posição visível.

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

para essa marcação:

  
placeholder 1
placeholder 2

Aqui está o violino: http://jsfiddle.net/QrrpB/1657/

Algo assim?

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

Isso funciona para mim:

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