twitter-bootstrap 如何在动态内容插入后重新定位 Bootstrap Popover?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23506472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 20:40:12  来源:igfitidea点击:

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

javascriptjquerycsstwitter-bootstrap

提问by Fizzix

So basically whenever I am loading a Bootstrap Popoverwith an empty contentoption and inserting content into it dynamically, the popover loses its correct position.

因此,基本上每当我加载带有空选项的Bootstrap Popovercontent并动态插入内容时,popover 都会丢失其正确位置。

For example:

例如:

$('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");
});

My Question:

我的问题:

Is there a method that can recalculate the popovers position such as $('td.chartSection').popover('recalculate').

有没有一种方法可以重新计算弹出窗口的位置,例如$('td.chartSection').popover('recalculate').

Or is there another way to re-position the popover without manually doing this with CSS styles?

或者是否有另一种方法可以在不使用 CSS 样式手动执行此操作的情况下重新定位弹出框?

WORKING DEMO

工作演示

采纳答案by jme11

No, there isn't a recalculate and there's really no easy way to do it. That said, you can dynamically inject the popovers this way:

不,没有重新计算,而且真的没有简单的方法可以做到。也就是说,您可以通过这种方式动态注入弹出框:

$('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');
});

Just replace all of your js in your fiddle with the above and check it out...

只需将小提琴中的所有 js 替换为上述内容并检查一下...

回答by AlexCheuk

Using Bootstrap v3.3.7:

使用 Bootstrap v3.3.7:

You can extend the Popover constructor to add support for a re-positioning function. You can place this script below where you load bootstrap.

您可以扩展 Popover 构造函数以添加对重新定位功能的支持。您可以将此脚本放在加载引导程序的下方。

JSFiddle Demo

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>

Then in your script whenever you need to reposition your tooltip after inserting content. You can just call:

然后在您的脚本中,只要您需要在插入内容后重新定位工具提示。你可以打电话:

$element.popover('reposition')

回答by DigitalMC

I just called

我刚打电话

button.popover('show');

button.popover('show');

And it re-positioned it.

它重新定位了它。

回答by Tim

I had a similar situation where I had a popover which already contained some HTML (a loading spinner) and I was changing the content when an ajax call returned. In my ajax callback function, this was the code I used to change the positioning so it remained centred:

我有一个类似的情况,我有一个已经包含一些 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) });

回答by muchacho

I used this code to adjust the height off the popover when it's already loaded to the page:

当它已经加载到页面时,我使用此代码来调整弹出窗口的高度:

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

Variable sender is the target where the popover is centred from.

变量 sender 是 popover 居中的目标。

回答by Maria Blair

this is inspired by @AlexCheuk answer above, but I needed a solution using Bootstrap 2. Also, in my project I didn't need to change popovers' placement, so I cut that out.

这受到上面@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);
    };
});

To call it:

调用它:

$element.popover('reposition')

回答by Alex

If the popover's position is "top" (as in the question), you can just adjust its absolute positioning from the top of the page.

如果弹出框的位置是“顶部”(如问题所示),您只需从页面顶部调整其绝对位置即可。

I've created a function to work out the height of the popover, and then shift it up on the page by its height.

我创建了一个函数来计算弹出框的高度,然后将其在页面上的高度向上移动。

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

and use with an ajax request to get data:

并与 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);
})

回答by Jake Graff

window.dispatchEvent(new Event('resize'));

This works for me.

这对我有用。

回答by Alex S

I took the concept of jme11's answer and updated for Bootstrap 3.3.2+

我采用了 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();
    }
  })
;

There's a method called setContent on the popover object, but for some reason it wasn't working for me. If you'd like to try, it would look like this:

popover 对象上有一个名为 setContent 的方法,但由于某种原因它对我不起作用。如果你想尝试,它看起来像这样:

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

回答by XaviQV

After a Popover content update, if you scroll up or down on page content, Popover does an auto-positioning and is readable again, so a simpler workaround to re-position the Popover after dynamic content update is to scroll down and up for 1 pixel on the page via pure javascript:

在 Popover 内容更新后,如果您在页面内容上向上或向下滚动,Popover 会进行自动定位并再次可读,因此在动态内容更新后重新定位 Popover 的更简单的解决方法是向下和向上滚动 1 个像素在页面上通过纯 javascript

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

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