Funktion in Funktion mit setTimeout

Just_Bob

Grünschnabel
Hallo zusammen,

ich möchte in einer Funktion ein setTimeout setzen. Wäre toll wenn mir jemand sagen würde warum das so nicht geht und wie das Ganze funktioniert. :)

HTML:
function ticker() {
	
	var z = 0;

	function scroll() {
		z++;
		alert(z*-1);
		stop = setTimeout("scroll()", 100);
		if(z == 10) clearTimeout(stop);
	}
	scroll();
}
 
Zuletzt bearbeitet:
Moin Bob,

das Problem ansich ist, dass scroll() nicht global bekannt ist, sondern nur innerhalb der Funktion. Funktionsaufrufe per setTimeout() erfolgen aber im globalen Kontext.

In diesem speziellen Fall kommt noch hinzu, dass es eine Methode des window-Objekts namens scroll() gibt...diese wird beim Aufruf per setTimeout() aufgerufen...allerding fehlen dem Aufruf dabei die 2 Pflichtargumente von scroll().
 
Hi,

ein Aufruf der Form
Code:
stop = window.setTimeout(function(){scroll();}, 100);
könnte das Problem eventuell dennoch lösen. Da die Gültigkeitskette und somit die Auflösung der Objekte (Variablen) von innen nach aussen verlaufen sollte, müsste eigentlich die passende Funktion aufgerufen werden. Denn in diesem Augenblick ist die scroll-Funktion aus dem lokalen Gültigkeitsbereichs der Funktion ticker (ähnlich den "Closure-Variablen").

Ciao
Quaese
 
Servus Sven,
Servus Quaese,

vielen Dank für die Infos. Hat mir wirklich geholfen. :) Die Variante von Quaese (lustiger Nick übrigens^^ das mein ich positiv, also nicht in falschen hals bekommen...) funktioniert super. Hier würde mich noch interessieren was mit dieser Möglichkeit eigentlich genau passiert.

So nachdem ich dann auch grundlegend Fertig war mit dem Script musste ich feststelle, dass meine Leerzeichen am Anfang und am Ende des Nachrichtentextes von dem Ticker verloren gehen. Ich find einfach nicht raus wo warum und wie ichs verhindern kann...

Was mir auch aufgefallen ist, der Text scrollt ansich doch recht langsam für 40 ms?

Hier mal der komplette Quelltext:

Code:
<html>
<head>
<title>
ticker
</title>

<script type="text/javascript">

function ticker() {
	var tb = document.getElementById("tb");
	var tb_scroll = document.getElementById("tb_scroll");
	var text = " Leerzeichen? ";
	var tbm = "<div id='tbm1' class='tbm'>"+text+"</div><div id='tbm2' class='tbm'>"+text+"</div>";
	var z = 0;
	var s = 0;
	
	tb_scroll.innerHTML = tbm;

	var tbm1 = document.getElementById("tbm1");
	var tbm2 = document.getElementById("tbm2");
	var pk = tbm2.offsetLeft-tbm1.offsetWidth;

	tb_scroll.style.width = tbm1.offsetWidth*2;
	
	var anzahl = Math.ceil(tb.offsetWidth/tbm1.offsetWidth)+1; //Anzahl wie oft die TBM in die TB passt ->  Aufrunden auf nächst höhere ganze Zahl
	
	if(anzahl > 2){
		tbm = new Array();
		for(z=1; anzahl >= z; z++) {
			tbm[z] = "<div id='tbm"+z+"' class='tbm'>" + "\r\n " +text+ "\r\n " + " </div>";
		}
		tb_scroll.style.width = tbm1.offsetWidth*anzahl+10;
		tb_scroll.innerHTML = tbm.join(" ");
	}
	

	tbm1 = document.getElementById("tbm1");
	tbm2 = document.getElementById("tbm2");
	pk = tbm2.offsetLeft-tbm1.offsetWidth;
	
	tb_scroll.onmouseover = wechsel;
	tb_scroll.onmouseout = wechsel;
	
	function wechsel() {
		if(s == 0) {
			s = 1;
		} else {
			s = 0;
			tbs(); 
		}
	}
	
	function tbs() {
		if(s == 0) {
			if(tb_scroll.offsetLeft-pk == tbm1.offsetWidth*-1 ) {
				tb_scroll.style.marginLeft = 0;
				z = 0;
			}
			
			z++;
			tb_scroll.style.marginLeft = z*-1;
			stop = window.setTimeout(function(){tbs();}, 40);
			if(z == tbm1.offsetWidth+1) clearTimeout(stop);
		}
	}
	tbs();
}



