[JavaScript] setInterval() problem

0

Witam,
Mam problem z pewnymi funkcjami odpalanymi poprzez setInterval(). Mam dwie funkcje do obsługi "meniu". Polegają one na tym, że jedna <ort>przesówa </ort><div'a> w prawo (left++) ujawniając kilka obrazków "menu", a druga chowa obrazki i z powrotem horyzontalnie (left--) <ort>przesówa </ort><div'a> na swoje miejsce. Obecnie działa to jedynie RAZ, później zaczyna się trząść i nici z ładnego ort!. Może to wina 'czyszczenia interwału'?

Ten kod wcześniej napisałem w innej postaci. W funkcjach menu_in() i menu_out() po prostu bez instrukcji warunkowej po której następuje "czyszczenie" i działało w miarę dobrze, jedyną wadą było to że w żaden sposób nie potrafiłem skontrolować zmiennej inkrementowanej "s" (szczegóły poniżej w kodzie) co przyczyniało się do tego, że w momencie uruchomienia funkcji gdzieś w tle leciała pewnie ona w nieskończoność.

Proszę o pomoc. Dzięki wielkie z góry.

 var s = 45;
 var c = 220;
 var predkosc = 10;
 
 var fade_s = 0;
 var fade = 0.1;
 
 var pokaz;
 var ukryj;
 
function menu_in()
{
if (s > 220) { clearInterval(ukryj); }
 pokaz = setInterval("menu_fade_in()", 25);
}

function menu_out()
{
if (s != 45)  { clearInterval(pokaz); }
 ukryj = setInterval("menu_fade_out()", 25);
}


function menu_fade_in()
{
  if (s < c)
 {
  s = s + predkosc;
  document.getElementById("pasek").style.left = s + "px";
}
 if (s > c)
 {
  fade_s = fade_s + fade;
   document.getElementById("o1").style.opacity = fade_s;
   document.getElementById("o2").style.opacity = fade_s;
   document.getElementById("o3").style.opacity = fade_s;
   document.getElementById("o4").style.opacity = fade_s;
   document.getElementById("o5").style.opacity = fade_s;
 }
}



function menu_fade_out()
{
 if (s != 45)
 {
  s = s - predkosc;
  document.getElementById("pasek").style.left = s + "px";
  document.getElementById("menu1").style.width = 200 + "px";
 }

 if (s > 45)
 {
  fade_s = fade_s - fade;
  
   document.getElementById("o1").style.opacity = fade_s;
   document.getElementById("o2").style.opacity = fade_s;
   document.getElementById("o3").style.opacity = fade_s;
   document.getElementById("o4").style.opacity = fade_s;
   document.getElementById("o5").style.opacity = fade_s;
 }
}

0

Witam.
Spojrzałem na Twój kod i parę rzeczy mi się nie podobało, np. czemu resetujesz timery tylko na końcu animacji? Albo ten kawałek:

document.getElementById("menu1").style.width = 200 + "px";

