Ankündigung

Einklappen
Keine Ankündigung bisher.

mehrere setTimeout zeitgleich

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • mehrere setTimeout zeitgleich

    Hallo,

    für einen Eingabebereich in meiner Anwendung habe ich drei Select Felder die über eine Ajaxkomponente miteinander verbunden sind. Auswahl 1 bestimmt Auswahl 2, Auswahl 2 die Auswahl 3, jeweils durch Datenbankabrufe, jeweils über das onChange / onKeyUp Ereignis angestoßen. Ganz nach Ajax' Natur laufen die Anfragen natürlich unabhängig voneinander, die vom zuständigen PHP Script gelieferten Daten werden per eval() als JS ausgeführt.
    Da den Selections ein ---Auswahl--- Listenelement vorangestellt ist, initiere ich als erste von Ajax gelieferte JS Anweisung einen Funktionsaufruf, die das aktuell geänderte Select farbig markiert (theobject wird vorher über getElementsByName () belegt, iNumber ist eine laufende Indexnummer für Ajax 'Ereignisse'), um die Änderung für eine gute halbe Sekunde optisch zu signalisieren:

    ajax_basic.js
    Code:
    var aMarks = array ();
    ...
    function MarkDynamic (theobject , iNumber)
      {
      theobject.style.backgroundColor='#beb';
      aMarks[iNumber] = window.setTimeout ('theobject.style.backgroundColor=""' , 600);
      }
    ...
    Das funktionierte auch gut, allerdings löscht ein gesetzter Timeout einen alten, obgleich ich über das Array verschiedene Variablen verwende. Das bedeutet, wenn ich schnell genug aus Select 1 und 2 nacheinander einen Eintrag wähle, wird die background-Farbe nur für das zuletzt geänderte Select zurückgesetzt.

    Hat jemand eine Erklärung dafür? Normalerweise können doch mehrere Timeouts zugleich ablaufen, oder?

    Zur Zeit lasse ich als Notbehelf den letzten Timeout vom neuen löschen und führe vorher die Rücksetzung des Style's aus, aber lieber wäre mir, eine voneinander unabhängige Funktionsweise.

  • #2
    Zwei Gründe könnte ich mir vorstellen:

    1.) Du wählst bei beiden <select> Feldern Elemente mit der selben iNumber aus, daher überschreibt der 2. Aufruf innerhalb der 600 Millisekunden das 1. timeout-Objekt im Array. Dadurch geht der 1. Aufruf verloren. Wobei ich aber nicht weiß, ob ein überschreiben einer timeout-Resource auch den Verlust der Operation zur Folge hat oder ob die sie nur mit clearTimeout zurückgenommen werden kann.
    obgleich ich über das Array verschiedene Variablen verwende
    Warum speicherst du den Timeout überhaupt? Macht ja eigentlich nur Sinn, wenn es sein könnte, dass du diesen mit clearTimeout() doch noch killen möchtest.

    Ist es also sichergestellt, dass iNumber nicht mehrfach vergeben ist?

    2.) Du hast die Funktion gekürzt um sie für uns verständlicher zu machen (array() ist beispielsweise eine PHP-Array-Zuweisung, in JavaScript benötigt man new Array()) und das Objekt, auf dass sich theobject bezieht hat sich mittlerweile (600 Millisekunden) geändert.

    Kommentar


    • #3
      Ja ich habs gekürzt (rekonstruiert), weils, wie gesagt nicht funktioniert. new array () ist natürlich richtig. Und ich schätze Du hast mich nicht ganz verstanden. Die ID für das Array (ja wozu eigentlich?) kommt aus meiner (php) Ajax Klasse, die einzelne Ajax Objekte verwaltet und als indiziertes Array vorhält.
      etwas konkreter:
      Ich denke die ajax Anfrage ist ok, sie funktioniert ja.
      Bei Klick ins erste Select liefert das Script dann bspw.
      Code:
      theobject = document.getElementsByName('Select2')[0];
      theobject.options.length = 0;
      MarkDynamic (theobject , 0);                     // <<<<<<<<<<<<<<
      SelectionElementAdd (theobject,'#','Auswahl');
      SelectionElementAdd (theobject,'0','Wert1');
      SelectionElementAdd (theobject,'1','Wert2');
      ein Klick ins zweite entsprechend
      Code:
      theobject = document.getElementsByName('Select3')[0];
      theobject.options.length = 0;
      MarkDynamic (theobject , 1);                     // <<<<<<<<<<<<<<
      SelectionElementAdd (theobject,'#','Auswahl');
      SelectionElementAdd (theobject,'0','Wert1');
      ...
      wobei diese Funktion aufgerufen wird:
      Code:
      function SelectionElementAdd (theobject , value , title)
        {
        theobject.options[theobject.options.length] = new Option(title , value);
        }
      Der entspr. Response (= responseText) läuft dann hier rein und wird ausgeführt:
      Code:
      function AjaxRequestCallback ()
        {
        if (xhttp.readyState==4 && xhttp.status==200)
          {
          try {
          eval (xhttp.responseText);
          }
          catch (e) {}
          }
        }
      Die Anfrage sind also voneinander unabhängig und m.E. dürfte das auch keinen Einfluss auf das Setzen des Timeouts haben, das Sie parallel ausgeführt werden. Tuts aber. Erfolgt innerhalb der ,6 sek. ein Klick in das jeweils andere Select, wird das zuerst markierte Zielobjekt nicht mehr zurückgesetzt. Was eigentlich nur daran liegen kann, dass das entspr. Timeout gelöscht, überschrieben oder sonstwie nicht ausgeführt wird.

      Kommentar


      • #4
        Ich habe schon verstanden, dass du wohl ein anderes iNumber übergibst, aber wenn dem so ist kann ich mir das Problem kaum erklären.
        Wenn du zudem noch nichtmal einen JavaScript-Fehler bekommst, kann es ja eigentlich nur an dieser Stelle passieren.
        Lass doch die aMarks-Zuweisung einfach mal weg, nur zu Testzwecken.

        Kommentar


        • #5
          tja, auch das habe ich schon gemacht. dann muß ich wohl dumm sterben. nen js fehler gibts auch nicht.

          Edit:
          Ich geb's auf und lass nur das letzte geänderte markieren. Habe es probiert, die beiden Anweisungen (style.backgroundColor und setTimeout) direkt von Ajax liefern zu lassen und per eval auszuwerten - selber Effekt. Ich schätze das hängt irgendwie mit eval zusammen. Noch bemerkenswert: Die Anweisungen scheinen sich die Zeit des Timeout zu teilen: das zweite angeklickte löst eine wesentlich kürzere Markierung des 'Zielobjektes' aus, als in einer Einzelaktion. Sozusagen die Restzeit, die vom ersten Timeout übrig geblieben ist. Alles höchst merkwürdig.

          Kommentar


          • #6
            Wenn du das komplette Projekt mal online stellst schaue ich gern nochmal drüber. Vielleicht finde ich ja etwas, was du beim ganzen Trouble doch übersehen hast.

            Kommentar


            • #7
              Schätze das ist zu aufwendig. Entwickle quasi parallel zu einer alten Anwendung und da hängen somit schon echte Kundendaten dran. Um die Datenbank mit gut 20 Tabellen und Spieldaten einzurichten fehlt mir leider grad die Zeit. Aber vielen Dank für das Angebot.

              Kommentar

              Lädt...
              X