如何约束工具提示/弹出式DIV的大小,以便它不会触发页面上的滚动条

时间:2008-10-17 04:24:17

标签: javascript html css dom

鼠标悬停在元素上并显示提示。尖端溢出页面,触发滚动条,这会更改布局,以便触发尖端的底层元素不再位于鼠标指针下方,因此尖端消失。

提示消失,滚动条消失,现在鼠标再次位于元素上。

洗涤,冲洗,重复。

如果我能确保提示不是太大以至于触发滚动条,那就可以解决我的问题。

编辑:阅读评论后,有些事情需要澄清: div包含可以变化的文本。如果可以,我想展示所有文字。 div的位置需要靠近鼠标尖端的元素。所以关键是,我需要知道是否截断文本。

我找到了这个链接:
http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
其中包含了这个拼图,确定了浏览器窗口的大小:

function alertSize() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  window.alert( 'Width = ' + myWidth );
  window.alert( 'Height = ' + myHeight );
}

9 个答案:

答案 0 :(得分:1)

编辑:在回复评论时,听起来您正在尝试显示工具提示,而不会影响现有元素的定位(从而导致主窗口上的滚动条)。

如果是这种情况,您希望将工具提示的位置定义为绝对位置,因为这会将其从元素流中移除(因此当它出现时不会将页面的其余部分向下推)。

例如,您可以将其隐藏起来:

#tooltip {
  position: absolute;
  height: 100px;
  width: 200px;
  border: 1px solid #444444;
  background-color: #EEEEEE;
  display: none;
}

然后,在您的鼠标悬停事件(或其他任何事件)上,将#tooltip的topleft css设置为您想要的位置,并将显示切换为{{1 }}。因为它绝对定位,所以不会引起闪烁。

答案 1 :(得分:1)

CSS:指定工具提示的widthheight,为其添加overflow: hiddenoverflow: scroll

position: absolute也可以,但当然,您必须指定工具提示的topleft位置。

答案 2 :(得分:1)

你可以使用位于0,0的隐藏DIV,宽度和高度设置为100%作为衡量屏幕客户区域的“尺度”

如果您知道工具提示窗口的大小,可以将其剪辑到客户端窗口,或者更改显示位置以将其移动以使其保持在边界内

下面的一些代码(未经测试,从另一个项目中删除并重命名为内联)