...nie wiem do czego to miało służyć, domyślam się, że Ci się gdzieś menu rozjeżdżało podczas animacji. Także to, że wywołujesz getElementById bym zmienił, bardzo cierpi na tym szybkość działania skryptu. Kolejna sprawa - styl opacity jest dziedziczony, więc jak masz różne listy 'ol' to lepiej będzie jak dasz opacity na kontener w którym się znajdują, i będziesz miał taki sam efekt jakbyś nadał go każdemu dziecku osobno (no chyba że nie chcesz nadawać wszyskim dzieciom, wtedy zignoruj ten komentarz). Ja bym to zrobił tak, mam nadzieję, że pomoże:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
		<title>Input visual test</title>
		<style type="text/css">
			body {
				height: 200px;
			}
			#container {
				background-color: green;
				height: 100%;
				width: 100%;
			}
			#cover {
				position: relative;
				width: 200px;
                height: 100%;
                background-color: red;
				z-index: 2;
            }
			#menu {
				list-style-type: none;
				width: 200px;
				position: relative;
				float: left;
				height: 100%;
				background-color: blue;
				z-index: 1;
				margin: 0;
				padding: 0;
			}
		</style>
	</head>
	<body>
		<div id="container">
			<ol id="menu">
                    <li class="item">Item1</li>
                    <li class="item">Item2</li>
                    <li class="item">Item3</li>
            </ol>
			<div id="cover"></div>
		</div>
		<script>
		 var s = 45;
		 var c = 200;
		 var predkosc = 10;

		 var fade_s = 0;
		 var fade = 0.1;

		 var pokaz;
		 var ukryj;
		 var menu = document.getElementById("menu");

		function menu_in() {
			if(ukryj) {
				clearInterval(ukryj);
			}
			pokaz = setInterval("menu_fade_in()", 25);
		}

		function menu_out() {
			if(pokaz) {
				clearInterval(pokaz);
			}
			ukryj = setInterval("menu_fade_out()", 25);
		}

		function menu_fade_in() {
			if (s < c) {
				s = (s + predkosc) <= 200 ? s+predkosc : 200;
				menu.style.left = s + "px";
				fade_s = (fade_s + fade) <= 1 ? fade_s+fade: 1;
                menu.style.opacity = fade_s;
			}
			if (s > c) {

			}
		}

		function menu_fade_out() {
			if (s !== 0) {
				s = (s - predkosc) >= 0 ? s-predkosc : 0;
				menu.style.left = s + "px";
				fade_s = (fade_s - fade) >= 0 ? fade_s-fade : 0;
                menu.style.opacity = fade_s;
			}
		}

		var menuVisible = false;
		document.getElementById('cover').addEventListener("click", function() {
            if(menuVisible) {
                menu_out();
				menuVisible = false;
			} else {
                menu_in();
				menuVisible = true;
			}
		}, false);
		</script>
	</body>
</html>
0

Dzięki za odpowiedź zaraz zajmę się implementacją Twojej propozycji. Na pierwszy rzut oka wygląda sensowniej w każdym razie.

Co do tego nieszczęsnego ...width = 200, to to była pomyłka, napisałem to na samym początku jak miałem problemy, ale już to wywaliłem dawno, ale dzięki za zwrócenie uwagi ;)

Co do ilości pobierania elementów po ID to oczywiście się zgodzę, aczkolwiek również chciałbym dodać powiedzmy opcja1.style.opacity = fade + 0.5; o2.opac = fade + 0.4 itd itd aby uzyskać efekt 'schodkowy' pokazywania poszczególnych elementów menu, dlatego jest przedstawiony jako 5 pobieranych ID.

Jeszcze jedno pytanko mam co do całego kodu. W między czasie ukazywania menu dodaje do elementu

poza event'em onMouseOver i Out event onMouseDown. Zauważyłem, że takie łączenie eventów troche się ze sobą gryzie. Pewnie to wynika z tego, że event MouseOver oraz przypisana doń funkcja jest cały czas aktywna. Czy w związku z tym jest możliwość zatrzymania ów funkcji (bo eventa raczej nie bo się później nie zorientuje, że w pewnym momencie ma wykonać onMouseOut) by nie naruszyć ideii tych działań :) ?</p>
0

Aha sorki, nie zauważyłem w dalszej części kodu, że jest dodany eventListener, co by chyba odpowiadało na moje pytanie. Pierwszy raz to widzę, więc proszę o rozwagę.
[soczek]

0

Apropos event listenerów, czy jesteś pewien że potrzebujesz ich na mouseover i mouseout? Zgaduję, że chcesz zmienić wygląd elementu menu po najechaniu myszką - jeśli tak to zapoznaj się z pseudo klasą :active - znacznie ułatwi Ci to życie. No chyba, że potrzebne Ci są one do czego innego, wtedy zignoruj ten komentarz ;-) Pozdr.

EDIT: ups, oczywiście chodziło mi o pseudo klasę :hover :-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1