[jquery] 창 가장자리와 관련하여 팝 오버의 X 위치를 기준으로 부트 스트랩 팝 오버의 위치를 ​​변경 하시겠습니까?

나는 인터넷을 광범위하게 샅샅이 뒤 졌고이 stackoverflow 게시물이 통찰력있는 것을 발견했지만 화면 너비에 따라 부트 스트랩 팝 오버의 위치를 ​​변경할 수 있습니까? , 위치 / 오프셋을 이해하는 데 문제가 있었기 때문에 여전히 내 질문에 대답하지 못했습니다.

여기 내가하려는 일이 있습니다. 핫스팟 팝 오버가 뷰포트 너머에 위치하지 않는 한 Twitter Bootstap Popover 위치를 RIGHT로 설정 한 다음 LEFT에 위치시키고 싶습니다. 핫스팟이있는 iPad 웹 앱을 만들고 있는데, 핫스팟을 누르면 정보가 표시되지만 수평 스크롤이 잠겨있을 때 뷰포트 외부에 표시되는 것을 원하지 않습니다.

나는 그것이 다음과 같이 될 것이라고 생각하고 있습니다.

$('.infopoint').popover({
        trigger:'hover',
        animation: false,
        placement: wheretoplace
    });
    function wheretoplace(){
        var myLeft = $(this).offset.left;

        if (myLeft<500) return 'left';
        return 'right';
    }

생각? 감사!



답변

방금 배치 옵션이 문자열 이거나 팝 오버 가능한 링크를 클릭 할 때마다 계산을 수행 하는 문자열반환하는 함수일 수 있음을 알았습니다 .

이렇게하면 초기 $ .each 함수 없이 수행 한 작업을 정말 쉽게 복제 할 수 있습니다.

var options = {
    placement: function (context, source) {
        var position = $(source).position();

        if (position.left > 515) {
            return "left";
        }

        if (position.left < 515) {
            return "right";
        }

        if (position.top < 110){
            return "bottom";
        }

        return "top";
    }
    , trigger: "click"
};
$(".infopoint").popover(options);


답변

Bootstrap 3의 경우

placement: 'auto right'

더 쉽습니다. 기본적으로 오른쪽이지만 요소가 화면 오른쪽에 있으면 팝 오버가 왼쪽에 있습니다. 따라서 다음과 같아야합니다.

$('.infopoint').popover({
   trigger:'hover',
   animation: false,
   placement: 'auto right'
});


답변

문서 auto에 따라 선호하는 배치와 함께 사용할 수 있어야합니다.auto left

http://getbootstrap.com/javascript/#popovers : “”자동 ​​”을 지정하면 팝 오버의 방향이 동적으로 조정됩니다. 예를 들어 배치가”자동 왼쪽 “인 경우 도구 설명은 가능한 경우 왼쪽에 표시되고 그렇지 않은 경우에는 왼쪽에 표시됩니다. 오른쪽으로 표시됩니다. “

나는 똑같은 일을하려고했지만이 기능이 이미 존재한다는 것을 깨달았습니다.


답변

그래서 저는 이것을 효과적으로하는 방법을 찾았습니다. 내 특정 프로젝트를 위해 iPad 웹 사이트를 구축하고 있으므로 화면 가장자리에 도달하는 픽셀 X / Y 값이 무엇인지 정확히 알았습니다. thisX 및 thisY 값은 다양합니다.

어쨌든 팝 오버는 인라인 스타일링으로 배치되기 때문에 각 링크의 왼쪽 및 상단 값을 잡아서 팝 오버의 방향을 결정합니다. 이는 .popover ()가 실행시 사용하는 html5 데이터 값을 추가하여 수행됩니다.

if ($('.infopoint').length>0){
    $('.infopoint').each(function(){
        var thisX = $(this).css('left').replace('px','');
        var thisY = $(this).css('top').replace('px','');
        if (thisX > 515)
            $(this).attr('data-placement','left');
        if (thisX < 515)
            $(this).attr('data-placement','right');
        if (thisY > 480)
            $(this).attr('data-placement','top');
        if (thisY < 110)
            $(this).attr('data-placement','bottom');
    });
    $('.infopoint').popover({
        trigger:'hover',
        animation: false,
        html: true
    });
}

모든 의견 / 개선은 환영하지만 값을 수동으로 입력하려는 경우 작업이 완료됩니다.


답변

bchhun의 대답은 올바른 방향으로 나아 갔지만 소스와 뷰포트 가장자리 사이에 사용 가능한 실제 공간을 확인하고 싶었습니다. 또한 공간이 충분하지 않은 경우 적절한 대체 방법으로 데이터 배치 속성을 기본 설정으로 존중하고 싶었습니다. 예를 들어 팝 오버가 오른쪽에 표시 될 공간이 충분하지 않은 경우 “오른쪽”은 항상 오른쪽으로 이동합니다. 이것이 제가 처리 한 방식이었습니다. 저에게는 효과가 있지만 조금 번거 롭습니다. 더 깨끗하고 간결한 솔루션에 대한 아이디어가있는 사람이 있다면보고 싶습니다.

var options = {
  placement: function (context, source) {
    var $win, $source, winWidth, popoverWidth, popoverHeight, offset, toRight, toLeft, placement, scrollTop;

    $win = $(window);
    $source = $(source);
    placement = $source.attr('data-placement');
    popoverWidth = 400;
    popoverHeight = 110;
    offset = $source.offset();

    // Check for horizontal positioning and try to use it.
    if (placement.match(/^right|left$/)) {
      winWidth = $win.width();
      toRight = winWidth - offset.left - source.offsetWidth;
      toLeft = offset.left;

      if (placement === 'left') {
        if (toLeft > popoverWidth) {
          return 'left';
        }
        else if (toRight > popoverWidth) {
          return 'right';
        }
      }
      else {
        if (toRight > popoverWidth) {
          return 'right';
        }
        else if (toLeft > popoverWidth) {
          return 'left';
        }
      }
    }

    // Handle vertical positioning.
    scrollTop = $win.scrollTop();
    if (placement === 'bottom') {
      if (($win.height() + scrollTop) - (offset.top + source.offsetHeight) > popoverHeight) {
        return 'bottom';
      }
      return 'top';
    }
    else {
      if (offset.top - scrollTop > popoverHeight) {
        return 'top';
      }
      return 'bottom';
    }
  },
  trigger: 'click'
};
$('.infopoint').popover(options);


답변

이것을 시도해 볼 수도 있습니다.

==> 뷰포트에서 타겟 / 소스 위치
가져 오기 ==> 하단의 공간이 툴팁 높이보다 작은 지 확인 ==> 하단의 공간이 툴팁 높이
보다 작 으면 페이지 위로 스크롤

placement: function(context, source){
  //get target/source position in viewport
  var bounds = $(source)[0].getBoundingClientRect();
      winHeight = $(window).height();

  //check wheather space from bottom is less that your tooltip height
  var rBottom = winHeight - bounds.bottom;

  //Consider 180 == your Tooltip height
  //if space from bottom is less that your tooltip height, this will scrolls page up
  //We are keeping tooltip position is fixed(at bottom)

  if (rBottom < 180){
    $('html, body').animate({ scrollTop: $(document).scrollTop()+180 }, 'slow');
  }

  return "bottom";
}


답변

data-placement = “auto left”와 같은 데이터 배치에서 자동을 사용할 수 있습니다. 화면 크기에 따라 자동으로 조정되며 기본 배치는 그대로 유지됩니다.