14

我一直在做一个项目,我注意到引导程序的行为存在一些我想解决的不一致。

当弹出框(或工具提示,无论如何,它们基本上相同)接近屏幕边缘时 - 如果它是右侧的,当接近边缘时 - 它会收缩以免离开屏幕(它只适用在一定程度上,但这通常就足够了)。

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

IE:

正确的位置:

正常宽度:

在此处输入图像描述

接近边缘:

在此处输入图像描述

左侧位置:

正常宽度:

在此处输入图像描述

接近边缘:

在此处输入图像描述

这些图像来自我为说明问题而编写的一个小型DEMO 。

我已经搞砸了源代码,到目前为止无济于事。我似乎无法确定到底是什么导致了这种行为。

有任何想法吗?

ps

我正在使用引导程序 3.1.1。新的 3.2 并没有解决这个问题(我现在想避免升级)。


重大更新!

经过一番挖掘,我发现这与引导程序无关 - 它是简单的 css - 似乎当你绝对定位一个元素并将其推到两侧时,它会尝试留在屏幕上。

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

碰巧的是,弹出框仅与left分配一起定位——这就是为什么我们看到不一致的行为——当它被推到右边时它会收缩而不是另一个方向。

所以解决方案是改为分配right- 听起来很简单?没那么多。我获取了源代码并对其进行了一些操作,添加了这些行(在 jsfiddle 中的第 250 行附近):

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

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

看起来很合理,对吧?如果向左的偏移量小于 0(即,它离开屏幕),则计算窗口宽度并从中删除左侧偏移量和弹出框 ( actualWidth) 本身的宽度,然后得到与右侧的距离。

然后,确保重置左偏移并应用正确的定位。但是......它只能工作 - 也就是说它只能在第二次工作。

亲自检查一下!悬停一次,它放错了位置,把鼠标拉到一边再试一次,它突然就定位正确了。我勒个去?

编辑

好的,这似乎出现了很多,所以我会说清楚:

我知道auto安置。我不想要它。我想控制弹出框的去向,让它自动决定不是问题的解决方案,它只是避免它

4

3 回答 3

1

好的,我已经接近了一点。

一旦你right在 css 中赋值,actualWidthandactualHeight就会改变,所以你需要更新这些变量。在您的 jsfiddle 中的第 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 });
    actualWidth  = $tip[0].offsetWidth;
    actualHeight = $tip[0].offsetHeight;
}

这在您第一次悬停时有效,但此后每次都将 设置top得太高,因此您无法阅读工具提示的顶部。

更新:设置值似乎right会弄乱applyPlacement函数中的定位。要解决此问题,请right在设置初始 actualWidth 和 actualHeight 之前清除该值(在第 225 行附近):

$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
于 2014-08-06T05:02:12.550 回答
0

我相信这与访问网页的浏览器/客户端有很大关系。例如,为了在正确的一侧显示提示(左侧或右侧不聚集或难以辨认),请使用 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;
于 2014-08-05T17:41:24.620 回答
-1

我想你基本上已经明白了,它对我来说很好。

只需添加最小宽度检测,使其不会太小。

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');    
}
于 2014-07-31T20:32:12.923 回答