Klaus: Warum startet Transistion nicht?

Hallo,

über PHP erzeuge ich wie folgt ein Balken-Chart, der animiert werden soll.
Der Javascript-Teil ändert zwar die Weite des Div, aber die Transistion startet nicht.
Liege ich eventuell mit der Vermutung richtig, dass das Javascript bereits ausgeführt wird, bevor die Seite fertig geladen wurde und daher die Transition nicht startet, da dadurch quasi keine Änderung erkannt wird?
Wie könnte ich es ansonsten sinnvoller lösen?

  
						<div class="statbez"><?=$vorname;?> <?=$nachname;?></a>:</div>  
						<div class="stat_wrapper">  
							<div ID="STAT_<?=$pnr;?>" class="stat_black"></div>  
						</div>  
						<div class="statwerte"><?=$anz;?></div>  
						<script type="text/javascript" language="javascript">  
							document.getElementById("STAT_<?=$pnr;?>").style.width = '<?=$laenge;?>px';  
						</script>  

der CSS-Code sieht so aus:

  
.stat_wrapper {  
	width:300px;  
	height:20px;  
	float:left;  
	margin: 5px 5px;  
	border-radius:5px;  
	background: rgb(255,255,255);  
	background: -moz-linear-gradient(top,  rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%);  
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(229,229,229,1)));  
	background: -webkit-linear-gradient(top,  rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);  
	background: -o-linear-gradient(top,  rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);  
	background: -ms-linear-gradient(top,  rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);  
	background: linear-gradient(to bottom,  rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);  
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e5e5e5',GradientType=0 );  
}  
.stat_black {  
	height:20px;  
	width:0px;  
	background: rgb(91,89,89);  
	border-radius: 5px;  
	background: -moz-linear-gradient(top,  rgba(91,89,89,1) 0%, rgba(4,5,1,1) 50%, rgba(4,5,0,1) 51%, rgba(142,136,135,1) 100%);  
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(91,89,89,1)), color-stop(50%,rgba(4,5,1,1)), color-stop(51%,rgba(4,5,0,1)), color-stop(100%,rgba(142,136,135,1)));  
	background: -webkit-linear-gradient(top,  rgba(91,89,89,1) 0%,rgba(4,5,1,1) 50%,rgba(4,5,0,1) 51%,rgba(142,136,135,1) 100%);  
	background: -o-linear-gradient(top,  rgba(91,89,89,1) 0%,rgba(4,5,1,1) 50%,rgba(4,5,0,1) 51%,rgba(142,136,135,1) 100%);  
	background: -ms-linear-gradient(top,  rgba(91,89,89,1) 0%,rgba(4,5,1,1) 50%,rgba(4,5,0,1) 51%,rgba(142,136,135,1) 100%);  
	background: linear-gradient(to bottom,  rgba(91,89,89,1) 0%,rgba(4,5,1,1) 50%,rgba(4,5,0,1) 51%,rgba(142,136,135,1) 100%);  
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#5b5959', endColorstr='#8e8887',GradientType=0 );  
	transition: width 1.0s linear;  
	-moz-transition: width 1.0s linear; /* Firefox 4 */  
	-webkit-transition: width 1.0s linear; /* Safari and Chrome */  
	-o-transition: width 1.0s linear; /* Opera */  
}  
  
