Andre Herrmann: Ladebalken funktioniert nur mit alert()-Meldung

Hallo Leute,

Nach einiger Recherche habe ich leider niemanden gefunden der dasselbe Problem hat wie ich.

Zuerst: Die Seite wird nicht im Internet benutzt sondern stellt eine plattformunabhängige Mini-Anwendung dar, die im Firefox laufen soll.

Zum Start meiner Javascript-Seite wird eine große xml Datei im Hintergrund geparst (Mit XML for <script> -> http://xmljs.sourceforge.net/index.html) und die Daten in viele Listen eingetragen. Es handelt sich bei der XML-Datei um einen Fragenkatalog, der 150 Fragen beinhaltet. Dieses nimmt einige Zeit in Anspruch. So lange, dass Firefox mir nach einiger Zeit meldet, dass ein Script nicht Antwortet. Erst nach zwei bis dreimal klicken auf fortsetzen wird der Vorgang bis zu Ende durchgeführt.

Für diesen Start soll ein Ladebalken eingeblendet werden der dem Benutzer den Ladestand in Prozent mitteilt. Im Anschluss wird der Ladebalken-div versteckt und der Einstellungs-div sichtbar.

Meine Lösung funktioniert soweit schon ganz gut, allerdings nur wenn ich in der Funktion, die den Prozentbalken und -wert ändert ( progress(Wert) ) einen alert() hineinsetze. Lasse ich diesen weg, so kommt nach einiger Zeit die o.g. Meldung wegen dem nicht-antwortenden Skript und die Änderung des Wertes zur Zeit der Fehlermeldung wird eingetragen, der Ladebalken hingegen bleibt im Anfangszustand.

Mir scheint, dass Javascript irgendwie zu schnell arbeitet, jedoch das setzten eines künstlichen Sleeps funktioniert leider auch nicht und führt dazu, dass die Fehlermeldung noch öfter eingeblendet wird

Hier ist der entscheidene Code-Ausschnitt:

function startvorgang(lpic)
{
 if (lpic==1)
 {
  xmlDatei="lpic1.xml.html";
 }
 else
 {
  xmlDatei="lpic2.xml.html";
 }
 xmlIOLoadLocalData(xmlDatei, "initialisierung");
}
function sleep(ms){
 var zeit=(new Date()).getTime();
 var stoppZeit=zeit+ms;
 while((new Date()).getTime()<stoppZeit){};
}
function progress(Wert)
{
 OK = 0;
 // alert("Mit " + Wert + " anzeigen")
 if(Wert < 51)
  document.getElementById("balken").style.background = 'rgb(255, ' +
  Math.floor(Wert / 50 * 255) + ', 0)';
 else
  document.getElementById("balken").style.background = 'rgb(' +
  Math.floor(255 - ((Wert - 50) / 50 * 255)) +
  ', 255, 0)';

document.getElementById("rahmenbalken").firstChild.nodeValue = Wert +" % des Fragenkatalogs geladen...";
 document.getElementById("balken").style.width = Wert + "%";
 OK=1;
 // sleep(2000);
 alert(Wert + "%");
 return OK;

}

// Initialisierungsvorgang der Testeinstellungen
function initialisierung(strXML)
{
 var xml;
 xml = ""
 + "<?xml version="1.0"?>"
 + strXML;
 // alert (xml);
 var OK=0;
 OK = progress(1);
 // Listen zu den Fragedaten
 if(OK == 1) liste_fuellen(xml, "fragetitel", "fragetitel", 1, "");
 OK = progress(10);
 if(OK == 1) liste_fuellen(xml, "fragetyp", "fragetyp", 1, "");
 OK = progress(20);
 if(OK == 1) liste_fuellen(xml, "punkte", "punkte", 1, "");
 OK = progress(30);
 if(OK == 1) liste_fuellen(xml, "hinweis", "hinweis", 1, "");
 OK = progress(40);
 if(OK == 1) liste_fuellen(xml, "erklaerung", "erklaerung", 1, "");
 OK = progress(50);
 if(OK == 1) liste_fuellen(xml, "fragetext", "fragetext", 1, "");
 OK = progress(60);

// Listen zu den Antwortdaten
 if(OK == 1) liste_fuellen(xml, "antwort", "antworttext", 1, "");
 OK = progress(70);
 if(OK == 1) liste_fuellen(xml, "antwort", "zufrage", 2, "zufrage");
 OK = progress(80);
 if(OK == 1) liste_fuellen(xml, "antwort", "richtig", 2, "richtig");
 OK = progress(90);
 // Die restlichen Standardantworten eintragen
 if(OK == 1) matrix_fuellen();
 OK = progress(100);

if(OK == 1) document.getElementById("ladebalken").style.visibility = "hidden";
 if(OK == 1) document.getElementById("Einstellungen").style.visibility = "visible";
 if(OK == 1) document.Fragenanzahl.VerfuegbarAnzahl.value = AnzahlFragenkatalog();

}

ERLÄUTERUNG ZUM Code unten:
In der Funktion Startvorgang befindet sich eine Funktion aus dem XML for <script>-Framework welcher die XML-Datei einliest.
Diese Ruft nach Einlesen des XML die Funktion initialisierung auf.
Danach werden die einzelnen Listen gefüllt und nach jedem Vorgang soll der Prozentwert geändert werden.
Funktioniert wie gesagt gut, wenn alert() in der Funktion progress() ausgeführt wird und der Benutzer ständig ok klickt. Lässt man das weg kommen Meldungen über das nicht-antwortende Skript.
Die Fehlerkonsole von Firefox meldet keinerlei Fehler bei der Prozedur

Hoffe jemand hat eine Idee, wie ich das ohne den alert hinbekomme

Danke im Voraus

André

  1. Moin!

    Mir scheint, dass Javascript irgendwie zu schnell arbeitet, jedoch das setzten eines künstlichen Sleeps funktioniert leider auch nicht und führt dazu, dass die Fehlermeldung noch öfter eingeblendet wird

    Der Browser aktualisiert das Fenster nur, wenn Javascript nicht mehr ausgeführt wird. Dein "sleep" stoppt bzw. unterbricht aber nicht die Ausführung, sondern dreht unter aktiver Codeausführung nur Däumchen - 100% CPU-Auslastung, aber keinerlei Fensteraktualisierung.

    Du mußt die Gesamtaufgabe in Einzelschritte zerlegen, die du jeweils mit setTimeout aufrufst, bzw. indem du den jeweils nächsten Schritt damit aufrufst. Nur damit beendest du Javascript, setzt aber einen Timer, der dann nach kurzer Wartezeit (in der der Browser den Bildschirm aktualisiert) die weitere Ausführung anstößt.

    Alternativ ist es eventuell eine bessere Idee, kein XML zu parsen, sondern diese Daten direkt als Javascript-kompatible Datenstruktur verfügbar zu machen. JSON käme da ins Spiel.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
  2. Hallo,

    Zum Start meiner Javascript-Seite wird eine große xml Datei im Hintergrund geparst (Mit XML for <script> -> http://xmljs.sourceforge.net/index.html) und die Daten in viele Listen eingetragen.

    Firefox hat mindestens zwei Möglichkeiten, XML-Dateien einzulesen, sodass sie über das DOM ansprechbar sind: document.implementation.createDocument plus .load() oder XMLHttpRequest (siehe etwa Import XML). Bei beiden Möglichkeiten wird der Firefox-interne XML-Parser genutzt, der superschnell arbeitet.

    Es besteht keine Notwendigkeit, einen XML-Parser in JavaScript zu nutzen. Bei näherer Betrachtung ist das ein völliger Performance-Overkill. Ein Grund für die Nutzung von »XML for Script« scheint mir die Möglichkeit, das XML-Dokument über XPath-ähnliche Ausdrücke abfragen zu können. Das ist toll, aber ebenso überflüssig, weil Firefox eine hervorragende native XPath-Implementierung über document.evaluate oder XPathEvaluator bietet.

    Es ist ein enormer Geschwindigkeitszuwachs, wenn du »XML for Script« herauswirfst. Die nativen Möglichkeiten arbeiten soweit ich weiß auch beide asynchron bzw. eventbasiert, sodass für den JavaScript-Interpreter nicht ein Scriptteil ewig lange läuft, sondern immer abgehackt kleine Teile, die dann nach dem Laden einer XML-Datei berichterstattet, sodass der Ladebalken aktualisiert wird.

    Aber wie Sven sagt, wenn du die Daten ohnehin nur »in viele Listen eintragen« willst, dann kannst du diese JavaScript-Objekte auch gleich in einer für JavaScript geeigneteren Form speichern. Außerdem solltest du prüfen, ob du die Daten nicht inkrementell nachladen kannst.

    Mathias

    1. Hi,

      danke erstmal für die hilfreichen Tipps!

      Nach einiger Überlegung bin ich auch zu dem Schluss gekommen, dass XML for <script> bestenfalls die drittbeste Lösung für mich ist.
      Allerdings möchte ich schon bei XML bleiben, da mein Kunde die Daten schon so vorliegen hat und ich zur Entwicklung nicht noch die Ganzen Daten anpassen möchte.
      Zudem sind Erweiterungen für den Kunden nach dem XML-Schema einfacher zu behandeln.
      So möchte ich mein Glück mit dem von Matthias vorgeschlagenen Import XML -Link probieren.

      Auf den ersten Blick sieht es auch so aus als ob der Eingriff im Code nicht so dramatisch ausfällt, da das gesamte XML-Dokument am Anfang eingeladen wird und anschließend mit den Listen weitergearbeitet wird, also kein weiterer Zugriff auf die XML-Datei erfolgt.

      Leider ist in dem Link oben nicht beschrieben, wie ich auf Attribute des Tags zugreifen kann. Im Beispiel mit dem <emporor> werden lediglich die Inhalte der Tags eingelesen. In meinem Fall ist es aber nötig den Inhalt der Attribute einzulesen.

      In meinem Beispiel handelt es sich um folgendes XML-Schema:

      <fragetitel>Frage 1</fragetitel>
       <fragetyp>auswahl</fragetyp>
       <punkte>1</punkte>
       <hinweis>keiner</hinweis>

      <erklaerung>keine</erklaerung>
       <fragetext>
       Das Kommando jobs gibt folgende Ausgabe auf Ihrem Terminal aus:
       [1]+ Stopped /usr/bin/programm
       Welches Kommando setzt die Ausführung des Programms im Hintergrund fort, so dass Sie weitere Kommandos auf dem gleichen Terminal eingeben können?
       </fragetext>
       <antwort zuFrage="Frage 1" richtig="ja">bg 1</antwort>
       <antwort zuFrage="Frage 1" richtig="nein">continue programm</antwort>
       <antwort zuFrage="Frage 1" richtig="nein">exec programm</antwort>
       <antwort zuFrage="Frage 1" richtig="nein">fg programm</antwort>
       <antwort zuFrage="Frage 1" richtig="nein">programm &</antwort>

      Der Zugriff auf XML erfolgt in den Funktionen startvorgang, initialisierung und liste_fuellen (Nach der alten, fehlerhaften Methode):

      function startvorgang(lpic)
      {
       if (lpic==1)
       {
        xmlDatei="lpic1.xml.html";
       }
       else
       {
        xmlDatei="lpic2.xml.html";
       }
       xmlIOLoadLocalData(xmlDatei, "initialisierung");

      }

      function progress(Wert)
      {
       document.getElementById("rahmenbalken").firstChild.nodeValue = Wert +" % des Fragenkatalogs geladen...";
       document.getElementById("balken").style.width = Wert + "%";
       alert("Ohne Mich sieht man nix ;(");
      }

      function initialisierung(strXML)
      {
       var xml;
       xml = ""
       + "<?xml version="1.0"?>"
       + strXML;

      progress(5);
       liste_fuellen(xml, "fragetitel", "fragetitel", 1, "",5);
       progress(10);
       liste_fuellen(xml, "fragetyp", "fragetyp", 1, "",10);
       progress(20);
       liste_fuellen(xml, "punkte", "punkte", 1, "",20);
       progress(30);
       liste_fuellen(xml, "hinweis", "hinweis", 1, "",30);
       progress(40);
       liste_fuellen(xml, "erklaerung", "erklaerung", 1, "",40);
       progress(50);
       liste_fuellen(xml, "fragetext", "fragetext", 1, "",50);
       progress(60);
       liste_fuellen(xml, "antwort", "antworttext", 1, "",60);
       progress(70);
       liste_fuellen(xml, "antwort", "zufrage", 2, "zufrage",70);
       progress(80);
       liste_fuellen(xml, "antwort", "richtig", 2, "richtig",80);
       progress(90);
       matrix_fuellen();
       progress(100);
       document.getElementById("ladebalken").style.visibility = "hidden";
       document.getElementById("Einstellungen").style.visibility = "visible";
       document.Fragenanzahl.VerfuegbarAnzahl.value = AnzahlFragenkatalog();
      }
      function liste_fuellen(xml, xml_tag, liste, typ, attribut, prozent)
      {
      XML-Datei)
       var objDom = new XMLDoc(xml, xmlError)
       var objDomTree = objDom.docNode;
       // Wird nach dem Tag oder nach
       // alert("Und Los!");
       var Elements = objDomTree.getElements(xml_tag);
       var i=0;
       do
       {
        var element = Elements[i];
        if (element)
        {
         // Im Normalfall gehts um den Inhalt des Textes
         var inhalt = element.getText();
         // Aber wenn typ 2 angegeben wurde so werden die Attribute herausgezogen
         if (typ==2)
         {
          // alert("Extra");
          var referenceNode = element;
          var attributeValue = referenceNode.getAttribute(attribut);
          inhalt = attributeValue;
         }
         // Den Inhalt in die übergebene Liste eintragen
         NeuerEintrag = new Option(inhalt, inhalt, false, true);
         parent.teststeuerung.document.getElementById(liste).options[parent.teststeuerung.document.getElementById(liste).length] = NeuerEintrag;
         i++;
        }
        else
        {
         inhalt = "";
        }
        // alert(inhalt);
       } while(inhalt != "");
       anzahl_elemente=i;
       //progress(prozent);
       // alert(anzahl_elemente);
      }

      Hoffe der Zugriff auf die XML-Attribute ist auch mit der Lösung von Matthias möglich.

      Vielleicht hat ja einer von euch noch den Letzen Hinweis den ich benötige.

      Danke

      André

      1. Hallo,

        Leider ist in dem Link oben nicht beschrieben, wie ich auf Attribute des Tags zugreifen kann.

        Für Zugriffe auf das Dokument nutzt du das DOM.
        Zum Abfragen eines Attributwertes gibt es die DOM-Methode elemenknoten.getAttribute("attrname").

        Mathias

        1. Zum Abfragen eines Attributwertes gibt es die DOM-Methode elemenknoten.getAttribute("attrname").

          Ich verstehe deine Frage nicht ganz, denn genau das macht die Pseudo-DOM-Implementierung von »XML for script« in der Funktion liste_fuellen() bereits. Vom Schema her stimmt das im Groben, bis auf objDomTree.getElements - da nimmst du halt xmlDocument.getElementsByTagName(). Und statt new XMLDoc() usw. nimmst du eben document.implementation.createDocument() und eine onload-Handlerfunktion wie im verlinkten Beispiel.

          1. Zitat von molily:

            "Ich verstehe deine Frage nicht ganz, denn genau das macht die Pseudo-DOM-Implementierung von »XML for script« in der Funktion liste_fuellen() bereits"

            Die Ähnlichkeit ist mir beim umstellen dann auch aufgefallen ;)

            Allerdings krieg ichs derzeit net zum laufen.
            Als Vorlage habe ich den Import XML-Link von Matthias verwendet, allerdings bin ich noch nicht so fit was den Umgang damit betrifft. Ich schätze mal die Node-Zuordnungen stimmen einfach noch nicht oder die XML-Datei wurde nicht korrekt geladen, da ich bei jedem Zugriff auf die Nodes eine Meldung in der Fehlerkonsole erhalte, die mir erzählt, dass das gewählte Element keine Eigenschaften besitzt, also nicht existiert.
            Ein alert hiervon:
             var xml_element = xmlDoc.getElementsByTagName(xml_tag);
             anzahl_elemente=xml_element.length;
            gibt mir 0 aus, so als wenn immer noch dieses leere Dokument existiert:
                  xmlDoc = document.implementation.createDocument("", "", null);

            Hier mein letzter Code:

            function startvorgang(lpic)
            {
             if (lpic==1)
             {
              xmlDatei="lpic1.xml.html";
             }
             else
             {
              xmlDatei="lpic2.xml.html";
             }

            if (document.implementation && document.implementation.createDocument)
             {
              alert("Firefox");
              xmlDoc = document.implementation.createDocument("", "", null);
              xmlDoc.onload = initialisierung;
             }
             else if (window.ActiveXObject)
             {
              xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
              xmlDoc.onreadystatechange = function () {
               if (xmlDoc.readyState == 4) initialisierung()
              };
              }
             else
             {
              alert('Mit diesem Browser funktioniert die Software nicht.\n Diese Software ist für den Browser Firefox optimiert');
              return;
             }
             xmlDoc.load(xmlDatei);

            }
            function progress(Wert)
            {
             document.getElementById("rahmenbalken").firstChild.nodeValue = Wert +" % des Fragenkatalogs geladen...";
             document.getElementById("balken").style.width = Wert + "%";
            }
            // Initialisierungsvorgang der Testeinstellungen
            function initialisierung() // strXML
            {
             progress(5);
             liste_fuellen("fragetitel", "fragetitel", 1, "",5);
             progress(10);
             liste_fuellen("fragetyp", "fragetyp", 1, "",10);
             progress(20);
             liste_fuellen("punkte", "punkte", 1, "",20);
             progress(30);
             liste_fuellen("hinweis", "hinweis", 1, "",30);
             progress(40);
             liste_fuellen("erklaerung", "erklaerung", 1, "",40);
             progress(50);
             liste_fuellen("fragetext", "fragetext", 1, "",50);
             progress(60);
             liste_fuellen("antwort", "antworttext", 1, "",60);
             progress(70);
             liste_fuellen("antwort", "zufrage", 2, "zufrage",70);
             progress(80);
             liste_fuellen("antwort", "richtig", 2, "richtig",80);
             progress(90);
             matrix_fuellen();
             progress(100);
             document.getElementById("ladebalken").style.visibility = "hidden";
             document.getElementById("Einstellungen").style.visibility = "visible";
             document.Fragenanzahl.VerfuegbarAnzahl.value = AnzahlFragenkatalog();
            }
            function liste_fuellen(xml_tag, liste, typ, attribut, prozent)
            {
             var xml_element = xmlDoc.getElementsByTagName(xml_tag);
             anzahl_elemente=xml_element.length;

            for (i=0;i<anzahl_elemente;i++)
             {
              alert("1. schleife");
              var element = xml_element[i];
              for (j=0;j<xml_element[i].childNodes.length;j++)
              {
               alert ("2. Schleife");
               var inhalt = xml_element[i].childNodes[j].firstChild.nodeValue;
               if (typ==2)
               {
                var referenceNode = element;
                var attributeValue = referenceNode.getAttribute(attribut);
                inhalt = attributeValue;
               }
               NeuerEintrag = new Option(inhalt, inhalt, false, true);
               parent.teststeuerung.document.getElementById(liste).options[parent.teststeuerung.document.getElementById(liste).length] = NeuerEintrag;
               i++;
              }
             }
            }

            1. Bin jetzt schon ein bisschen weiter, d.h. Er lädt das xml Dokument mitlerweile.

              Arbeite noch ein paar kleinigkeiten. Werd dann noch das fertige skript posten oder euch weiter mit meinen Problemen nerven.

              Danke auf jeden Fall bis hierhin :-)

  3. Hab jetzt auf den internen XML-Parser von Firefox umgestellt und hab den Schritt definitiv nicht bereut, denn die Ladezeit ist deutlich geringer als zuvor.

    Allerdings bin ich in Sachen Ladebalken nicht wirklich weiter gekommen.
    Es findet noch immer keine Aktualisierung statt, obwohl ich die Ladebalkensteuerung mittlerweile mit setInterval() realisiert habe. Mittlerweile habe ich den Fragenkatalog auf 150 Fragen anwachsen lassen Noch schlimmer ist, dass ich wieder die Meldung von Firefox erhalte, ob das laufende Skript beendet oder fortgesetzt werden soll :((((
    Zweimal muss ich bestätigen, dass er fortsetzen soll, erst dann läuft es. Ich muss davon ausgehen, dass der Großteil der Zielgruppen-Nutzer noch schwächere Kisten am laufen hat.

    Hier mein letzter Code, der den XML-Fragenkatalog lädt:

    // XML Datei Laden und weiter zur initialisierung
    //
    // 19.12.2007 ah
    function startvorgang(lpic)
    {

    if (lpic==1)
     {
      xmlDatei="lpic1.xml";
     }
     else
     {
      xmlDatei="lpic2.xml";
     }

    if (document.implementation && document.implementation.createDocument)
     {
      // alert("Firefox");
      xmlDoc = document.implementation.createDocument("", "", null);
      xmlDoc.onload = initialisierung;
     }
     else if (window.ActiveXObject)
     {
      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
      xmlDoc.onreadystatechange = function () {
       if (xmlDoc.readyState == 4) initialisierung()
      };
      }
     else
     {
      alert('Mit diesem Browser funktioniert die Software nicht.\n Diese Software ist für den Browser Firefox optimiert');
      return;
     }
     xmlDoc.async = false;
     xmlDoc.load(xmlDatei);
     laden = window.setInterval("progress()", 1000);
    }
    function progress()
    {
     document.getElementById("rahmenbalken").firstChild.nodeValue = fortschritt_aktuell +" % des Fragenkatalogs geladen...";
     document.getElementById("balken").style.width = fortschritt_aktuell + "%";
    }
    // Initialisierungsvorgang der Testeinstellungen
    function initialisierung() // strXML
    {
     liste_fuellen("fragetitel", "fragetitel", 1, "");
     fortschritt_aktuell=10;
     liste_fuellen("fragetyp", "fragetyp", 1, "");
     fortschritt_aktuell=20;
     liste_fuellen("punkte", "punkte", 1, "");
     fortschritt_aktuell=30;
     liste_fuellen("hinweis", "hinweis", 1, "");
     fortschritt_aktuell=40;
     liste_fuellen("erklaerung", "erklaerung", 1, "");
     fortschritt_aktuell=50;
     liste_fuellen("fragetext", "fragetext", 1, "");
     fortschritt_aktuell=60;
     liste_fuellen("antwort", "antworttext", 1, "");
     fortschritt_aktuell=70;
     liste_fuellen("antwort", "zufrage", 2, "zuFrage");
     fortschritt_aktuell=80;
     liste_fuellen("antwort", "richtig", 2, "richtig");
     matrix_fuellen();
     document.getElementById("ladebalken").style.visibility = "hidden";
     document.getElementById("Einstellungen").style.visibility = "visible";
     document.Fragenanzahl.VerfuegbarAnzahl.value = AnzahlFragenkatalog();
     window.clearInterval(laden);
    }
    function liste_fuellen(xml_tag, liste, typ, attribut)
    {
     var xml_element = xmlDoc.getElementsByTagName(xml_tag);
     var anzahl_elemente=xml_element.length;

    for (var i=0;i<anzahl_elemente;i++)
     {
      var element = xml_element[i];
      for (j=0;j<element.childNodes.length;j++)
      {
       var inhalt = element.firstChild.nodeValue;
       if (typ==2)
       {
        var attributeValue = element.getAttribute(attribut);
        var inhalt = attributeValue;
       }
       NeuerEintrag = new Option(inhalt, inhalt, false, true);
       parent.teststeuerung.document.getElementById(liste).options[parent.teststeuerung.document.getElementById(liste).length] = NeuerEintrag;
      }
     }

    }
    function matrix_fuellen()
    {
     // Die Liste mit den Fragetiteln durchlaufen
     for (var i=0;i < parent.teststeuerung.document.listen.fragetitel.length; i++)
     {
      var AktuellerFragetitel = parent.teststeuerung.document.listen.fragetitel.options[i].value;
      var MatrixString = "";
      // Die zweite Schleife durchläuft die Liste zufrage nach den zum fragetitel passenden Antworten
      for (var i2=0; i2 < parent.teststeuerung.document.listen.zufrage.length; i2++)
      {
       var AktuelleZuFrage = parent.teststeuerung.document.listen.zufrage.options[i2].value;
       // Auf übereinstimmung Prüfen
       if(AktuelleZuFrage == AktuellerFragetitel)
       {
        // Bei übereinstimmung den Wert aus der Liste richtig auswerten
        // Der Matrix den entsprechenden Wert (0 oder 1) zuweisen
        AktuellRichtig = parent.teststeuerung.document.listen.richtig.options[i2].value;
        // Wenn Antwort richtig, dann eine 1 sonst eine 0
        if (AktuellRichtig == "ja")
        {
         MatrixString = MatrixString + "1";
        }
        else
        {
         MatrixString = MatrixString + "0";
        }
       }
      }
      // Nach Auswertung der vorgegebenen Antworten und ihre Richtigkeit wird der MatrixString in die
      // zur Frage passende mustermatrix-Liste
      NeuerEintrag = new Option(MatrixString, MatrixString, false, true);
      parent.teststeuerung.document.listen.mustermatrix.options[parent.teststeuerung.document.listen.mustermatrix.length] = NeuerEintrag;
     }
     // Jetzt noch die gegebenen Antworten eintragen (default: Alle auf 0)
     for (var i=0;i < parent.teststeuerung.document.listen.fragetitel.length; i++)
     {
      var AktuellerFragetitel = parent.teststeuerung.document.listen.fragetitel.options[i].value;
      var MatrixString = "";
      // Die zweite Schleife durchläuft die Liste zufrage nach den zum fragetitel passenden Antworten
      for (var i2=0; i2 < parent.teststeuerung.document.listen.zufrage.length; i2++ )
      {
       var AktuelleZuFrage = parent.teststeuerung.document.listen.zufrage.options[i2].value;
       // Auf übereinstimmung Prüfen
       if(AktuelleZuFrage == AktuellerFragetitel)
       {
         MatrixString = MatrixString + "0";
       }
      }
      // Nach Auswertung der vorgegebenen Antworten und ihre Richtigkeit wird der MatrixString in die
      // zur Frage passende mustermatrix-Liste
      NeuerEintrag = new Option(MatrixString, MatrixString, false, true);
      parent.teststeuerung.document.listen.antwortmatrix.options[parent.teststeuerung.document.listen.antwortmatrix.length] = NeuerEintrag;
      var Free = "";
      NeuerEintrag = new Option(Free, Free, false, true);
      parent.teststeuerung.document.listen.antworteingabe.options[parent.teststeuerung.document.listen.antworteingabe.length] = NeuerEintrag;
      var Zero ="0";
      NeuerEintrag = new Option(Zero, Zero, false, true);
      parent.teststeuerung.document.listen.wiedervorlage.options[parent.teststeuerung.document.listen.wiedervorlage.length] = NeuerEintrag;
     }
    }

    Leider fällt mir nicht mehr viel ein.
    Irgendwie muss ich dem Browser wenigstens zwischendurch melden, dass alles ok ist und er nicht das Fenster mit der Meldung oben aufpoppen lässt.

    Hoffe jemand hat einen Rat für mich.

    Dank im Voraus

    André

    1. Moin!

      Allerdings bin ich in Sachen Ladebalken nicht wirklich weiter gekommen.
      Es findet noch immer keine Aktualisierung statt, obwohl ich die Ladebalkensteuerung mittlerweile mit setInterval() realisiert habe.

      Aber nicht so, wie ich es sagte. Du rufst einmalig setInterval auf und hoffst, dass dann regelmäßig der Balken wächst, indem du einfach nur die Fortschrittsvariable änderst. Aber Javascript ist eine Single-Task-Sprache, d.h. wenn irgendwo eine Funktion ausgeführt wird, wird keinerlei andere Funktion parallel ausgeführt.

      Das bedeutet:

      Hier mein letzter Code, der den XML-Fragenkatalog lädt:

      Ein frommer Wunsch, der nur ausgeführt wird, wenn absolut nichts zu tun ist:

      laden = window.setInterval("progress()", 1000);

      Das hier soll getan werden (ist im Prinzip nicht falsch, wird nur nie ausgeführt).

      function progress()
      {
      document.getElementById("rahmenbalken").firstChild.nodeValue = fortschritt_aktuell +" % des Fragenkatalogs geladen...";
      document.getElementById("balken").style.width = fortschritt_aktuell + "%";
      }

      Und das hier wird, ohne dass eine Pause gemacht wird, indem die Funktion echt endet, ausgeführt, ohne Zeit für den Balken zu lassen:

      function initialisierung() // strXML
      {
      liste_fuellen("fragetitel", "fragetitel", 1, "");
      fortschritt_aktuell=10;
      liste_fuellen("fragetyp", "fragetyp", 1, "");
      fortschritt_aktuell=20;
      liste_fuellen("punkte", "punkte", 1, "");
      fortschritt_aktuell=30;
      liste_fuellen("hinweis", "hinweis", 1, "");
      fortschritt_aktuell=40;
      liste_fuellen("erklaerung", "erklaerung", 1, "");
      fortschritt_aktuell=50;
      liste_fuellen("fragetext", "fragetext", 1, "");
      fortschritt_aktuell=60;
      liste_fuellen("antwort", "antworttext", 1, "");
      fortschritt_aktuell=70;
      liste_fuellen("antwort", "zufrage", 2, "zuFrage");
      fortschritt_aktuell=80;

      ...

      Korrekte Vorgehensweise wäre:
      1. Funktionsaufruf.
      2. Funktion erledigt eine kleine Teilaufgabe.
      3. Funktion aktualisiert den Fortschrittsbalken.
      4. Funktion prüft, ob noch weitere Aufgaben zu erledigen sind. Wenn ja:
         4a. Funktion setzt mit setTimeout ihren eigenen Wiederaufruf auf die Liste.
      5. Funktion endet.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
    2. Hallo,

      der Vorschlag wurde dir schon gemacht, die Initialisierung in Teilschritten ausführen:

        
        
      
      >  xmlDoc.async = false;  
      >  xmlDoc.load(xmlDatei);  
      >  laden = window.setInterval("progress()", 1000);  
        
      initial(10);  
        
        
      
      > // Initialisierungsvorgang der Testeinstellungen  
      
      function initial(fortschritt) // strXML  
      {  
       switch (fortschritt) {  
       case 10:  
        liste_fuellen("fragetitel", "fragetitel", 1, "");  
        break;  
        
       case 20:  
        liste_fuellen("fragetyp", "fragetyp", 1, "");  
        break;  
        
      // ....  
       case 80:  
         liste_fuellen("antwort", "richtig", 2, "richtig");  
        break;  
       case 90:  
        matrix_fuellen();  
        document.getElementById("ladebalken").style.visibility = "hidden";  
        document.getElementById("Einstellungen").style.visibility = "visible";  
        document.Fragenanzahl.VerfuegbarAnzahl.value = AnzahlFragenkatalog();  
       }  
        
       progress(fortschritt);  
       fortschritt+=10;  
       if (fortschritt < 100) setTimeout(function() {initial(fortschritt);},50);  
      }  
        
      
      

      dann lässt sich der Code noch optimieren, indem du lokale Variablen als Referenz auf die select-Elemente nutzt.

        
      
      > function liste_fuellen(xml_tag, liste, typ, attribut)  
      > {  
      >  var xml_element = xmlDoc.getElementsByTagName(xml_tag);  
      >  var anzahl_elemente=xml_element.length;  
        
          var select=parent.teststeuerung.document.getElementById(liste);  
      
      >   
      >  for (var i=0;i<anzahl_elemente;i++)  
      >  {  
      >   var element = xml_element[i];  
      >   for (j=0;j<element.childNodes.length;j++)  
      >   {  
      
       // macht das Sinn, immer element.firstChild nehmen?  
      
      >    var inhalt = element.firstChild.nodeValue;  
      >    if (typ==2)  
      >    {  
      >     var attributeValue = element.getAttribute(attribut);  
      >     var inhalt = attributeValue;  
      >    }  
      
          var NeuerEintrag = new Option(inhalt, inhalt, false, true);  
          select.options[select.options.length] = NeuerEintrag;  
      
      >   }  
      >  }  
      
      

      Gruß plan_B

      --
           *®*´¯`·.¸¸.·