Reputation: 23133
The mouse hovers over an element and a tip appears. The tip overflows the page, triggering a scrollbar, which changes the layout just enough so that the underlying element that triggered the tip is no longer under the mouse pointer, so the tip goes away.
The tip goes away, so the scrollbar goes away, and now the mouse is again over the element.
Wash, rinse, repeat.
If I could make sure that tip isn't too big so as to trigger scrollbars, that would solve my problem.
EDIT: After reading comments, some things to clarify: The div contains text which can vary. If I can, I want to show all the text. The div's location needs to be near the element the mouse's tip is over. So the key is, I need to know whether to truncate the text.
I did find this link:
http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
which contains this piece of the puzzle, figuring out how big the browser window is:
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 );
}
Upvotes: 5
Views: 4952
Reputation: 23133
Here is the code that I ended up using, and it seems to be working.
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];
}
Upvotes: 1
Reputation: 11431
A better idea may be to place the tooltip to the left or to the right of the element depending on which side of the page is closer. I have width of my tooltip fixed, fill it with content and make it visible when needed, and then position it depending on mouse position. Here's the key part of onmousemove event handler when tooltip is enabled:
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);
}
Upvotes: 0
Reputation: 13386
I had this same problem earlier this year. The way I fixed it:
One thing that helped me implement it this was was Quirksmode's Find Position article.
My solution might not be exactly what you're looking for, but at least have a look at the Quirksmode link, its good.
Hope that helps!
Upvotes: 0
Reputation: 37643
You could try determining where the pointer is, and if it is in the right 1/4 (or whatever area you determine) of the viewport, put the tool tip on the left of the pointer, otherwise put it to the right.
You mentioned that the text can vary, but is it possible it will grow very large? Could it take up an entire screen itself? Most likely, there is a maximum size it will be, so take that into account when deciding what threshold to use to decide if the tip should be on the right or the left.
Then, absolutely position your tip div, and to be safe, give it a max-height
and max-width
attribute. If the text does grow larger than that, give it overflow: scroll
in the CSS.
Upvotes: 0
Reputation: 3253
It could be possible to setup a ghost transparent DIV exactly of you whole page/viewport size. Then you can 'stick' a tooltip DIV within it, providing CSS float:right attribute. That would give you correct top/left tooltip's corner measures for a final tooltip rendering.
Edit: this should be done only for the case of 'edge situations'.
Upvotes: 0
Reputation: 61233
you can use a hidden DIV positioned at 0,0 with width and height set to 100% as a 'yardstick' to measure the client area of the screen
if you know the size of your tooltip window, you can clip it to the client window, or change the display position to shift it so that it stays within the boundaries
some code below (untested, ripped from another project and renamed inline)
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;
}
Upvotes: 1
Reputation: 84513
edit: in response to the comments, it sounds like you're trying to have the tooltip appear, without affecting the positioning of existing elements (and thus causing the scrollbar on the main window).
if that's the case, you want to define your tooltip's position as absolute, as this will remove it from the flow of elements (so when it appears it won't push the rest of the page down).
for example, you could start it hidden:
#tooltip {
position: absolute;
height: 100px;
width: 200px;
border: 1px solid #444444;
background-color: #EEEEEE;
display: none;
}
then, on your mouseover event (or whatever it's called on), set the top
and left
css of the #tooltip to where ever you want it, and switch the display to block
. as it's positioned absolutely, it won't cause the flicker.
Upvotes: 1
Reputation: 87171
Seems to me that what you need is cursor position within the client browser window. Then you can do your calculations to place the tooltip so it doesn't cross the border.
What I found on the web is a short article discussing this in diffrent browsers: Mouse Cursor Position. Maybe this could help you fix your problem?
And some more info about browser size can be found here.
Hope it helps.
Upvotes: 0
Reputation: 10008
CSS : specify the tooltip's width
and height
, add overflow: hidden
or overflow: scroll
to it.
position: absolute
works fine too, but of course, then you'll have to specify the top
and left
position of the tooltip.
Upvotes: 1