簡體   English   中英

如何在動態內容插入后重新定位 Bootstrap Popover?

[英]How to re-position a Bootstrap Popover after dynamic content insertion?

所以基本上每當我加載一個帶有空content選項的Bootstrap Popover並動態插入內容時,popover 就會失去正確的位置。

例如:

$('td.chartSection').each(function () {
    var $thisElem = $(this);
    $thisElem.popover({
        placement: 'top',
        trigger: 'hover',
        html: true,
        container: $thisElem,
        delay: {
            hide: 500
        },
        content: ' '
    });
});

//After popup is shown, run this event
$('td.chartSection').on('shown.bs.popover', function () {
    var $largeChart = $(this).find('.popover .popover-content');

    //Insert some dummy content
    $largeChart.html("dfjhgqrgf regqef  f wrgb wrbgqwtgtrg <br /> wfghjqerghqreg fbvwqbtwfbvfgb <br />efgwetrg");
});

我的問題:

是否有可以重新計算彈出框位置的方法,例如$('td.chartSection').popover('recalculate')

或者是否有另一種方法可以在不使用 CSS 樣式手動執行此操作的情況下重新定位彈出框?

工作演示

使用 Bootstrap v3.3.7:

您可以擴展 Popover 構造函數以添加對重新定位函數的支持。 您可以將此腳本放在加載引導程序的下方。

JSFiddle 演示

<script src="bootstrap.js"></script>
<script type="text/javascript">
$(function () {
    $.fn.popover.Constructor.prototype.reposition = function () {
        var $tip = this.tip()
        var autoPlace = true

        var placement = typeof this.options.placement === 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement

        var pos = this.getPosition()
        var actualWidth = $tip[0].offsetWidth
        var actualHeight = $tip[0].offsetHeight

        if (autoPlace) {
            var orgPlacement = placement
            var viewportDim = this.getPosition(this.$viewport)

            placement = placement === 'bottom' &&
                pos.bottom + actualHeight > viewportDim.bottom ? 'top' : placement === 'top' &&
                pos.top - actualHeight < viewportDim.top ? 'bottom' : placement === 'right' &&
                pos.right + actualWidth > viewportDim.width ? 'left' : placement === 'left' &&
                pos.left - actualWidth < viewportDim.left ? 'right' : placement

            $tip
                .removeClass(orgPlacement)
                .addClass(placement)
        }

        var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)

        this.applyPlacement(calculatedOffset, placement)
    }
})
</script>

然后在您需要在插入內容后重新定位工具提示時,在您的腳本中。 你可以打電話:

$element.popover('reposition')

不,沒有重新計算,而且真的沒有簡單的方法可以做到。 也就是說,您可以通過這種方式動態注入彈出框:

$('td.chartSection').on('mouseenter', function() {
    var myPopOverContent = 'This is some static content, but could easily be some dynamically obtained data.';
    $(this).data('container', 'body');
    $(this).data('toggle', 'popover');
    $(this).data('placement', 'top');
    $(this).data('content', myPopOverContent);
    $(this).popover('show');
});

$('td.chartSection').on('mouseout', function() {
    $(this).popover('hide');
});

只需將小提琴中的所有 js 替換為上述內容並檢查一下...

我剛打電話

button.popover('show');

它重新定位了它。

我有一個類似的情況,我有一個已經包含一些 HTML(加載微調器)的彈出窗口,並且當 ajax 調用返回時我正在更改內容。 在我的 ajax 回調函數中,這是我用來更改定位的代碼,因此它保持居中:

var originalHeight = $(popover).height();

$(popover).find('.popover-content').html(data);

var newHeight = $(popover).height();
var top = parseFloat($(popover).css('top'));
var changeInHeight = newHeight - originalHeight;

$(popover).css({ top: top - (changeInHeight / 2) });

當它已經加載到頁面時,我使用此代碼來調整彈出窗口的高度:

   var popover = $(this).closest('.popover');
   var sender = popover.prev();
   var adjustment = (sender.position().top - popover.height()) + 15;
   popover.css({ top: adjustment });

變量 sender 是 popover 居中的目標。

這受到上面@AlexCheuk 回答的啟發,但我需要一個使用Bootstrap 2的解決方案。 此外,在我的項目中,我不需要更改彈出框的位置,所以我刪掉了它。

$(function() {
    $.fn.popover.Constructor.prototype.reposition = function () {
        console.log('popover reposition is called');
        var $tip = this.tip();

        var placement = typeof this.options.placement === 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement;

        var pos = this.getPosition();
        var actualWidth = $tip[0].offsetWidth;
        var actualHeight = $tip[0].offsetHeight;

        function getCalculatedOffset (placement, pos, actualWidth, actualHeight) {
            return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
                   placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
                   placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
                /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width };
        }

        var calculatedOffset = getCalculatedOffset(placement, pos, actualWidth, actualHeight);

        this.applyPlacement(calculatedOffset, placement);
        console.log(this);
    };
});

調用它:

$element.popover('reposition')
window.dispatchEvent(new Event('resize'));

這對我有用。

如果彈出框的位置是“頂部”(如問題所示),您只需從頁面頂部調整其絕對位置即可。

我創建了一個函數來計算彈出框的高度,然后將其在頁面上的高度向上移動。

function adjustPopoverHeight($popoverElement) {     
    var height = $popoverElement.height();
    var adjustment = 0 - height - 4;
    $popoverElement.css({ top: adjustment });
}

並與 ajax 請求一起使用以獲取數據:

 $.ajax({
    type: 'GET',
    url: url,
    contentType: 'application/json; charset=utf-8',
    dataType: 'json'
}).done(function(dat) { 
    //set the popover content to whatever you like

    //adjust height of popover
    var $popoverElement = $('.popover');
    adjustPopoverHeight($popoverElement);
})

我采用了 jme11 的答案的概念並針對 Bootstrap 3.3.2+ 進行了更新

$('button')
  .popover({
    trigger: 'manual',
    html: true,
    container: 'body',
  })
  .click(function() {
    var $this = $(this);
    var popover_obj = $this.data('bs.popover');
    if (popover_obj.tip().hasClass('in')) {
      popover_obj.hide();
    } else {
      var opts = popover_obj.options;
      opts.content = $('<div/>').text('hello world');
      popover_obj.init('popover', $this, opts);
      popover_obj.show();
    }
  })
;

popover 對象上有一個名為 setContent 的方法,但由於某種原因它對我不起作用。 如果你想嘗試,它看起來像這樣:

popover_obj.setContent($('<div/>').text('hello world'));

在 Popover 內容更新后,如果您在頁面內容上向上或向下滾動,Popover 會進行自動定位並再次可讀,因此在動態內容更新后重新定位 Popover 的更簡單的解決方法是向下和向上滾動 1 個像素在頁面上通過純 javascript

var y = $(window).scrollTop(); //your current y position on the page $(window).scrollTop(y+1).scrollTop(y-1);

在 DOM 中動態插入其他元素后,我遇到了定位問題,我使用container選項解決了這些問題。 默認情況下,我的彈出框附加到body

將它們連接到最近的容器解決了位置問題。

<div id="test">
    <span
        data-container="#test" data-toggle="popover" data-placement="top" title="Help"
        data-trigger="hover" tabindex="-1" data-html="true"
        data-content="Some text">
</div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM