• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] Ajax-Script funktioniert nur mit einem Alert dazwischen...

thordirk

New member
Hi, mein Name ist Thor.

Ich fummle schon eine ganze Weile an einem Upload-Script, was wie folgt aussieht und bis auf eine Kleinigkeit hin funktioniert:

Code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Thors Test</title>
</head>
 
<body>
<div style="margin-bottom:20px;" id="uploadInfo">...</div>

<input type="file" name="afile" id="fu" accept="all/*" multiple>
<input type="button" name="uploadSpeichern" value="speichern" onClick="myUploader()">

<div style="margin-top:20px; margin-bottom:20px; width:600px; background-color:yellow;" id="UploadListe"></div>
<div id="fortschritt"></div>
</body>
</html>

<style>

td{
	padding:10px;
	background-color:lime;
}

</style>

<script type="text/javascript">

function myUploader()
{
	var A = document.getElementById('fu').files;
	
	if(A)
	{
		var D = '';
		
		D = D + '<table style="width:100%">';
		
		for(i = 0; i < A.length; i++)
		{
			var bla = "Q" + parseInt(i + 1);
			D=D+'<tr id="C'+i+'"> <td>'+A[i].name+'</td> <td>'+A[i].size+'</td> <td><div id="'+bla+'">0</div> %</td> <td>'+bla+'</td> </tr>';
		}
		
		D = D + '</table>';
		
		document.getElementById('UploadListe').innerHTML = D;
		
		D = '';
		
		for(j = 0; j < A.length; j++)
		{
			var blo = "Q" + parseInt(j + 1);
			
			var fd = new FormData();
			fd.append("afile", A[j]);
			
xhr =  new XMLHttpRequest();
			
			xhr.upload.onprogress = function(e)
			{
				var P = parseInt(100 / e.total * e.loaded);
				P = Math.floor(P);
				document.getElementById(blo).innerHTML = P;
			}
			
			xhr.open('POST', 'test4.php', true);
			xhr.send(fd);	
			
			//alert("");
		}
	}
}

</script>


Wenn ich das "//alert("");" auskommentiere funktioniert das Script und zeigt mir der Reihe nach hochlaufend an, wie viel Prozent einer jeweiligen Datei breits hochgeladen wurden.
Ohne alert erhält nur die zuletzt hochgeladene Datei den Prozentwert 100.


Kurze Erklärung zum Script:

Als erstes soll der Inhalt der hochgeladenen Daten im Table aufgelistet werden. Das passiert in der ersten Schleife.

Danach tritt die zweite Schleife in Aktion und kopiert Datei für Datei.

Ich habe das auch mit nur einer Schleife probiert. Bisher hat das nicht wirklich gefruchtet.

Als PHP-Mensch muss ich andeuten, dass Javascript ein wahrer Alptraum ist.
Wie viele LKWs müssen einem über den Schädel fahren, um so einen geistigen Krampf zu produzieren?
Und da wird von PHP gesagt, es sei eine nicht ernstzunehmende Sprache.

Na ja, wie dem auch sei. Um den Java-Kack kommt vorläufig noch keiner drum herum.

Und wer ich jetzt nicht auf die Schuhe gepinkelt fühlt, ist herzlich dazu eingeladen, mir eine konstruktive Antwort zu schreiben.

Herzlichst allerliebst euer Thor (Übrigens mein reeller Vorname!)



PS: Warum habe ich mir eigentlich die Mühe gemacht, den Code gut leserlich einzurücken, wie das Gottverdammte Script dieser Homepage alles wieder völlig zermatscht links anschlägt?

Ach ja, und geil, dass der geschriebene Text mit einem Klick auf Vorschau weg vom Teller war! Wie gut, vorher ein STRG+A+C zu benutzen.

- - - Aktualisiert - - -

Noch ein Hinweis:

Ein Alert(blo); im "xhr.upload.onprogress = function(e)" liefert stets dieselbe ID für die prozentuale Auswertung pro File. Ein Alert(blo); an andere Stelle liefert hingegen jeweils die richtige ID.
Es scheint mir, als würde "xhr.upload.onprogress = function(e)" einfach überrannt. Nur das Alert am Ende des Scripts - siehe oben! - hemmt das Programm am "Überrennen"! Im Übrigen scheint das Alert auch nur die prozentuale Aufrechnung anzuhalten. Die Dateien des Uploads sind mit dem ersten Alert schon längst übertragen worden, wie ich festgestellt habe.
 
Hi,

da die callback-Funktion onprogress asynchron ausgeführt wird, läuft der Index (j) weiter. Bis zur ersten Ausführung von onprogress ist der Wert beim Maximum angekommen und wird als Referenz verwendet.

Um dieses Verhalten zu verhindern, solltest du die gewünschte Variable an die Funktion binden. Moderne Browser unterstützen hierfür bereits die Methode bind, für ältere muss diese selbst implementiert werden. Das folgende Script zeigt das Vorgehen dafür, sowie die Anwendung.
Code:
if (typeof Function.prototype.bind != "function") {
    Function.prototype.bind = function() {
        var _fn = this;
        var _this = arguments[0];
        var arrArgs = [];
        if (arguments.length > 1) {
            for (var i = 1; i < arguments.length; i++) {
                arrArgs[arrArgs.length] = arguments[i];
            }
        }

        return (function(evt) {
            // als letztes Argument wird der Event übergeben
            arrArgs.push(evt || window.event);
            _fn.apply(_this, arrArgs);
        });
    }
}

function myUploader() {
    var A = document.getElementById('fu').files;

    if (A) {
        var D = '',
            xhrs = {};

        D = D + '<table style="width:100%">';

        for (var i = 0; i < A.length; i++) {
            var bla = "Q" + parseInt(i + 1);
            D = D + '<tr id="C' + i + '"> <td>' + A[i].name + '</td> <td>' + A[i].size + '</td> <td><div id="' + bla + '">0</div> %</td> <td>' + bla + '</td> </tr>';
        }

        D = D + '</table>';
        document.getElementById('UploadListe').innerHTML = D;
        D = '';

        for (var j = 0; j < A.length; j++) {
            var blo = "Q" + parseInt(j + 1),
                fd = new FormData();

            fd.append("afile", A[j]);

            xhrs[blo] = new XMLHttpRequest();

            xhrs[blo].upload.onprogress = (function(data, e) {
                var P = parseInt(100 / e.total * e.loaded);
                P = Math.floor(P);
                document.getElementById(data.id).innerHTML = P;
            }).bind(this, {
                id: blo
            });

            xhrs[blo].open('POST', 'my_upload_file.php', true);
            xhrs[blo].send(fd);
        }
    }
}
Ich hoffe, das hilft dir weiter.

Ciao
Quaese
 
Ja sagt Mal, stehe ich eigentlich im Wald?

Ich stelle eine komplizierte Frage und bekomme innerhalb weniger Stunden eine funktionierende Lösung.

Mein Grinsen ist grad breiter als die Bildschirmdiagonale!

Also, meine Hochachtung ist dir gezollt, lieber Quaese!

Das war professionell abgeliefert.
Und welch Mühe du dir gegeben hast - ich bin sprachlos!

Dann werd ich nun mal völlig aufgepeitscht mein Projekt weiterverfolgen.

1000 Dank!!!
 
Tja, so sind wir :D

Ab und zu sieht man aber wirklich den Wald vor lauter Bäumen nicht.
 
Zurück
Oben