基于窗口边缘的popup窗口的X位置来更改Bootstrappopup窗口的位置?

我已经搜遍了互联网,而我发现这个stackoverflowpost洞察力是否有可能根据屏幕宽度来改变Bootstrappopup窗口的位置? ,它仍然没有回答我的问题,可能是由于我的理解位置/抵消。

这是我想要做的。 我想Twitter的Bootstap Popover的位置是正确的,除非热点popover将被放置在视口之外,那么我希望它被定位在左边。 我正在制作一个具有热点的iPadnetworking应用程序,当您在热点上按下时,会出现信息,但是当水平滚动被locking时,我不希望它出现在视口之外。

我想这会是这样的:

$('.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函数 ,每次点击一个可以popup的链接时都会进行计算。

这使得在没有初始$ .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“时,它会dynamic地调整popover的方向,例如,如果placement为”auto left“,则工具提示会显示在左边,否则它会显示正确的。“

我试图做同样的事情,然后意识到这个function已经存在。

对于Bootstrap 3,有

 placement: 'auto right' 

这更容易。 默认情况下,它是正确的,但是如果元素位于屏幕的右侧,popup窗口将被保留。 所以它应该是:

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

所以我想出了一个有效的方法。 对于我的特定项目,我正在构build一个iPad网站,以便我确切知道像素X / Y值到达屏幕边缘的程度。 你的thisX和thisY值会有所不同。

由于无论如何都是通过内联样式来设置popup,所以我只需抓住每个链接的左侧和顶部值来决定popup窗口的方向。 这是通过添加.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 }); } 

任何意见/改进都是值得欢迎的,但如果您愿意手动input值,则可以完成工作。

bchhun的回答让我走上了正确的轨道,但我想检查源和视口边缘之间的实际可用空间。 如果没有足够的空间,我也希望尊重数据放置属性作为一个偏好,并有适当的回退。 例如,除非没有足够的空间来显示popup窗口,否则这种“正确”的方式总是正确的。 这是我处理它的方式。 它适合我,但感觉有点麻烦。 如果有人有一个更清洁,更简洁的解决scheme的任何想法,我有兴趣看到它。

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

您可以使用自动放置数据,如data-placement =“auto left”。 它会自动根据你的屏幕尺寸进行调整,并保留默认的位置。

除了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的位置放到最好的位置。

你也可以尝试这一个,如果你需要在几乎所有的地方在页面中。

你可以用一般的方法configuration它,然后使用它。

这样你也可以使用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>