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


83

나는 인터넷을 광범위하게 샅샅이 뒤 졌고이 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';
    }

생각? 감사!

답변:


177

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

이렇게하면 초기 $ .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);

1
이것은 auto페이지 레이아웃과 팝 오버에 넣은 콘텐츠에 따라 항상 완벽하게 작동하지 않기 때문에 가장 좋은 방법 입니다.
Bron Davies

감사합니다. 귀속없이 사용해도 괜찮습니까?
D.Tate 2015 년

6
@ D.Tate 나는 stackoverflow의 모든 것이 어떤 귀속없이 사용할 수 있어야한다고 믿습니다. 그것으로 이동 미친)
bchhun

3
선택의 논리 무엇 left 515&top 110
무랄리 Murugesan을

1
@MuraliMurugesan 전혀 논리가 없습니다. 나는 단지 질문에 제공된 숫자를 사용했습니다. 원하는 것을 사용할 수 있습니다.
bchhun

35

Bootstrap 3의 경우

placement: 'auto right'

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

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

2
나는 지금까지 이것과 혼합 된 경험을했다. 아직 부트 스트랩 소스를 보지 않았지만, 팝 오버의 위치가 아닌 요소 위치 만 고려한 것 같습니다. 따라서 가장자리에 있거나 창 가장자리를 벗어난 요소는 최대 가장자리에서 팝 오버를 받지만 가장자리 바로 위에있는 요소 (예 : 접힌 부분 아래)는 팝 오버를 얻습니다.
Daved 2015-08-26

1
아니요, 허용되는 답변이되어서는 안됩니다. "배치"옵션은 창 가장자리 를 고려 하지 않고 상위 요소 / 컨테이너 경계 만 고려합니다. 따라서 예를 들어 '자동 상단'이있는 경우 아래로 스크롤 할 때 창 상단에 계속 표시됩니다.
rzb

31

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

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

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


2
자동 왼쪽에 수평 스크롤바 제공
Jitendra Vyas 2014

3
viewport요소의 상위 요소를 기반으로 계산하지 않으려면을 지정할 수도 있습니다.
allicarn 2014

5

그래서 저는 이것을 효과적으로하는 방법을 찾았습니다. 내 특정 프로젝트를 위해 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
    });
}

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


2

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

1

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

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

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";
}

0

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


0

bchhun의 훌륭한 답변 외에도 절대적인 위치를 원한다면 이렇게 할 수 있습니다.

var options = {
    placement: function (context, source) {
         setTimeout(function () {
               $(context).css('top',(source.getBoundingClientRect().top+ 500) + 'px')
         },0)
         return "top";
    },
    trigger: "click"
};
$(".infopoint").popover(options);

0

AngularJS에서 내 문제를 다음과 같이 해결했습니다.

var configPopOver = {
        animation: 500,
        container: 'body',
        placement: function (context, source) {
                    var elBounding = source.getBoundingClientRect();
                    var pageWidth = angular.element('body')[0].clientWidth
                    var pageHeith = angular.element('body')[0].clientHeith

                    if (elBounding.left > (pageWidth*0.34) && elBounding.width < (pageWidth*0.67)) {
                        return "left";
                    }

                    if (elBounding.left < (pageWidth*0.34) && elBounding.width < (pageWidth*0.67)) {
                        return "right";
                    }

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

                    return "top";
                },
        html: true
    };

이 함수는 요소 위치를 기반으로 부트 스트랩 팝 오버 플로트의 위치를 ​​최상의 위치로 수행합니다.


0
$scope.popoverPostion = function(event){
    $scope.pos = '';

       if(event.x <= 207 && event.x >= 140){
           $scope.pos = 'top';
           event.x = '';
       }
       else if(event.x < 140){
           $scope.pos = 'top-left';
           event.x = '';
       }
       else if(event.x > 207){
           $scope.pos = 'top-right';
           event.x = '';
       }

};

-2

페이지의 거의 모든 위치에서 필요한 경우이 작업을 시도 할 수도 있습니다.

U는 일반적인 방법으로 구성한 다음 사용할 수 있습니다.

이런 식으로 u는 HTML 요소와 원하는 것을 사용할 수도 있습니다. :)

$(document).ready(function()
                  {
  var options =
      {
        placement: function (context, source)
        {
          var position = $(source).position();
          var content_width = 515;  //Can be found from a JS function for more dynamic output
          var content_height = 110;  //Can be found from a JS function for more dynamic output

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

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

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

          return "top";
        }
        , trigger: "hover"
        , animation: "true"
        , html:"true"
      };
  $('[data-toggle="popover"]').popover(options);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>


<div class="container">
	<h3>Popover Example</h3>
	<a id="try_ppover" href="#" data-toggle="popover" title="Popover HTML Header" data-content="<div class='jumbotron'>Some HTML content inside the popover</div>">Toggle popover</a>
</div>

부가


더 많은 옵션을 설정하려면 여기 로 이동 하십시오 .

여기 에서 더 많은 정보를 찾을 수 있습니다 .

최신 정보


클릭 후 팝업을 원하면 JS 옵션을 다음 trigger: "click"과 같이 변경할 수 있습니다.

        return ..;
    }
    ......
    , trigger: "click"
    ......
};

U는 또한 다음 data-trigger="click"과 같이 HTML ading에서 사용자 정의 할 수 있습니다.

<a id="try_ppover" href="#" data-toggle="popover" data-trigger="click" title="Popover Header" data-content="<div class='jumbotron'>Some content inside the popover</div>">Toggle popover</a>

나는 그것이 더 지향적 인 코드가 될 것이고 더 재사용 가능하고 모두에게 더 도움이 될 것이라고 생각합니다. :).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.