Comment positionner un élément par rapport à un autre avec jQuery?

j'ai un DIV caché qui contient un menu semblable à une barre d'outils.

j'ai un certain nombre de DIVs qui sont activés pour montrer le menu DIV quand la souris plane au-dessus d'eux.

y a-t-il une fonction intégrée qui déplacera le menu DIV en haut à droite du DIV actif (curseur de la souris)? Je cherche quelque chose comme $(menu).position("topright", targetEl);

347
demandé sur Andreas Niedermair 2008-10-01 19:01:01

8 réponses

vous pouvez maintenant utiliser:

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

pour positionnement rapide ( jQuery UI/Position ).

NOTE: Cela nécessite jQuery UI (et pas seulement de jQuery).

Vous pouvez télécharger jQuery UI ici .

197
répondu Uriel 2018-08-23 20:06:37

tl;dr: (essayez ici )

si vous avez le code HTML suivant:

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

alors vous pouvez utiliser le code JavaScript suivant:

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

mais ça ne marche pas!

cela fonctionnera aussi longtemps que le menu et le paramètre auront le même parent offset. S'ils ne le font pas, et vous n'avez pas imbriqué CSS règles qui se soucient où dans le DOM l'élément #menu est, utiliser:

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

juste avant la ligne qui positionne l'élément #menu .

mais ça ne marche toujours pas!

vous pourriez avoir une mise en page bizarre qui ne fonctionne pas avec cette approche. Dans ce cas, il suffit d'utiliser jQuery.la position de l'ui plugin (comme mentionné dans un réponse ci-dessous), qui gère toutes les éventualités possibles. Notez que vous devrez show() l'élément de menu avant d'appeler position({...}) ; le plugin ne peut pas positionner les éléments cachés.

notes de mise à Jour 3 ans plus tard, en 2012:

(la solution originale est archivée ici pour la postérité)

Donc, il s'avère que la méthode originale que j'ai eu ici était loin d'être idéale. Dans en particulier, il échouerait si:

  • le parent offset du menu n'est pas le parent offset du placeholder
  • le placeholder a une bordure / rembourrage

heureusement, jQuery a introduit des méthodes ( position() et outerWidth() ) dans le 1.2.6 qui rendent la recherche des bonnes valeurs dans ce dernier cas beaucoup plus facile. Dans le premier cas, append ing l'élément de menu du placeholder fonctionne (mais enfreindre les règles CSS basées sur la nidification).

395
répondu Jacob 2017-05-23 11:47:10

C'est ce qui a fonctionné pour moi à la fin.

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();
};
13
répondu paul 2008-10-02 07:16:12

Voici une fonction jQuery que j'ai écrite qui m'aide à positionner des éléments.

voici un exemple d'usage:

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

le code ci-dessus aligne la partie inférieure droite de #el1 avec la partie supérieure droite de #el2. ['cc',' cc'] centrerait #el1 dans #el2. Assurez-vous que #el1 a le css DE position: absolute et z-index: 10000 (ou un nombre vraiment important) pour le garder en haut.

l'option offset vous permet de déplacer les coordonnées par un nombre de pixels spécifié.

le code source est le suivant:

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

}
6
répondu Venkat D. 2009-07-15 00:19:21

Pourquoi compliquer trop? La Solution est très 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();
})

Il fonctionne même si,

  • deux divs placés ailleurs
  • navigateur redimensionné
3
répondu gtamil 2011-09-29 11:59:17

vous pouvez utiliser le plugin jQuery calculateur de position

ce plugin a également inclus la gestion de collision (flip), de sorte que le menu semblable à une barre d'outils peut être placé à une position 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"
    });
});

pour cette majoration:

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

voici le violon: http://jsfiddle.net/QrrpB/1657 /

3
répondu TLindig 2014-03-31 14:24:37

quelque chose comme ça?

$(menu).css("top", targetE1.y + "px"); 
$(menu).css("left", targetE1.x - widthOfMenu + "px");
2
répondu slf 2008-10-01 15:22:34

ça marche pour moi:

var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});
2
répondu devXen 2010-03-15 19:22:02