360 votes

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

J'ai un DIV caché qui contient un menu de type barre d'outils.

J'ai un certain nombre de DIV qui sont activés pour afficher le DIV de menu lorsque la souris les survole.

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

1 votes

Jeter un coup d'œil à stackoverflow.com/questions/8400876/ qui traite de beaucoup plus de problèmes qui peuvent survenir

0 votes

Veuillez consulter "Les questions doivent-elles inclure des "tags" dans leurs titres ?" où le consensus est "non, ils ne devraient pas" !

0 votes

@paul Oui, il y a une légère différence dans le style. Le titre initial de cette question était préfixé de jQuery : ce qui n'est pas encouragé. Habituellement, en raison du balisage supplémentaire de la question, qui rend le préfixe inutile. Si le technologie est nécessaire dans le titre, il doit être capturé dans un fichier réel et pas seulement un préfixe, car c'est à cela que servent les balises.

402voto

Jacob Points 9117

tl;dr : (essayez-le aquí )

Si vous avez le 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 tant que le menu et l'espace réservé auront le même parent décalé. Si ce n'est pas le cas, et si vous n'avez pas de règles CSS imbriquées qui tiennent compte de l'emplacement dans le DOM de l'élément de menu et de l'élément de remplacement, vous pouvez utiliser les règles CSS. #menu l'élément est, l'utilisation :

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

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

Mais ça ne marche toujours pas !

Il se peut que vous ayez une disposition bizarre qui ne fonctionne pas avec cette approche. Dans ce cas, utilisez simplement Plugin de position de jQuery.ui (comme mentionné dans un réponse ci-dessous), qui gère toutes les éventualités imaginables. 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.

Mise à jour des notes 3 ans plus tard en 2012 :

(La solution originale est archivée aquí pour la postérité)

Il s'avère donc que la méthode originale que j'avais ici était loin d'être idéale. En particulier, elle échouait si :

  • le parent décalé du menu n'est pas le parent décalé de l'espace réservé.
  • l'espace réservé a une bordure/un bourrelet

Heureusement, jQuery a introduit des méthodes ( position() y outerWidth() ) dans la version 1.2.6, ce qui facilite grandement la recherche des bonnes valeurs dans le dernier cas. Pour le premier cas, append L'insertion de l'élément de menu dans l'espace réservé fonctionne (mais elle enfreint les règles CSS basées sur l'imbrication).

169 votes

Whoa, c'est flippant : J'ai dû faire ça l'autre jour, je ne me souvenais plus comment, j'ai cherché sur Google et j'ai trouvé... cette réponse ! J'adore les FOS.

18 votes

Heh - La même chose m'est arrivée - je ne me souvenais plus comment faire quelque chose, et j'ai trouvé ma propre réponse sur Stack Overflow.

16 votes

Je pense que le style de votre div menu devrait utiliser display:none au lieu de display:hidden.

210voto

Uriel Points 1561

NOTA: Cela nécessite jQuery UI (pas seulement jQuery).

Vous pouvez maintenant utiliser :

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

Pour un positionnement rapide ( jQuery UI/Position ).

Vous pouvez Téléchargez jQuery UI ici .

1 votes

J'ai essayé d'utiliser le plugin Positon mais pour une raison quelconque, je n'arrive pas à le faire fonctionner :(

0 votes

Cela ne fonctionne pas non plus pour moi. En essayant de l'utiliser pour positionner un simple div de couleur unie au-dessus du corps, il a été décalé de 17 pixels en haut à gauche.

47 votes

Notez que cette réponse dépend de jQueryUI, pas seulement de jQuery. Cela pourrait expliquer pourquoi elle ne fonctionne pas pour certains d'entre vous.

18voto

paul Points 4903

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

6voto

Venkat D. Points 1103

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

Voici un exemple d'utilisation :

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

Le code ci-dessus aligne le bas-droit de #el1 avec le haut-droit de #el2. ['cc', 'cc'] centrerait #el1 dans #el2. Assurez-vous que #el1 a les css de position : absolute et z-index : 10000 (ou un nombre vraiment important) pour le maintenir en haut.

L'option de décalage vous permet de déplacer les coordonnées d'un certain nombre de pixels.

Le code source se trouve ci-dessous :

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

}

4voto

gtamil Points 318

Pourquoi trop de complications ? 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();
})

Cela fonctionne même si,

  • Deux divs placés n'importe où ailleurs
  • Navigateur redimensionné

0 votes

Cette méthode ne fonctionne pas si je veux émuler le placeholder pour ie et le montrer au-dessus de l'entrée(

0 votes

Cela ne fonctionne pas lorsque je veux aligner deux éléments qui sont frères et sœurs ou même complètement sans rapport, ce qui est très courant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X