Javascript 引导工具提示\popover-解决左侧放置不一致的问题

Javascript 引导工具提示\popover-解决左侧放置不一致的问题,javascript,jquery,css,twitter-bootstrap,twitter-bootstrap-tooltip,Javascript,Jquery,Css,Twitter Bootstrap,Twitter Bootstrap Tooltip,我一直在做一个项目,我注意到bootstrap行为中有一些不一致的地方,我想解决这个问题 当弹出框(或工具提示,无论什么,它们基本上是一样的)接近屏幕边缘时——如果是右侧的,当接近边缘时——它会收缩以避免脱离屏幕(它只在某一点上起作用,但通常就足够了) 当放置在左侧时,不会发生这种情况 i、 e: 正确的位置: 正常宽度: 靠近边缘: 左侧位置: 正常宽度: 靠近边缘: 这些图片来自我写的一个小例子来说明这个问题 我把源代码弄得乱七八糟,到目前为止都没有用。我似乎无法确定到底是什么导致了

我一直在做一个项目,我注意到bootstrap行为中有一些不一致的地方,我想解决这个问题

当弹出框(或工具提示,无论什么,它们基本上是一样的)接近屏幕边缘时——如果是右侧的,当接近边缘时——它会收缩以避免脱离屏幕(它只在某一点上起作用,但通常就足够了)

当放置在左侧时,不会发生这种情况

i、 e:

正确的位置:

正常宽度:

靠近边缘:

左侧位置:

正常宽度:

靠近边缘:

这些图片来自我写的一个小例子来说明这个问题

我把源代码弄得乱七八糟,到目前为止都没有用。我似乎无法确定到底是什么导致了这种行为

有什么想法吗

p.s.

我使用的是Bootstrap3.1.1。新的3.2并不能解决这个问题(我希望在这一点上避免升级)


主要更新

经过一番挖掘,我发现这与引导无关——这是一个简单的css——似乎当你完全定位一个元素并将其推到两侧时,它会尝试保持在屏幕上

我从来不知道这种行为,它会自动发生-但只发生在你按下的方向-即,从左侧按下的div在到达屏幕右边缘时会收缩,反之亦然

碰巧的是,Popover只使用
left
赋值来定位-这就是为什么我们看到不一致的行为-当它被推到右侧时,它会收缩,但不会收缩到另一个方向

因此,解决方案是将
赋值为right
——听起来简单吗? 没有那么多。我获取了源代码并对其进行了一些操作(在JSFIDLE的第250行附近):

if(placement==“left”和&offset.left<0){
var right=($(window.width()+10)-(offset.left+actualWidth);
offset.left=0;
$tip.抵销(抵销);
$tip.css({'right':right});
}
看起来很合理,对吧?如果向左偏移小于0(即,它偏离屏幕),则计算窗口宽度,并从中删除左偏移和popover(
actualWidth
)本身的宽度,然后获得与右侧的距离

然后,确保重置向左偏移并应用向右定位。但是它只起了一点点作用——也就是说它只在第二次起作用

看看!将鼠标悬停一次,如果鼠标放错了位置,请将鼠标拉到一边,然后再试一次,然后突然鼠标定位正确。怎么回事

编辑

好吧,这似乎出现了很多问题,所以我要说清楚:


我知道
auto
placement。我不想要它我想控制popover的位置,让它自动决定并不是问题的解决方案,它只是避免它

我想你基本上已经掌握了它,它对我来说很好

只需添加最小宽度检测,这样它就不会变得太小

if (/bottom|top/.test(placement)) {
  var delta = 0

  if (offset.left < 0) {
    delta       = offset.left * -2
    offset.left = 0

    $tip.offset(offset)

    actualWidth  = $tip[0].offsetWidth
    actualHeight = $tip[0].offsetHeight
  } 

  this.replaceArrow(delta - width + actualWidth, actualWidth, 'left');

} else {
    if (placement == 'left' && offset.left < 0) {
        var right = (  $(window).width() + 10) - ( offset.left + actualWidth ); 

        offset.left = 0;
        $tip.offset(offset);
        $tip.css({ 'right': right });
    }

    this.replaceArrow(actualHeight - height, actualHeight, 'top');    
}
if(/bottom | top/.test(放置)){
var delta=0
如果(偏移量左<0){
增量=偏移量。左*-2
offset.left=0
$tip.抵销(抵销)
实际宽度=$tip[0]。偏移宽度
实际高度=$tip[0]。视线外
} 
这个.replaceArrow(delta-width+actualWidth,actualWidth,'left');
}否则{
if(placement='left'&&offset.left<0){
var right=($(window.width()+10)-(offset.left+actualWidth);
offset.left=0;
$tip.抵销(抵销);
$tip.css({'right':right});
}
此.replaceArrow(实际高度-高度,实际高度,“顶部”);
}

我相信这与访问网页的浏览器/客户端有很大关系。例如,为了在适当的一侧显示提示(不在左侧或右侧聚集或难以辨认),请使用javascript确定对象元素的offsetLeft&offsetTop,并相应地放置它。对于不同的分辨率,可以有不同的页面

屏幕宽度为400-720像素的CSS示例:

@media screen and (min-width:400px) and (max-width:721px)
一些伪代码:

if (this.offsetLeft < 200)   //if there's not enough room to display the tip
tip.offsetLeft += 200;
if(this.offsetLeft<200)//如果没有足够的空间显示提示
tip.offsetLeft+=200;

好的,我已经靠近了一点

一旦在css中指定了
右侧
,则
实际宽度
实际高度
将发生变化,因此需要更新这些变量。在JSFIDLE的第253行附近:

if (placement == 'left' && offset.left < 0) {
    var right = ( $(window).width() + 10 ) - ( offset.left + actualWidth ); 

    offset.left = 0;
    $tip.offset(offset);
    $tip.css({ 'right': right });
}
if (placement == 'left' && offset.left < 0) {
    var right = (  $(window).width() + 10) - ( offset.left + actualWidth ); 

    offset.left = 0;
    $tip.offset(offset);
    $tip.css({ 'right': right });
    actualWidth  = $tip[0].offsetWidth;
    actualHeight = $tip[0].offsetHeight;
}

我已经添加了css标签。我开始怀疑它与引导无关,而是与左右css属性的默认行为有关……事实上——如果我将
right:…
放在popover上(你知道,不是通常的左边),它的工作方式就像左边的赋值一样——即,在边缘附近收缩。这到底是什么现象?你试过设置左右偏移吗?@PabloKarlsson没有,但为什么会有帮助?整个过程都是围绕着只从一个方向计算事物而构建的。如果我想添加一个右偏移量,它还需要使一切都与之配合。这是不必要的,我只需要从一个方向来计算,真的。只是在某些情况下,我需要添加一个
right
的位置(参见我的第二个演示),是否不可能将right offset设置为none?这就是我编写的代码。它几乎起作用了。如果你仔细观察,你会发现它在第一次悬停时不起作用,但在第二次悬停时起作用。很难错过它,因为那里有很多图标,但是拿一个不是完全偏侧的(从左边拿第四个),你会看到它(仔细看箭头)。是的,它从第一个悬停变为第二个。我去拿
$tip.css({ 'right': '' });
// check to see if placing tip in new offset caused the tip to resize itself
var actualWidth  = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight