Knight: Einmaliger Funktionsaufruf nach Ablauf einer Schleife

Hallo,

ich habe folgendes Problem:
Und zwar möchte ich prüfen, ob ein Element vorhanden ist. Sobald das Element vorhanden ist, soll EIN MAL eine Funktion aufgerufen werden, wenn das Element wieder gelöscht wird, soll das ganze von vorne los gehen. Ich habe es schon mit einer while-Schleife probiert:

  
while(document.getElementById('myDiv')) {  
   machwas();  
}  

Das ganze funktioniert nicht, was mich nicht verwundert, da in JavaScript ja alle Befehle nach der Reihe abgearbeitet werden und die while-Schleife garnicht erst anfängt. Das Element ist wird erst nach einiger (unbestimmter) Zeit durch einen Link eingefügt. Ich bräuchte also:

  
while(!document.getElementById('myDiv')) {  
   machnichts();  
}  

Und einen Funktionsaufruf der unmittelbar NACH dem Ablaufen der while-Schleife passiert. Ist sowas möglich? Wenn ja, wie?

Grüße, Knight

--
ie:{ fl:) br:^ va:) ls:~ fo:| rl:( n4:& ss:| de:> js:) ch:| sh:} mo:} zu:(
  1. Hallo Knight,

    beschreibe bitte, wie es dazu kommt, das ein Element vorhanden sein kann! Grundlage Deines abzufragenden Events zum Aufruf einer Funktion ist ja Die Existens eines Elements.

    Wodurch wird das Element ins Dokument eingefügt (Seitenladevorgang oder eine andere Funktion)?
    Wenn das Element von einer Funktion eingefügt wird, warum passt Du diese nicht an, um die (Pseudo-)Funktion machwas(); aufzurufen?

    Gruß aus Berlin!
    eddi

    1. Hallo eddi,

      Das Element wird, wie beschrieben, durch klicken eines Links einfegefügt. Dadurch wird KEINE neue Seite aufgerufen sondern durch JavaScript (genauer gesagt Ajax) ein neues Element eingefügt. Das passiert also auf Wunsch des Nutzers, wenn er lust hat.
      Wichtig dazu ist: Das Element (ich nenne es jetzt mal Element1) liegt innerhalb eines anderen Elementes (Element2). Durch klicken auf den Link wird Element2 sofort sichtbar, Element1 wird erst noch kurz geladen.
      Wenn das so möglich wäre, hätte ich das gemacht. Leider ist das jedoch nicht meine Seite und deshalb kann ich das auch nicht tun. Ich habe aber gerade eine Idee, die ich testen werde.

      Grüße, Knight

      --
      ie:{ fl:) br:^ va:) ls:~ fo:| rl:( n4:& ss:| de:> js:) ch:| sh:} mo:} zu:(
      1. Re:

        Du beantwortest die Fragen nicht. Insbesondere wäre doch wichtig zu klären, wenn das Einfügen des Elements "Element1" nach einem Ajax-Ladevorgang geschieht, warum Du keine Wrapperfunction nutzt, die im Anschluss an den Ajax-Request und dem Einfügen machwas() aufruft:

        function ajaxRequest(){  
          // vorgegebene Funktion  
          return (einfuegeElement);  
        }  
        function verarbeiteAjax(){  
          // vorgegebene Funktion  
          document.getElementsById('Element2').appendChild(ajaxRequest());  
          return(false);  
        }  
        function wrapper(){  
          // Deine Wrapperfunktion  
          document.getElementsById('Element2').appendChild(ajaxRequest());  
          
          machwas();  
          
          return(false);  
        }  
        window.onload=document.getElementsById('Verweis').setAttribute('onclick','return wrapper();');
        

        <a href="#" onclick='return verarbeiteAjax();'>Inhalt einfügen</a>

        Gruß aus Berlin!
        eddi

        1. Hi!

          Du beantwortest die Fragen nicht. Insbesondere wäre doch wichtig zu klären, wenn das Einfügen des Elements "Element1" nach einem Ajax-Ladevorgang geschieht, warum Du keine Wrapperfunction nutzt, die im Anschluss an den Ajax-Request und dem Einfügen machwas() aufruft:

          Ich zitiere hier mal Knight:

          Wenn das so möglich wäre, hätte ich das gemacht. Leider ist das jedoch nicht meine Seite und deshalb kann ich das auch nicht tun. Ich habe aber gerade eine Idee, die ich testen werde.

          Das hat er zugegebenermassen erstmal verschwiegen. Ich nehme an, er moechte ein Seite modifizieren nachdem sie geladen wurde. Jedenfalls verstehe ich das gerade so. Er moechte also einen Eventhandler einfuegen, der auf den existierenden Code reagiert. Da wuerde ich doch mit timern arbeiten, die das Element abfragen.

          --
          "Die Diebesgilde beklagte sich darueber, dass Mumm in aller Oeffentlichkeit behauptet hatte, hinter den meisten Diebstaehlen steckten Diebe."
                - T. Pratchett
          1. Hi!

            Das hat er zugegebenermassen erstmal verschwiegen. Ich nehme an, er moechte ein Seite modifizieren nachdem sie geladen wurde. Jedenfalls verstehe ich das gerade so. Er moechte also einen Eventhandler einfuegen, der auf den existierenden Code reagiert. Da wuerde ich doch mit timern arbeiten, die das Element abfragen.

            Zugegebenermaßen, ja das habe ich Anfangs verschwiegen. Ich wusste nicht ob das so wichtig ist. Ja, mein Plan ist es durch ein Userscript (vielleicht sagt euch das ja was) eine JavaScript Datei einzubinden. Darum geht es aber nicht, es geht um den Inhalt dieser Datei, die also praktisch wie eine ganz normale JavaScript Datei eingebunden ist. Den JavaScript Code kann ich ja durch JavaScript nicht ändern ;)
            Das Problem ist im Prinzip noch das gleiche:

              
            function activate_check() {  
                while(!document.getElementById('bag')) {      // Solange Element nicht vorhanden, soll nichts passieren  
                }  
                machwas();                         // Dannach soll Funktion ausgeführt werden  
            }  
              
              
            document.getElementById('link1').firstChild.setAttribute("onclick", "AjaxWindow.show('beispielwindow'); activate_check();");  // fügt Funktionsaufruf in onClick-Handler ein  
            
            

            Wenn jetzt auf den Link innerhalb des Div's 'link1' geklickt wird, wird die Schleife aktiviert und - führt zu einer Warnung, dass das Script nicht reagiert oder auf eine Eingabe wartet. Wundert mich nicht, denn es dauert kurz, bis das Elemnt 'bag' vorhanden ist, da erst noch Informationen ausgelesen werden müssen. In der Zeit lastet die while-Schleife Mozilla aus. Habe ich einen Fehler gemacht? Gibt es eine Alternative zum Checken? Ich schreibe zur Verständlichkeit nochmal die Aktionen, die ausgeführt werden, chronologisch auf:

            1. Seitenaufbau
            2. Etwa 3 Sekunde nach Ladeanfang (spätestens kurz vorm Ende des Ladens) wird durch GreaseMonkey ein Script in die Seite eingebunden (sprich: <script src="http://meinehomepage.de/js/main.js" type="text/javascript"></script>
            3. Der Benutzer des Userscriptes klickt auf einen bestimmten Link, der durch das eingebundene JavaScript geändert wurde, von <a onclick="AjaxWindow.show('beispielwindow');" href="[...]">Beispiel</a> auf <a onclick="AjaxWindow.show('beispielwindow'); activate_check();" href="[...]">Beispiel</a>
            <Problemstelle>
            4. Der Rahmen eines INTERNEN JavaScript Fensters (!!!Kein neues Browser Fenster!!!) wird geladen, Daten werden abgerufen.
            5. Ein Div wird nach unbestimmter Zeit (= nachdem die Daten ausgelesen wurden) sichtbar, darin die ausgelesenen Elemente.
            6. Über diesem Div sollen durch die Funktion machwas() einige Elemente eingefügt werden.
            </Problemstelle>
            7. Beim Klick auf den INTERNEN Schließen-Knopf, der per onClick-Handler gesteuert wird, soll das INTERNE JavaScript Fenster und die von meinem Script eingefügten Elemente wieder entfernt werden.

            Ich schildere nochmal das Problem, dass ich durch <Problemstelle> gekennzeichnet habe: Es soll, sobald die Daten abgerufen sind und der Div mit diesen "Daten" erscheint (das passiert nach unbestimmter Zeit!) etwa zeitgleich mit dem Erscheinen eine Funktion aufgerufen werden (die dann einige andere Elemente einfügt, was aber kein Problem ist).
            Ich hoffe so versteht jeder mein Problem :)

            Grüße, Knight

            --
            ie:{ fl:) br:^ va:) ls:~ fo:| rl:( n4:& ss:| de:> js:) ch:| sh:} mo:} zu:(
            1. Re:

              Und wo ist jetzt das Problem, die Methode AjaxWindow.show(); mittels Deines Scripts zu überschreiben?

              Beispiel:

              var a={  
              	show:function(){ alert('a');}  
              }  
                
              var b=a.show.toString()  
              b=b.slice(13,b.length-1)  
              b+=' alert("b");'  
              a.show=new Function(b);  
              a.show();
              

              Alles andere belastet unnötig die CPU. Überschreibe die Funktionen, bzw. ergänze sie, statt zu versuchen, einen Eventhandler mittels Schleife und Interval zu simulieren!

              Gruß aus Berlin!
              eddi

              1. Re:

                Und wo ist jetzt das Problem, die Methode AjaxWindow.show(); mittels Deines Scripts zu überschreiben?

                Ich GLAUBE, dass du das etwas falsch verstanden hast. Die Ajax Funktion soll nachwievor bleiben. Durch sie wird erst das Fenster geöffnet! Innerhalb dieses Fensters soll etwas eingefügt werden, da das Objekt, in das etwas eingefügt werden soll, erst aus einer Datenbank ausgelesen werden muss. Das dauert natürlich ein bisschen. Ich brauche praktisch eine If-Schleife, die beispielsweise alle 100 Millisekunde prüft, ob das Element vorhanden ist. Sobald das Element dann da ist, soll eine Funktion EINMAL ausgeführt werden. Würde man einfach ein Interval setzen, würde die Funktion folglich solange in diesem Intervall ausgeführt werden, bis das Element wieder weg ist. Die Funktion wird also immerwieder neugestartet. Das soll so nicht sein!

                Grüße, Knight

                --
                ie:{ fl:) br:^ va:) ls:~ fo:| rl:( n4:& ss:| de:> js:) ch:| sh:} mo:} zu:(
                1. Re:

                  Und wo ist jetzt das Problem, die Methode AjaxWindow.show(); mittels Deines Scripts zu überschreiben?
                  Ich GLAUBE, dass du das etwas falsch verstanden hast.

                  Dann wisse jetzt, dass Du Dir die Meile zu Siebenvierteln machst und dabei um Hilfe bittest! Dein Konzept ist grundverkehrt.

                  Die Ajax Funktion soll nachwievor bleiben. Durch sie wird erst das Fenster geöffnet! Innerhalb dieses Fensters soll etwas eingefügt werden, da das Objekt, in das etwas eingefügt werden soll, erst aus einer Datenbank ausgelesen werden muss. Das dauert natürlich ein bisschen. Ich brauche praktisch eine If-Schleife, die beispielsweise alle 100 Millisekunde prüft, ob das Element vorhanden ist.

                  Du brauchst eine Ergänzung der onreadystatechange-Methode des XMLHttpRequest-Objekts, die nach erfolgreichem einfügen des Elements ins Dokument ausgeführt wird. Dazu stehen Dir prinzipiell mehrere Möglichkeiten zur Verfügung. Wie anhand meines letzten Beispiels Dir hätte ersichtlich werden können, kannst Du als eine mögliche Lösung den Sourcen Code nach dessen Laden durch Dein eigenes Script direkt editieren. Somit kannst Du der onreadystatechange-Methode eine Funktion unterjubeln, die neben dem vorgegebenen Code Deinen eigenen Code (machwas();) zum Schluss ausführt.

                  Sieh Dir mein Beispiel also an und übertrage es auf Dein Problem. Es war vorsorglich so gestaltet, dass sowohl der alte Code (alert('a');) als auch der neue (alert('b');) ausgeführt wird. Mitdenken, statt sich immer nur völlig missverstanden zu fühlen, erwarte ich allemal!

                  Gruß aus Berlin!
                  eddi

                2. Hi,

                  Ich brauche praktisch eine If-Schleife,

                  Wer von „If-Schleifen“ redet, der braucht erst mal Ahnung ...

                  Würde man einfach ein Interval setzen, würde die Funktion folglich solange in diesem Intervall ausgeführt werden, bis das Element wieder weg ist.

                  Wieso sollte sie?

                  Die Funktion wird also immerwieder neugestartet. Das soll so nicht sein!

                  Zeitintervalle kann man in JS auch wieder aufheben.

                  MfG ChrisB

                  --
                  “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]