.statbez,.statwerte { float:left; margin: 5px; }  
.statbez { width: 120px; }  
.statwerte { width: 50px; }  

  1. Hallo,

    prinzipiell sollte das funktionieren, siehe bspw. http://jsfiddle.net/R4waX/

    Was an deinem Code konkret falsch ist, erkenne ich nicht. PHP-Code ist auch immer verwirrend, wenn es um konkretes HTML/CSS geht. Hast du vielleicht einmal ein reduziertes Online-Beispiel?

    Liege ich eventuell mit der Vermutung richtig, dass das Javascript bereits ausgeführt wird, bevor die Seite fertig geladen wurde und daher die Transition nicht startet, da dadurch quasi keine Änderung erkannt wird?

    So wie du das JavaScript platziert hast, wird es beim Parsen des HTMLs ausgeführt. Und zwar nachdem das betreffende Element geparst wurde. Es sollte also Zugriff auf das Element haben – sonst würdest du eine Fehlermeldung auf der Konsole sehen (getElementById würde null zurückgeben).

    Wichtig ist, dass das Stylesheet im <head>…</head> geladen wird. Der Download des Stylesheets blockt das Rendern. Also sollte der Browser durchaus eine Änderung durch das JavaScript bemerken (eben von 0 auf die gegebene Länge).

    Mathias

    1. Hallo Mathias,

      prinzipiell sollte das funktionieren, siehe bspw. http://jsfiddle.net/R4waX/

      auch bei mir funktioniert es im jsfiddle: http://jsfiddle.net/h75nd/

      Ich weiß aber nicht, inwiefern jsfiddle die einzelnen Teile ausführt und damit tatsächlich vergleichbar mit meinem Script ist.

      So wie du das JavaScript platziert hast, wird es beim Parsen des HTMLs ausgeführt. Und zwar nachdem das betreffende Element geparst wurde. Es sollte also Zugriff auf das Element haben – sonst würdest du eine Fehlermeldung auf der Konsole sehen (getElementById würde null zurückgeben).

      Zugriff auf das Element ist vorhanden. Wenn ich den JS-Teil weglasse, hat das erzeugte Div keine Breite und wird nicht angezeigt.

      Wichtig ist, dass das Stylesheet im <head>…</head> geladen wird. Der Download des Stylesheets blockt das Rendern. Also sollte der Browser durchaus eine Änderung durch das JavaScript bemerken (eben von 0 auf die gegebene Länge).

      Tja, das CSS wird im Head-Bereich geladen, die Änderung bekommt er aber offenbar dennoch nicht mit, also im eigentlichen Sinn der "Änderung", denn bis auf die Transistion wird alles korrekt angezeigt.

      Gruß,

      Klaus

  2. Hallo Klaus,

    <div ID="STAT_<?=$pnr;?>" class="stat_black"></div>

    <script type="text/javascript" language="javascript">
      document.getElementById("STAT_<?=$pnr;?>").style.width = '<?=$laenge;?>px';
    </script>

    warum erstellt php ein javascript, dass die Breite des ebenfalls vom php erzeugten div ändert? Warum schreibt php die Breitenangabe nicht direkt ans div?

    Gruß, Jürgen

    1. Hallo Jürgen,

      warum erstellt php ein javascript, dass die Breite des ebenfalls vom php erzeugten div ändert? Warum schreibt php die Breitenangabe nicht direkt ans div?

      Eine Transistion ist die Animation zwischen zwei Zuständen. Wenn ich die Breitenangabe direkt mmit php schreiben würde, würde sich ja keine Änderung ergeben und dadurch auch keine Transistion gestartet.

      Gruß,

      Klaus

      1. Hallo Klaus,

        hast du schon mal versucht, das Script verzögert aufzurufen?

        Gruß, Jürgen

  3. Hallo,

    ich habe es jetzt (warscheinlich recht umständlich) gelöst:
    Ich habe am Ende im Javascript einen Timeout auf eine Funktion gesetzt, die document.readyState auf 'complete' prüft und erst wenn die Seite vollständig geladen wurde, die neuen width-Werte setzt. Damit ist die Transition jetzt sauber gelaufen.

      
    window.setTimeout(animationstart, 100);  
    						  
    function animationstart() {  
       if(document.readyState != "complete") {  
          window.setTimeout(animationstart, 100);  
          return false;  
       } else {  
          <?=$scriptvar;?>  
       }  
    }  
    
    

    In $scriptvar stehen die Kommandos zur Änderung der Weite drin:
    document.getElementById("STAT_1").style.width = '75px';
    document.getElementById("STAT_2").style.width = '175px';
    document.getElementById("STAT_3").style.width = '305px';
    document.getElementById("STAT_4").style.width = '215px';

    Danke dennoch für die Hilfe.

    LG,

    Klaus

    1. Hallo,

      ich habe es jetzt (warscheinlich recht umständlich) gelöst:
      Ich habe am Ende im Javascript einen Timeout auf eine Funktion gesetzt, die document.readyState auf 'complete' prüft und erst wenn die Seite vollständig geladen wurde, die neuen width-Werte setzt.

      Ja, das hört sich recht umständlich an. Vermutlich kannst du einfach das load- oder DOMContentLoaded-Ereignis verwenden:
      JavaScript: Onload-Techniken

      Mathias