...

View Full Version : Onmouseout triggered by hovering over links?



skidvd
10-23-2003, 04:50 PM
Hello. I have a page containing a dynamically positioned DIV. The DIV is moved into position as part of an onmouseover event. The DIV is then subsequently re-positioned to a "docking area" as part of an onmouseout event.

This all seems to be working for the most part with one major exception. Provided that that the DIV does NOT contain any < href> type links or any <img> tags that function as links everything is OK; i.e. if the DIV has just plain text content everything is fine. As soon as I add any links to the DIV I run into the following problem: whenever the user moves the mouse WITHIN the DIV and then over any of the contained links, the onmouseout event is triggerred - causing the DIV to be re-positioned to it's "docking area". This is NOT desirable as I want the user to be able to mouse into the DIV, interact with the DIVs contents (including normally functional links, etc.) til their hearts content, and then mouseout - returning the DIV to the "docking area".

Any thoughts, ideas or suggestions on how to prevent the links from triggering the onmouseout event or correcting the behavior will be greatly appreciated.

Kor
10-23-2003, 05:02 PM
can you give us a link to see?

skidvd
10-23-2003, 05:09 PM
Unfortunately, not immediately. The page is not yet on a public server since it's still in development. With some time (a day or so), I could get it staged - but our process takes some time.....

I'll work on making it available - Any ideas in the meantime?

Thanks again!

Willy Duitt
10-23-2003, 05:34 PM
Try adding a onMouseOver event handler to your images and links
which would once again call the function you called with the
original onMouseOver. It should cancel out the onMouseOut.
You may have to add a setTimeout to the onClick event handler
to give the additional onMouseOver time to fire.

It's much easier to offer assistance if we can see some codes.
If you don't have a page online, you can attach a text file.
Otherwise, we're shooting in the dark.

.....Willy

RoyW
10-23-2003, 07:10 PM
Put this code in a document then take a look at the output.


<body>
<script>
function db(txt)
{
document.getElementById('debug').innerHTML += txt + "<br>";
}
</script>

<div style="position:absolut;width:100;height:100;background-color:red"
onmouseover="db('OVER: div')" onmouseout="db('OUT : div')">
<br>
<p><a href="#" onmouseover="db('OVER: link 1')" onmouseout="db('OUT : link 1')" >Link 1</a></p>

<p><a href="#" onmouseover="db('OVER: link 2')" onmouseout="db('OUT : link 2')" >Link 2</a></p>

</div>

<div id="debug">
</div>
</body>


It creates a DIV (red square) with 2 links. As you move your mouse SLOWLY from the top of the DIV, over the links, out the bottom you get this result.
---------------------------
OVER: div

OUT : div
OVER: link 1
OVER: div

OUT : link 1
OUT : div
OVER: div

OUT : div
OVER: div

OUT : div
OVER: link 2
OVER: div

OUT : link 2
OUT : div
OVER: div

OUT : div
----------------------------------------
(I have split the output into how many event occur for each link - run the demo to see when the events occur)

As you can see you get a lot of events. This is something to do with event bubbling.

