jQuery를 사용하여 한 요소를 다른 요소에 상대적으로 배치하는 방법은 무엇입니까?


354

툴바와 같은 메뉴를 포함하는 숨겨진 DIV가 있습니다.

마우스를 가리킬 때 메뉴 DIV를 표시 할 수있는 많은 DIV가 있습니다.

메뉴 DIV를 활성 (마우스 호버) DIV의 오른쪽 상단으로 이동시키는 내장 기능이 있습니까? 나는 같은 것을 찾고 있습니다$(menu).position("topright", targetEl);


1
stackoverflow.com/questions/8400876/… 에서 더 많은 문제가 발생할 수있는 문제를 살펴보십시오
Toskan

참조하시기 바랍니다 태그 "를해야한다 질문은 다음과 같습니다" "자신의 제목에?" , 합의가 "아니오, 그들은해서는 안됩니다"!
Andreas Niedermair 8

@paul 예, 스타일에 약간의 차이가 있습니다. 이 질문의 초기 제목은 jQuery : 접두사로 시작되었으므로 권장하지 않습니다. 일반적으로 질문의 추가 태그로 인해 접두사가 쓸모 없게됩니다. 제목에 기술 이 필요한 경우 접두사뿐만 아니라 실제 문장으로도 기술 되어야합니다. 왜냐하면 그것이 태그의 목적이기 때문입니다.
Andreas Niedermair

답변:


203

참고 : jQuery UI (jQuery뿐만 아니라)가 필요합니다.

이제 다음을 사용할 수 있습니다.

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

빠른 위치 지정 ( jQuery UI / Position )

여기서 jQuery UI다운로드 할 수 있습니다 .


1
나는 positon 플러그인을 사용하려고 노력했지만 어떤 이유로 든 작동시킬 수 없습니다 :(
Salman A

또한 나를 위해 작동하지 않습니다. 이 옵션을 사용하여 본체 위에 간단한 단색 div를 배치하려고 시도하면 왼쪽 상단에서 17 픽셀 떨어져 있습니다.
가지 Jeff

46
이 답변은 jQuery뿐만 아니라 jQueryUI에 의존합니다. 왜 두 사람에게 효과가 없는지 설명 할 수 있습니다.
btubbs

398

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

그러나 작동하지 않습니다!

메뉴와 자리 표시자가 동일한 오프셋 부모를 갖는 한 작동합니다. 그렇지 않고 DOM에서 #menu요소의 위치를 신경 쓰는 중첩 된 CSS 규칙이없는 경우 다음을 사용하십시오.

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

#menu요소 를 배치하는 줄 바로 앞에 있습니다.

그러나 여전히 작동하지 않습니다!

이 방법으로 작동하지 않는 이상한 레이아웃이있을 수 있습니다. 이 경우 jQuery.ui의 위치 플러그인 ( 아래 답변에 언급 된 대로)을 사용하면 가능한 모든 상황을 처리 할 수 ​​있습니다. show()호출하기 전에 메뉴 요소 를 사용해야합니다 position({...}). 플러그인은 숨겨진 요소를 배치 할 수 없습니다.

3 년 후 2012 년에 메모 업데이트 :

(원래 솔루션은 후손을 위해 여기 에 보관 됩니다 )

그래서 내가 여기에 가지고 있던 원래의 방법은 이상적이지 않은 것으로 판명되었습니다. 특히 다음과 같은 경우 실패합니다.

  • 메뉴의 오프셋 부모가 자리 표시 자의 오프셋 부모가 아닙니다.
  • 자리 표시 자에 테두리 / 패딩이 있습니다

운 좋게도 jQuery는 1.2.6에서 메소드 ( position()outerWidth())를 도입 하여 후자의 경우 올바른 값을 훨씬 쉽게 찾을 수 있습니다. 전자의 경우 append메뉴 요소를 자리 표시 자에 사용하면 작동하지만 중첩에 따라 CSS 규칙이 위반됩니다.


168
우와, 이거 참 이상한데 : 다른 날에해야했는데 어떻게 기억하지 못했는지, 구글 검색해서 ... SOF를 좋아해야합니다.
Jacob

17
Heh-나에게 똑같은 일이 있었지만 무언가를 수행하는 방법을 기억하지 못하고 Stack Overflow에서 내 자신의 대답을 찾았습니다.
Herb Caudill

16
메뉴 div 스타일은 display : hidden 대신 display : none을 사용해야한다고 생각합니다.
Gabe

6
position : absolute는 키를 끄고 .offset은 페이지 왼쪽 상단에서 키를 떼기 때문에 메뉴의 컨테이너에 position : relative (또는 inherit 이외의 항목)가 있으면 올바르게 작동하지 않습니다.
마이크 쿠퍼

3
메뉴 위치에 따라 jQuery의 .offset ()을 .position ()의 대체 대체물로 사용할 수 있습니다. api.jquery.com/offset
Danny C

16

이것이 결국 나를 위해 일한 것입니다.

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

6

내가 작성한 jQuery 함수는 요소를 배치하는 데 도움이됩니다.

다음은 사용법 예입니다.

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

위의 코드는 # el1의 오른쪽 아래를 # el2의 오른쪽 위와 정렬합니다. [ 'cc', 'cc']는 # el1을 # el2의 중앙에 배치합니다. # el1이 CSS의 위치 : 절대 및 z- 인덱스 : 10000 (또는 실제로 큰 숫자)을 가지고 있는지 확인하십시오.

오프셋 옵션을 사용하면 지정된 픽셀 수만큼 좌표를 이동시킬 수 있습니다.

소스 코드는 다음과 같습니다.

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

}

3

왜 너무 복잡합니까? 해결책은 매우 간단합니다

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

경우에도 작동합니다.

  • 다른 곳에 배치 된 두 개의 div
  • 브라우저 크기 조정

자리 표시자를 에뮬레이션하고 입력 위에 표시하려는 경우이 방법이 작동하지 않습니다 (
tibalt

형제이거나 완전히 관련이없는 두 요소를 정렬하려고 할 때 작동하지 않습니다. 매우 일반적입니다.
oriadam

3

jQuery 플러그인 PositionCalculator를 사용할 수 있습니다

이 플러그인에는 충돌 처리 (플립)도 포함되어 있으므로 툴바와 같은 메뉴를 보이는 위치에 배치 할 수 있습니다.

$(".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/


콘솔은 정의되지 않은이 라인에 대한 함수가 아닙니다 기록 : var에 POS = $ .PositionCalculator ({당신이 만족 할 수의 도움으로 문제가 해결?
알렉산드르 Belov

@ AlexandrBelov : 플러그인을로드하지 않은 것 같습니다. 사용하기 전에 플러그인 PositionCalculator의 js 파일을로드해야합니다.
TLindig

2

이 같은?

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

2

이것은 나를 위해 작동합니다 :

var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.