ウィンドウの端に対するポップオーバーのX位置に基づいて、ブートストラップポップオーバーの位置を変更しますか?


83

私はインターネットを広範囲にわたって精査しましたが、このスタックオーバーフローの投稿は洞察に満ちていることがわかりましたが、画面の幅に基づいてBootstrapポップオーバーの位置を変更することは可能ですか?、それでも私の質問に答えられませんでした。おそらく、位置/オフセットを理解するのに苦労したためです。

これが私がやろうとしていることです。ホットスポットポップオーバーがビューポートを超えて配置されない限り、Twitter Bootstap Popoverの位置を右にしたいので、左に配置します。ホットスポットのあるiPadWebアプリを作成しています。ホットスポットを押すと情報が表示されますが、水平スクロールがロックされているときにビューポートの外に表示されたくありません。

私はそれが次のようになると思っています:

$('.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ポップオーバーに配置するページレイアウトとコンテンツによっては、常に完全に機能するとは限らないため、これが最善の方法です。
ブロンデイビス2014年

これをありがとう。あなたに帰属せずに使用しても大丈夫ですか?
D.Tate 2015年

6
@ D.Tate Stackoverflowのすべては、帰属なしで使用できるはずだと思います。それに夢中になる;)
bchhun 2015年

3
left 515&を選択するロジックは何ですかtop 110
Murali Murugesan 2016

1
@MuraliMurugesanロジックはまったくありません。質問で提供された番号を使用しただけです。何でも使用できます。
bchhun 2016

35

Bootstrap 3には、

placement: 'auto right'

これは簡単です。デフォルトでは右になりますが、要素が画面の右側にある場合、ポップオーバーは左になります。したがって、次のようになります。

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

2
私はこれまでこれとさまざまな経験をしました。ブートストラップソースはまだ調べていませんが、要素の配置のみが考慮されており、ポップオーバーの位置は考慮されていないようです。したがって、エッジ上またはウィンドウエッジを超えている要素は、最大でもエッジでポップオーバーを取得しますが、エッジのすぐ上にある要素(たとえば)は、折り目の下でポップオーバーを取得します。
2015

1
いいえ、それは受け入れられた答えであるべきではありません。「配置」オプションでは、ウィンドウの端は考慮されず、親要素/コンテナの境界のみが考慮されます。したがって、たとえば「自動トップ」がある場合でも、下にスクロールすると、トップオフウィンドウに表示されます。
RZB

31

ドキュメントに基づいautoて、優先配置と組み合わせて使用できるはずです。auto left

http://getbootstrap.com/javascript/#popovers: "" auto "を指定すると、ポップオーバーの向きが動的に変更されます。たとえば、配置が" auto left "の場合、ツールチップは可能な場合は左に表示されます。それ以外の場合は、ツールチップが左に表示されます。正しく表示されます。」

私は同じことをしようとしていて、この機能がすでに存在していることに気づきました。


2
自動左は水平スクロールバーを提供します
Jitendra Vyas

3
viewport要素の親に基づいて計算されたくない場合は、を指定することもできます。
allicarn 2014

5

そこで、これを効果的に行う方法を考え出しました。私の特定のプロジェクトでは、iPad Webサイトを構築しているので、画面の端に到達するためのピクセル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 = "autoleft"のようにデータ配置でautoを使用できます。画面サイズに応じて自動調整され、デフォルトの配置のままになります。


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はそれを一般的な方法で構成し、それを使用することができます。

このようにして、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>

添加


より多くのオプションを設定するには、uはここに行くことができます

さらに多くはここで見つけることができます

更新


クリック後にポップアップが必要な場合は、JSオプションを次のtrigger: "click"ように変更できます-

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

Uはこのdata-trigger="click"ようにHTMLでカスタマイズすることもできます-

<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.