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);
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 .
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).
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();
};
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'
});
}
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é
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 /
quelque chose comme ça?
$(menu).css("top", targetE1.y + "px");
$(menu).css("left", targetE1.x - widthOfMenu + "px");
ça marche pour moi:
var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});