</script>

<style type="text/css">
	body { overflow:hidden; }
	#tb { border:1px solid black; white-space:nowrap; overflow:hidden; width:400px; }
	#tb_scroll { margin-left:0px;  font:bold 11px verdana; width:1px; cursor:default; }
	.tbm { float:left; background-color:gold; }

</style>
</head>
<body onload="ticker();">

	<div id="tb">
		<div id="tb_scroll">
		</div>
	</div>
	
</body>
</html>

Hoffe ihr Helft mir wieder weiter :)

Gruß Bob
 
Hi,

eventuell ist die Begründung des Verhaltens wie folgt:
Die anonyme Funktion läuft im Gegensatz zu einem String im Argument nicht im Kontext des window-Objekts, sondern im Gültigkeitsbereich der übergeordneten Funktion. Verfährt JS nun nach dem Prinzip der Auflösung von Variablen (und Objekten), so werden die Funktionsebenen aufsteigend vom Fundort zur Wurzel hin durchlaufen und nach einer Übereinstimmung gesucht. Diese wird in der Funktion tbs gefunden und zeitverzögert ausgeführt.

Sollte es an dieser Begründung etwas auszusetzen geben, lasse ich mich gerne eines Besseren belehren.

Einen interessanten Artikel zu Gültigkeitsbereichen und Closures findest du hier.

Zu den Leerzeichen:
Notier den String mit geschützten Leerzeichen.
Code:
var text = "&nbsp;Leerzeichen?&nbsp;";
Ciao
Quaese
 
Hey ho,

super die Infos haben mir weitergeholfen und der Link ist wirklich sehr interessant. Nun weiß ich auch das ich n Closure gebastelt habe^^

Auf das geschützte Leerzeichen hätte ich auch selbst kommen können :rolleyes: aber gut manchmal ist die Lösung einfach als man glaubt.

Nun läuft der Ticker...
Allerdings legt er auch ein verhalten an den Tag was ich nicht mal im ansatz verstehe! Wenn man mit der Maus drüber fährt und er stehen bleibt und man die maus leicht hin und her bewegt wird er schneller und wenn er so richtig fahrt macht läuft er sogar irgendwann rückwärts..... -_-;;; Ich habe es schon ausprobiert das ich das mausover auf den übergeortneten Div gelegt habe und dann auch auf den scroll Div, was beides nichts geändert hat. Hier der aktuelle Code

Code:
<html>
<head>
<title>
ticker
</title>

<script type="text/javascript">