You could check the event to see if the event source is a DIV or not but this code would be different for IE and NS6+. (and it wouldn't work, notice the OUT div, OVER div in the middle of the output !)

One solution is :-
onmouseout, start a timer that will dock the div after a short time.
onmouseover if the timer is running cancel the timer, else undock the div.

Another solution is :-
- give the DIV a state ("DOCKED", "UNDOCKING", "UNDOCKED", "DOCKING")
- Use the mouse over/out events to change the state
- use a timer to check the state and move the DIV.

This is the solution I used for this script
Left Sliding Div - demo (http://www.javascript-fx.com/interfaces/dangerous/demo.html) - demo3 (http://www.javascript-fx.com/development/leftslider/demo3.html)

skidvd
10-24-2003, 04:55 PM
Thanks RoyW

The timeout suggestion you mentioned appears to the right path. Initial indications are that it will work for both IE and Netscape as desired.

Thanks again!

skidvd
10-24-2003, 05:16 PM
Ok, perhaps I spoke too soon...

The page below (please excuse the ugliness - it's a proof of concept page), seems to produce the desired results in IE 5.5 and above and is really close in Netscape 7. However, the "dockable" SPAN does not appear to work in Netscape 6. In NS 6, the SPAN does not appear to be moving into and out of view as desired. In NS 7, it does move, but the onmouseout event does not seem to be detected until you go to the extreme rigth side of the page (well beyond the width of the SPAN).

Any suggestions or help will be appreciated.

Here is the test page.......

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<style type="text/css">
<!--
.bookmarks
{
background-color: #9999FF;
border: thin solid #000000;
overflow: auto;
position: absolute;
z-index: 100;
left: 0px;
top: 35px;
height: 90%;
visibility: visible;
cursor: hand;
display: block;
}
.main {
position: absolute;
left: 10px;
top: 10px;
height: 200%;
width: 95%;
}
-->
</style>
<script language="JavaScript" type="text/JavaScript">
var isNav, isIE;
var collection;
var styleObj;
var timeoutId;
var waitId;
if ( parseInt( navigator.appVersion >= 4 ))
{
if ( navigator.appName == "Netscape" )
{
isNav = true;
collection = "";
styleObj = "";
}
else
{
isIE = true;
collection = "all.";
styleObj = ".style";
}
}
function findDiv( did )
{
if ( document.getElementById )
theDiv = document.getElementById( did );
else if ( document.layers )
theDiv = document.layers[did];
else
theDiv = document.all[did];
return theDiv;
}
function getStyleRef( obj )
{
if ( document.getElementById || document.all )
return obj.style;
else
return obj;
}
function displayObj( obj, msg )
{
var tmp = msg + "\n";
for ( var prop in obj )
{
tmp += "name: " + prop + " value: " + obj[prop] + "\t";
}
alert( tmp );
}
function getObjLeft( obj )
{
if ( document.all )
return obj.pixelLeft;
else
{
if ( typeof( obj.left ) == "string" && obj.left.length > 0 )
return parseInt( obj.left );
else
return obj.left;
}
}
function getObjRight( obj )
{
if ( document.all )
return obj.pixelRight;
else
{
if ( typeof( obj.right ) == "string" && obj.right.length > 0 )
return parseInt( obj.right );
else
return obj.right;
}
}
function getObjWidth( obj )
{
if ( document.getElementById || document.all )
return obj.clientWidth;
else
return obj.clip.width;
/*
if ( isNav )
return obj.clip.width;
else
return obj.clientWidth
*/

}
function getTop()
{
if ( document.all )
{
if ( document.offsetTop )
{
alert( document.offsetTop );
return document.offsetTop;
}
else
return 0;
}
else
return window.pageXOffset;
}
function shiftTo( obj, x, y )
{
if ( document.all )
{
obj.pixelLeft = x;
obj.pixelTop = y;
}
else if ( document.layers )
obj.moveTo( x, y )
else
{
obj.left = x;
obj.top = y;
}
}
function showBookmarksMenu( event )
{
if ( ! event )
event = window.event; // IE event model

if ( waitId )
clearTimeout( waitId );

var mainObj = getStyleRef( findDiv( "main" ));
var obj = getStyleRef( findDiv( "bookmarks" ));
shiftTo( obj, 0, getTop() + 35 );
<!-- findDiv( "bookmarks" ).onmouseout = hideBookmarksMenu; -->
}
function hideBookmarksMenu( event )
{
if ( ! event )
{
event = window.event; // IE event model
}
if ( event )
{
/*
displayObj( event, "Event" );
alert( "Obj: " + findDiv( "bookmarks" ) + " target: " + event.target );
if ( event.eventPhase == Event.AT_TARGET )
event.preventDefault();
*/
}

var mainObj = getStyleRef( findDiv( "main" ));
var obj = getStyleRef( findDiv( "bookmarks" ));
<!-- findDiv( "bookmarks" ).onmouseout = null; -->
if ( getObjLeft( obj ) >
( getObjLeft( obj ) - getObjWidth( findDiv( "bookmarks"
) ) + 10 ) )
{
if ( (( getObjWidth( findDiv( "bookmarks" )) - 10 ) +
getObjLeft( obj ) ) > 5 )
{
shiftTo( obj, (getObjLeft( obj ) - 5), getTop() + 35 );
timeoutId = setTimeout( "hideBookmarksMenu()", 1 );
}
else
{
shiftTo( obj, 0 - getObjWidth( findDiv( "bookmarks" )
) + 10,
getTop() + 35 );
}
}
<!-- obj.visibility = 'visible'; -->
<!-- alert( "Moving to " + getObjLeft( obj ) - getObjWidth( findDiv( "bookmarks" ) ) + 10 + ", " + getTop() + 35 ); -->
/*
if ( getObjLeft( obj ) >
( getObjLeft( obj ) - getObjWidth( findDiv( "bookmarks"
) ) + 10 ) )
{
alert( "At " + getObjLeft( obj ) + " vs " +
( getObjLeft( obj ) - getObjWidth( findDiv(
"bookmarks" ) ) + 10 )
+ " " +
(getObjLeft( obj ) > ( getObjLeft( obj ) -
getObjWidth( findDiv( "bookmarks" ) ) + 10 )));
shiftTo( obj, getObjLeft( obj ) - getObjWidth( findDiv(
"bookmarks" ) ) + 10, getTop() + 35 );
<!-- --> alert( "At " + getObjLeft( obj )); <!-- -->
}
*/
}
function waitToHide()
{
waitId = setTimeout( "hideBookmarksMenu()", 125 );
}
function relocateTo( url )
{
findDiv( "content" ).src = url;
}
</script>
</head>

<body onload="javascript:hideBookmarksMenu();">
<!-- <body> -->
<span class="bookmarks" id="bookmarks"
onmouseover="javascript:showBookmarksMenu();"
onmouseout="javascript:waitToHide();">
The bookmarks list<br>

Item 1<br>
Item 2<br>
Item 3<br>
Item 4<br>
<!--
-->
<a href="javascript:relocateTo( 'http://www.blooberry.com'
);">Blooberry</a><br>

<a href="javascript:relocateTo( 'http://www.cnn.com'
);">CNN</a><br>
<a href="javascript:relocateTo( 'http://www.safeway.com'
);">Safeway</a><br>
<a href="javascript:relocateTo( 'http://www.icca.org'
);">ICCA</a><br>
<a href="javascript:relocateTo( 'http://www.disney.com'
);">Disney Schwab</a><br>
<a href="javascript:relocateTo( 'http://www.sprintpcs.com'
);">Sprint PCS</a><br>
A really, really, really long item goes here<br>

</span>
<div class="main" id="main">
<iframe src="http://www.blooberry.com" id="content"
name="content" class="main">
<!--
<a href="javascript:hideBookmarksMenu();">Hide</a>
<p>The Bookmarks page is as displayed</p>
<p>&nbsp; </p>
Some additional content goes here
<br>
Maybe even some additional stuff here.......-->
</iframe>
</div>
</body>
</html>

Frank
10-24-2003, 07:10 PM
You could try this, use javascript to open the links instead of href.

<div id="theonethatsmoving">

<div onClick="OpenLink1()" class="link">text</div>
<div onClick="OpenLink2()" class="link">>text</div>
<div onClick="OpenLink3()" class="link">>text</div>

</div>

you can use css to display the hand when the user mouses over the div link.

<style type="text/css">
.link {cursor:hand; cursor:pointer}
</style>
</head>



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum