Helo.

I have a TD element, with a SPAN element inside. I use td-s onmouseover and onmouseout events for a small animation.

My problem is, that, when I move the cursor over the SPAN element,
the onmouseout event for TD element is fired. I want to prevent this. With other words, I want onmouseout fired, just when the cursor is moved outside the td area.
See the code..

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>delay</title>
<script language="javascript">
function over(e,id) {
document.getElementById(id).style.backgroundColor = "#333333";
alert('over: '+id);
}

function out(e,id) {
document.getElementById(id).style.backgroundColor = "#cccccc";
alert('out: '+id);
}
</script>
</head>

<body>
<table width="950" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#CCCCCC" id="td1" onmouseover="over();" onmouseout="out();">
<span>Google</span>
</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
</tr>
</table>
</body>
</html>

Dani AI

Generated

This is expected behavior: mouseover/mouseout fire whenever the pointer moves between two elements, so moving from the TD into its child SPAN can look like "leaving" the TD. was right to point out that alert()s make testing worse (they block the UI and change timing), and already passed the event into the handlers — that event is what you need to decide whether the pointer actually left the TD or just entered a child.

Two simple, reliable approaches:

Use non-bubbling events mouseenter / mouseleave (modern and straightforward):

var td = document.getElementById('td1');
td.addEventListener('mouseenter', function () { this.style.backgroundColor = '#333'; });
td.addEventListener('mouseleave', function () { this.style.backgroundColor = '#ccc'; });

Or keep mouseout but ignore transitions into descendants by checking relatedTarget (and fall back to toElement for old IE):

function contains(parent, node) {
  while (node) {
    if (node === parent) return true;
    node = node.parentNode;
  }
  return false;
}

function onTdMouseOut(e) {
  var to = e.relatedTarget || e.toElement;
  if (to && contains(this, to)) return; // still inside TD
  this.style.backgroundColor = '#ccc';
}
td.addEventListener('mouseout', onTdMouseOut);

Quick tips: if you only need a static hover color, use CSS td:hover { background-color: #333; } and avoid JS. Remove alert() while debugging. Prefer programmatic event binding (not inline attributes) so you can reliably add fallbacks and avoid reattaching handlers if your animation manipulates the DOM.

Recommended Answers

All 3 Replies

>> I can't say this enough: PUT CODE IN CODE TAGS, THAT IS WHERE THEY ARE MADE FOR!

>> I tested out your code, and to prevent the delay, you need to remove the alerts.

>> Also, your problem is really vague, there is a td, which has a span element within it. When the td is hovered (including the span), the background colour changes. Explain clearly to us all what you want different?

~G

Of course that my main problem wasn't with this code.. I just tried to "reconstruct" the problem.
The alerts are put there, just to show the events.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>delay</title>
<script language="javascript">
function over(e,id) {
document.getElementById(id).style.backgroundColor = "#333333";
alert('over: '+id);
}

function out(e,id) {
document.getElementById(id).style.backgroundColor = "#cccccc";
alert('out: '+id);
}
</script>
</head>

<body>
<table width="950" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#CCCCCC" id="td1" onmouseover="over(event,this.id);" onmouseout="out(event,this.id);">
<span>Google</span>
</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
</tr>
</table>
</body>
</html>

I write my code again, because first time it wasn't correct.

So..when I move the mouse over the td: the mouseover is fired - it is ok.
But when I move the mouse over the SPAN, then the mouseout and after that automatically the mouseover (for the TD) is fired again. That's my problem..

I tested your code with the following version:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>delay</title>
<script language="javascript">
function over(id) {
document.getElementById(id).style.backgroundColor = "#333333";
}

function out(id) {
document.getElementById(id).style.backgroundColor = "#cccccc";
}
</script>
</head>

<body>
<table width="950" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#CCCCCC" id="td1" onmouseover="over(this.id);" onmouseout="out(this.id);">
<span>Google</span>
</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
<td bgcolor="#CCCCCC">&nbsp;</td>
</tr>
</table>
</body>
</html>

You should use it to check wether it works. This should work properly: when you hover the td, including the span, the td should remain the onmouseover color. If not:

Stop using old browsers and switch to (IE <- although your code works in this browser, dont use it) , FF, GC, Safari or Opera.

If you already have one of the above browsers: please update them to the latest version.

~G

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.