function ticker() {
	var tb = document.getElementById("tb");
	var tb_scroll = document.getElementById("tb_scroll");
	var text = "12";
	var leer = "&nbsp;"
	var tbm = "<div id='tbm1' class='tbm'>"+text+"&nbsp;</div><div id='tbm2' class='tbm'>"+text+"&nbsp;</div>";
	var z = 0;
	var s = 0;
	
	tb_scroll.innerHTML = tbm;

	var tbm1 = document.getElementById("tbm1");
	var tbm2 = document.getElementById("tbm2");
	var pk = tbm2.offsetLeft-tbm1.offsetWidth;

	tb_scroll.style.width = tbm1.offsetWidth*2;
	
	var anzahl = Math.ceil(tb.offsetWidth/tbm1.offsetWidth)+1; //Anzahl wie oft die TBM in die TB passt ->  Aufrunden auf nächst höhere ganze Zahl
	
	if(anzahl > 2){
		tb_scroll.style.width = tbm1.offsetWidth*anzahl;	
		tbm = new Array();
		for(z=1; anzahl >= z; z++) {
			tbm[z-1] = "<div id='tbm"+z+"' class='tbm'>"+text+"&nbsp;</div>";
		}						
		tb_scroll.innerHTML = tbm.join(" ");
		z=0;
	}
	
	tb_scroll = document.getElementById("tb_scroll");
	tbm1 = document.getElementById("tbm1");
	tbm2 = document.getElementById("tbm2");
	pk = tbm2.offsetLeft-tbm1.offsetWidth;
	
	tb.onmouseover = wechsel;
	tb_scroll.onmouseout = wechsel;
	
	
	function wechsel() {
		if(s == 0) {
			s = 1;
		} else {
			s = 0;
			tbs(); 
		}
	}
	
	function tbs() {
		if(s == 0) {
			if(tb_scroll.offsetLeft-pk == tbm1.offsetWidth*-1 ) {
				tb_scroll.style.marginLeft = 0;
				z = 0;
			}	
			z++;
			tb_scroll.style.marginLeft = (z*1)*-1;
			stop = window.setTimeout(function(){tbs();}, 40);
			if(z == tbm1.offsetWidth+1) clearTimeout(stop);
		}
	}
	tbs();
}

</script>

<style type="text/css">
	body { overflow:hidden; }
	#tb { border:1px solid black; height:17px; white-space:nowrap;  width:400px; overflow:hidden; }
	#tb_scroll { margin-left:0px;  font:bold 11px verdana; width:1px; cursor:default; }
	.tbm { float:left; background-color:gold; height:17px; border:1px solid green; }

</style>
</head>
<body onload="ticker();">

	<div id="tb">
		<div id="tb_scroll">
		</div>
	</div>
	
</body>
</html>
 
Hi,

zunächst solltest du den mouseover-Event auch auf tb_scroll legen.
Code:
tb_scroll.onmouseover = wechsel;
tb_scroll.onmouseout = wechsel;
Als nächstes wird ein schon existierender Timeout zunächst beendet, falls der Cursor innerhalb des Laufbandes bewegt wird. Dazu ist es notwendig, der Variablen stop einen bekannten Zustand zuzuweisen, falls kein Timer gestartet ist (null).
Code:
function ticker() {
  // Bisherige Deklarationen
  var stop = null;

 // Weitere Anweisungen

  function tbs() {
    if(s == 0) {
      // Bei Bedarf laufenden Timer stoppen
      if(stop != null){
        clearTimeout(stop);
        stop = null;
      }
      if(tb_scroll.offsetLeft-pk == tbm1.offsetWidth*-1 ) {
        tb_scroll.style.marginLeft = 0;
        z = 0;
      }
      z++;
      tb_scroll.style.marginLeft = (z*1)*-1;
      stop = window.setTimeout(function(){tbs();}, 40);
      if(z == tbm1.offsetWidth+1) clearTimeout(stop);
    }
  }
  tbs();
}
Vielleicht hilft dir das weiter.

Ciao
Quaese
 
Servus,

ja das hat mir weiter geholfen. Was ich aber noch nicht ganz verstehe (bzw. überhaupt nicht...) warum die Variable stop einen bekannten Wert braucht?

Bob
 
achso :rolleyes: eigentlich logisch....

ich hab noch ne kurze frage und will nicht noch nen thread aufmachen

Code:
z = 0;
function test() {
	alert(this.src);
}

while(document.getElementsByName("Lupe")[z]) {
	document.getElementsByName("Lupe")[z].onmouseover = test;
	z++;
}

Hier wüsste ich auch nur gern warum das mit "this.src" funktioniert? Ich kann mir da in meinem Schrumpelhirn keine logische Verbindung vorstellen. Im allgemeinen tue ich mich schwer "this" gleich richtig zu verwenden... Vielleicht stoß ich auch grad an die grenzen meiner geistigen Kapazitäten und sollte aufhören zu versuchen in tiefere Regionen von js vorzudringen -_-

Gruß Bob
 

Neue Beiträge

Zurück