¿Cómo posicionar un elemento relativo a otro con jQuery?

Tengo un DIV oculto que contiene un menú similar a la barra de herramientas.

Tengo un número de DIV que están habilitados para mostrar el menú DIV cuando el mouse se cierne sobre ellos.

¿Hay una función incorporada que moverá el menú DIV a la parte superior derecha de la DIV activa (desplazamiento del mouse)? Estoy buscando algo como $(menu).position("topright", targetEl);

Ahora puede usar:

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

Para un posicionamiento rápido ( jQuery UI / Position ).

NOTA: Esto requiere jQuery UI (no solo jQuery).

Puede descargar la interfaz de usuario de jQuery aquí .

tl; dr: (pruébalo aquí )

Si tiene el siguiente HTML:

  
Hover over me to show the menu here

entonces puedes usar el siguiente 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(); }); 

¡Pero no funciona!

Esto funcionará siempre que el menú y el marcador de posición tengan el mismo elemento primario desplazado. Si no lo hacen, y usted no tiene reglas CSS anidadas que se preocupen por dónde en el DOM está el elemento #menu , use:

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

justo antes de la línea que coloca el elemento #menu .

¡Pero todavía no funciona!

Es posible que tenga un diseño extraño que no funciona con este enfoque. En ese caso, solo use el plugin de posición de jQuery.ui (como se menciona en la respuesta a continuación), que maneja todas las eventualidades imaginables. Tenga en cuenta que deberá show() el elemento del menú antes de llamar a la position({...}) ; el complemento no puede posicionar elementos ocultos.

Notas de actualización 3 años después en 2012:

(La solución original está archivada aquí para la posteridad)

Entonces, resulta que el método original que tenía aquí estaba lejos de ser ideal. En particular, fallaría si:

  • el elemento primario desplazado del menú no es el elemento desplazado del marcador de posición
  • el marcador de posición tiene un borde / relleno

Afortunadamente, jQuery introdujo métodos ( position() y outerWidth() ) en 1.2.6 que hacen que encontrar los valores correctos en este último caso sea mucho más fácil. Para el primer caso, append el elemento de menú al marcador de posición funciona (pero romperá las reglas de CSS basadas en el anidamiento).

Esto es lo que funcionó para mí al 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(); }; 

Aquí hay una función jQuery que escribí que me ayuda a posicionar elementos.

Aquí hay un ejemplo de uso:

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

El código anterior alinea la parte inferior derecha de # el1 con la parte superior derecha de # el2. [‘cc’, ‘cc’] centraría # el1 en # el2. Asegúrese de que # el1 tenga el css de posición: absoluto e índice z: 10000 (o un número realmente grande) para mantenerlo en la parte superior.

La opción de compensación le permite empujar las coordenadas en un número específico de píxeles.

El código fuente está a continuación:

 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 qué complicar demasiado? La solución es muy simple

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 incluso si,

  • Dos divs colocados en cualquier otro lugar
  • Navegador de nuevo tamaño

Puede usar el plugin jQuery PositionCalculator

Ese complemento también ha incluido el manejo de colisiones (voltear), por lo que el menú similar a la barra de herramientas se puede colocar en una posición visible.

 $(".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 ese marcado:

  
placeholder 1
placeholder 2

Aquí está el violín: http://jsfiddle.net/QrrpB/1657/

¿Algo como esto?

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

Esto funciona para mí:

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