Как разместить один элемент относительно другого с помощью jQuery?
У меня есть скрытый DIV, который содержит меню в виде панели инструментов.
У меня есть ряд DIV, которые позволяют показывать меню DIV, когда мышь наводится над ними.
Есть ли встроенная функция, которая переместит меню DIV в верхнюю правую часть активного (курсор мыши) DIV? Я ищу что-то вроде $(menu).position("topright", targetEl);
Ответы
Ответ 1
tl; dr: (попробуйте здесь)
Если у вас есть следующий HTML:
<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>
то вы можете использовать следующий код 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();
});
Но это не сработает!
Это будет работать до тех пор, пока меню и местозаполнитель имеют одинаковый родитель-корреспондент. Если они этого не делают, и у вас нет вложенных правил CSS, которые заботятся о том, где в DOM находится элемент #menu
, используйте:
$(this).append($("#menu"));
непосредственно перед строкой, которая позиционирует элемент #menu
.
Но это все еще не работает!
У вас может быть какой-то странный макет, который не работает с этим подходом. В этом случае просто используйте jQuery.ui position plugin (как указано в answer ниже), который обрабатывает все мыслимые возможности. Обратите внимание, что вам нужно show()
элемент меню перед вызовом position({...})
; плагин не может размещать скрытые элементы.
Обновить примечания 3 года спустя в 2012 году:
(оригинальное решение архивировано здесь для потомков)
Итак, оказывается, что оригинальный метод, который у меня был здесь, был далек от идеала. В частности, он потерпит неудачу, если:
- родитель смещения меню не является родителем смещения заполнителя
- Заполнитель имеет границу/дополнение
К счастью, jQuery ввел методы (position()
и outerWidth()
) обратно в 1.2.6, что намного упростило поиск правильных значений в последнем случае. В первом случае append
элемент меню на местозаполнитель работает (но будет нарушать правила CSS на основе вложенности).
Ответ 2
Теперь вы можете использовать:
$("#my_div").position({
my: "left top",
at: "left bottom",
of: this, // or $("#otherdiv")
collision: "fit"
})
Для быстрого позиционирования (jQuery UI/Position).
ПРИМЕЧАНИЕ. Для этого требуется jQuery UI (а не только jQuery).
Вы можете загрузить jQuery UI здесь.
Ответ 3
Это то, что сработало для меня в конце.
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();
};
Ответ 4
Вот функция jQuery, которую я написал, которая помогает мне позиционировать элементы.
Вот пример использования:
$(document).ready(function() {
$('#el1').position('#el2', {
anchor: ['br', 'tr'],
offset: [-5, 5]
});
});
Приведенный выше код выравнивает нижнее правое число # el1 с правом верхнего края # el2. ['cc', 'cc'] будет центрировать # el1 в # el2. Убедитесь, что # el1 имеет значение css: absolute и z-index: 10000 (или некоторое действительно большое количество), чтобы сохранить его сверху.
Параметр offset позволяет вам подталкивать координаты на указанное количество пикселей.
Исходный код приведен ниже:
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'
});
}
Ответ 5
Почему слишком сложно усложнять? Решение очень просто
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();
})
Он работает, даже если
- Два divs помещены где-нибудь еще
- Изменение размера браузера
Ответ 6
Вы можете использовать плагин jQuery PositionCalculator
Этот плагин также включает обработку столкновений (flip), поэтому меню в виде панели инструментов можно поместить в видимое положение.
$(".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"
});
});
для этой разметки:
<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>
Вот скрипка: http://jsfiddle.net/QrrpB/1657/
Ответ 7
Что-то вроде этого?
$(menu).css("top", targetE1.y + "px");
$(menu).css("left", targetE1.x - widthOfMenu + "px");
Ответ 8
Это работает для меня:
var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});