var toolTipDiv; //this is your tooltip div element
//call AdjustToolTipPosition(window.event);
function AdjustToolTipPosition(e)
{
    var cpos = getPosition(e);
    mouseX = cpos.x;
    mouseY = cpos.y;

    //Depending on IE/Firefox, find out what 
    //object to use to find mouse position

    toolTipDiv.style.visibility = "visible";

    //backdrop 'yardstick' for client area measurement
    var backdropDiv = document.getElementById("divBackdrop");

    //make sure floating box doesn't leave the screen
    //we know box is 200x200 plus margins, say 215x215
    if ((cpos.y + 215) > backdropDiv.offsetHeight)
    {
        cpos.y = backdropDiv.offsetHeight - 215;
    }
    if ((cpos.x + 215) > backdropDiv.offsetWidth)
    {
        cpos.x = backdropDiv.offsetWidth - 215;
    }
    toolTipDiv.style.left = cpos.x + "px";
    toolTipDiv.style.top = cpos.y + "px";
}
//this function courtesy of 
//http://hartshorne.ca/2006/01/23/javascript_cursor_position/
function getPosition(e) 
{
    e = e || window.event;
    var cursor = {x:0, y:0};
    if (e.pageX || e.pageY) 
    {
        cursor.x = e.pageX;
        cursor.y = e.pageY;
    }
    else 
    {
        var de = document.documentElement;
        var b = document.body;
        cursor.x = e.clientX + 
            (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
        cursor.y = e.clientY + 
            (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
    }
    return cursor;
}

答案 3 :(得分:1)

以下是我最终使用的代码,它似乎正在运行。

function display_popup(s)
{ 

    var popup = document.getElementById("popup");
    popup.innerHTML = s

    //viewport_height = $(document).height()  doesn't work
    viewport_height = get_viewport_size()[1] // does this factor in scrollbar?

    mytop = $(current_element).offset().top + $(current_element).height() + 4
    scroll_offset_y = $(document).scrollTop()
    y_in_viewport = mytop - scroll_offset_y

    if (y_in_viewport < viewport_height) // are we even visible?
    {
        // Display the popup, but truncate it if it overflows   
        // to prevent scrollbar, which shifts element under mouse
        // which leads to flicker...

        popup.style.height= ""
        popup.style.display = "block";

        if (y_in_viewport + popup.offsetHeight > viewport_height)
        {
            overflow = (y_in_viewport + popup.offsetHeight) - viewport_height

            newh = popup.offsetHeight -  overflow
            newh -= 10 // not sure why i need the margin..

            if (newh > 0)
            {
                popup.style.height = newh 
            }
            else
            {
                popup.style.display = "none";
            }
        }
        popup.style.left = $(current_element).offset().left + 40
        popup.style.top = mytop
    }
}


function get_viewport_size()
{
  var myWidth = 0, myHeight = 0;

  if( typeof( window.innerWidth ) == 'number' )
  {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  }
  else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
  {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  }
  else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
  {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }

  return [myWidth, myHeight];
}

答案 4 :(得分:0)

在我看来,您需要的是客户端浏览器窗口中的光标位置。然后,您可以进行计算以放置工具提示,使其不会越过边界。

我在网上发现的是一篇在不同浏览器中讨论此内容的简短文章:Mouse Cursor Position。也许这可以帮助您解决问题?

有关浏览器尺寸的更多信息可以在here找到。

希望它有所帮助。

答案 5 :(得分:0)

可以设置与整页/视口大小完全相同的幽灵透明DIV。然后你可以在其中“粘贴”工具提示DIV,提供CSS float:right属性。这样可以为最终的工具提示渲染提供正确的顶部/左侧工具提示的角点测量。

编辑:这应仅针对“边缘情况”进行。

答案 6 :(得分:0)

您可以尝试确定指针的位置,如果它位于视口的右1/4(或您确定的任何区域),请将工具提示放在指针的左侧,否则将其放在右侧

您提到文字可能会有所不同,但它是否可能会变得非常大?它本身可以占用整个屏幕吗?最有可能的是,它有一个最大尺寸,因此在决定使用什么阈值来决定尖端应该在右边还是左边时要考虑到这一点。

然后,绝对定位您的提示div,为了安全起见,请为其指定max-heightmax-width属性。如果文本确实比这大,那么在CSS中给它overflow: scroll

答案 7 :(得分:0)

今年早些时候我遇到了同样的问题。我修复它的方式:

  1. 我假设垂直滚动正常,但水平滚动不是。 (总是有足够的空间,以便垂直滚动条不影响我的布局)
  2. 我修复了工具提示相对于目标的相对垂直位置。 (工具提示的顶部总是比锚的底部低5px)
  3. 工具提示的左侧是根据屏幕大小设置的。如果整个工具提示可以放在一条线上,那么很酷。否则,我约束了最大宽度并使其换行。
  4. 帮助我实现这一点的一件事是Quirksmode的Find Position文章。

    我的解决方案可能并不完全符合您的要求,但至少要看看Quirksmode链接,它的优点。

    希望有所帮助!

答案 8 :(得分:0)

更好的想法可能是将工具提示放在元素的左侧或右侧,具体取决于页面的哪一侧更近。我将工具提示的宽度固定,用内容填充并在需要时使其可见,然后根据鼠标位置定位。这是启用工具提示时onmousemove事件处理程序的关键部分:

if (!e) var e = window.event;
if(e) {
    var posx = 0;
    var posy = 0;

    if (e.pageX || e.pageY) {
        posx = e.pageX;
        posy = e.pageY;
    }
    else if (e.clientX || e.clientY) {
        posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
    }

    var overflowX = (document.body.clientWidth + document.body.scrollLeft + document.documentElement.scrollLeft) - (posx + 25+ tooltip.clientWidth);
    if(overflowX < 0) posx -= 25+ (tooltip.clientWidth);

    var overflowY = (document.body.clientHeight + document.body.scrollTop + document.documentElement.scrollTop) - (posy + 15+ tooltip.clientHeight);
    if(overflowY < 0) posy += overflowY;

    tooltip.style.left=(10+posx);
    tooltip.style.top=(10+posy);
}