I'm trying to create a website navigation with moving images. However, I seem to have a bit problems with it as it bugs out sometimes.

This is my code:

<script type="text/javascript"></script>
                        var goDownH = 300;
			var goUpH = 320;
			
			function goDown(id) {
					if(goDownH < 320) {
						goDownH = goDownH + 1;
						
						document.getElementById(id).style.marginTop = goDownH + "px";
						setTimeout("goDown('"+id+"');", 10);
					}
					else {
						goDownH = 300;
					}
			}
			
			
			function goUp(id) {
					if(goUpH > 300) {
						goUpH = goUpH - 1;
						
						document.getElementById(id).style.marginTop = goUpH + "px";
						setTimeout("goUp('"+id+"');", 10);
					}
					else {
						goUpH = 320;
					}
			}
		</script>
<div id="divNav1" style="position: absolute; margin: 300px 0px 0px 400px;">
			<img src="nav.png" alt="nav" onMouseOver="javascript:goDown('divNav1')" onMouseOut="javascript:goUp('divNav1')">
		</div>
		<div id="divNav2" style="position: absolute; margin: 300px 0px 0px 520px;">
			<img src="nav.png" alt="nav" onMouseOver="javascript:goDown('divNav2')" onMouseOut="javascript:goUp('divNav2')">
		</div>

The code above becomes a problem when I'm moving like crazy with the mouse. Sometimes some DIVs get stuck or they start going up and down really fast.
I don't understand what the problem is so I can't start fixing it.

Brecht

Dani AI

Generated

Short diagnosis and a safe fix.

The behavior you describe is exactly what happens when multiple elements share the same animation state and timers. In ’s snippet the single globals goDownH/goUpH and the repeated setTimeout loops are used for every DIV, so two hover animations will fight each other. Also using mouseover/mouseout on the image while you move that element under the pointer often triggers extra enter/leave events and produces the fast flicker or “stuck” state.

If you only need a hover shift, the simplest, most robust solution is CSS transitions on transform (no timers, no JS race conditions, GPU-accelerated):

<style>
.nav {
  position: absolute;
  top: 300px;
  left: 400px;
  transition: transform 180ms ease;
  will-change: transform;
}
.nav:hover { transform: translateY(20px); }
</style>

<div class="nav"><img src="nav.png" alt="nav"></div>

If you need JS control (custom easing, different targets), avoid globals and setTimeout strings. Use requestAnimationFrame, store the animation id on the element and cancel it before starting a new animation, and use mouseenter/mouseleave to prevent bubbling-related retriggers. Example pattern:

function animateTop(el, to, duration) {
  cancelAnimationFrame(el._raf || 0);
  var start = parseFloat(getComputedStyle(el).top) || 0;
  var startTime = null;
  function step(ts) {
    if (!startTime) startTime = ts;
    var t = Math.min(1, (ts - startTime) / duration);
    el.style.top = (start + (to - start) * t) + 'px';
    if (t < 1) el._raf = requestAnimationFrame(step); else el._raf = null;
  }
  el._raf = requestAnimationFrame(step);
}

Notes: is right that animation libraries give helpers for easing and queuing, but for simple hover shifts CSS is lighter and more reliable. Checklist: animate transform where possible, use per-element timers/state, cancel prior animations, prefer mouseenter/mouseleave, and attach listeners with addEventListener rather than inline attributes.

Use YUI Animation Lib:

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.