私はインターネットを広範囲に精査しましたが、このstackoverflowの投稿は洞察力に富んでいますが 画面幅に基づいてBootstrap popoversの位置を変更することは可能ですか? 、それでもいませんでした私の質問に答えてください。おそらく位置/オフセットを理解するのが難しいからです。
これが私がやろうとしていることです。ホットスポットのポップオーバーがビューポートの外側に配置されない限り、Twitter Bootstap Popoverの位置を右にしたいので、左に配置したいです。ホットスポットを持つiPad Webアプリを作成しています。ホットスポットを押すと情報が表示されますが、水平スクロールがロックされているときにビューポートの外側に表示されたくないです。
私はそれがこのようなものになると思っています:
$('.infopoint').popover({
trigger:'hover',
animation: false,
placement: wheretoplace
});
function wheretoplace(){
var myLeft = $(this).offset.left;
if (myLeft<500) return 'left';
return 'right';
}
考え?ありがとう!
placementオプションは、ポップオーバーをクリックするたびに計算を行うstringまたはstringを返す関数のいずれかであることに気付きました-可能なリンク。
これにより、最初の$。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);
ドキュメントに基づいて、auto
を優先配置と組み合わせて使用できる必要があります。 auto left
http://getbootstrap.com/javascript/#popovers : "" auto "が指定されている場合、ポップオーバーを動的に再配置します。たとえば、配置が" auto left "の場合、ツールチップが表示されます可能な場合は左に、そうでない場合は右に表示されます。」
私は同じことをしようとしていましたが、この機能がすでに存在していることに気付きました。
Bootstrap 3には、
placement: 'auto right'
簡単です。デフォルトでは正しいですが、要素が画面の右側にある場合、ポップオーバーは左になります。したがって、次のようになります。
$('.infopoint').popover({
trigger:'hover',
animation: false,
placement: 'auto right'
});
そこで、これを効果的に行う方法を見つけました。私の特定のプロジェクトでは、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
});
}
コメント/改善は歓迎しますが、値を手動で入力しても構わないのであれば、これで仕事は完了です。
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";
}
Bchhunの素晴らしい答えに加えて、absoulteポジショニングが必要な場合は、これを行うことができます
var options = {
placement: function (context, source) {
setTimeout(function () {
$(context).css('top',(source.getBoundingClientRect().top+ 500) + 'px')
},0)
return "top";
},
trigger: "click"
};
$(".infopoint").popover(options);
私は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
};
この関数は、要素の位置に基づいて、Bootstrap popover floatの位置を最適な位置に移動します。
Data-placement = "auto left"のようなデータ配置でautoを使用できます。画面サイズに応じて自動的に調整され、デフォルトの配置が残ります。