Jörg: window.settimeout() mit Funktionsaufruf funktioniert nur im FF

Hallo,

die folgende Funktion

window.setTimeout("function()(new Effect.Fade(id,{duration:3.0, from:1.0}))", 2000);

Umgebung:
Windows XP bzw. Server 2008, WAMP, Scriptaculous, IE 6.0.x

funktioniert nur im Firfox einwandfrei. Der IE 6.0.x (Darf in dieser Umgebung nur dieser Browser in dieser Version sein!) meldet einen Scriptfehler.

Irgendwelche Ideen wie das zu umgehen ist?

Gruß
Jörg

  1. Hallo,

    Hallo,

    die folgende Funktion

    window.setTimeout("function()(new Effect.Fade(id,{duration:3.0, from:1.0}))", 2000);

    Umgebung:
    Windows XP bzw. Server 2008, WAMP, Scriptaculous, IE 6.0.x

    funktioniert nur im Firfox einwandfrei. Der IE 6.0.x (Darf in dieser Umgebung nur dieser Browser in dieser Version sein!) meldet einen Scriptfehler.

    Naja, liegts am Timeout oder an dem Effect.Fade inklusive Parameterübergabe. Ich würde das ja mal getrennt testen und vielleicht auch geschweifte Klammern nehmen.
    setTimeout("function() {alert("hallo"}", 2000);

    eigentlich aber

    function test() { alert("hallo") };
    setTimeout("test()", 2000);

    Gruß

    jobo

    1. @@jobo:

      nuqneH

      setTimeout("function() {alert("hallo"}", 2000);

      Nein. Zum einen window.setTimeout(), zum anderen müssen entweder die inneren Anführungszeichen escapet werden oder besser einfache und doppelte Anführungszeichen verwendet werden.

      eigentlich aber
      function test() { alert("hallo") };
      setTimeout("test()", 2000);

      Nein. Nicht als String sondern als Funktionsreferenz: window.setTimeout(test, 2000);

      Qapla'

      --
      Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
      (Mark Twain)
      1. Hallo,

        Nein. Nicht als String sondern als Funktionsreferenz: window.setTimeout(test, 2000);

        Ja, hatte ich schon gelesen bei deinem anderen Posting. Selfhtml schreibt das teilweise anders, zB:

        setTimeout("teste_x(" + Zaehler + ")", 30);

        http://de.selfhtml.org/javascript/beispiele/fehlerbehandlung_try_catch.htm

        Gruß

        jobo

        1. Hallo,

          s.a. http://www.highdots.com/forums/javascript/window-settimeout-vs-settimeout-272920.html

          "In the end, use either one, according to what you prefer. Personally,
          I'd use setTimeout "as is", the same way I prefer using "document"
          rather than "window.document"."

          Und wenn du Parameter übergeben willst, musst du doch den String nehmen, oder?

          Gruß

          jobo

          1. @@jobo:

            nuqneH

            "In the end, use either one, according to what you prefer. Personally,
            I'd use setTimeout "as is", the same way I prefer using "document"
            rather than "window.document"."

            Ähm ja, 'window.' dürfte man auch weglassen.

            Und wenn du Parameter übergeben willst, musst du doch den String nehmen, oder?

            Nein.

            Qapla'

            --
            Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
            (Mark Twain)
          2. s.a. http://www.highdots.com/forums/javascript/window-settimeout-vs-settimeout-272920.html

            "In the end, use either one, according to what you prefer. Personally,
            I'd use setTimeout "as is", the same way I prefer using "document"
            rather than "window.document"."

            Im Grunde ist es Quatsch und für den JS-Interpreter unnötig umständlich, immer window davor zu schreiben. Die Identifier Resolution durchsucht die Scope Chain, an dessen Ende immer das globale Objekt steht.

            Das globale Objekt hat keinen Namen und kann nicht direkt per Namen angesprochen werden. »window« ist nichts als eine Eigenschaft beim globalen Objekt, welches auf es selbst verweist. Klingt nach Brainfuck, ist es auch. »window« ist ja erst einmal ein Bezeichner genau wie »setTimeout«, kein besonderes Keyword. Um den aufzulösen, wird die Scope Chain abgelaufen. Beim globalen Objekt wird die JavaScript-Engine dann fündig:

            alert(this.window);
            (this wird nicht über die Scope Chain aufgelöst - es ist ein Keyword, kein Bezeichner)

            Wenn man also window.setTimeout schreibt, dann sucht er erst die Scope Chain nach dem Identifier »window« ab. Wenn es in der Scope Chain eine Variable namens window gibt, dann verwendet er diese - die muss nicht notwendig auf das globale Objekt verweisen. Bei dem Object, der beim Auflösen dieses Idenfitiers herauskommt, sucht er dann nach der Eigenschaft »setTimeout«.

            Wenn man nur setTimeout schreibt, dann sucht er die Scope Chain nach »setTimeout« ab. Dabei muss er ebenfalls nicht die gewünschte Methode finden, wenn eine gleichnamige Variable existiert.

            Insofern sind beide Zugriffsweisen letztlich gleich (un)zuverlässig. Manche Bibliotheken verwenden daher erst einmal this, um eine Referenz auf das globale Objekt zu bekommen, und arbeiten dann nur noch damit weiter:

            (function (dasRichtigeGlobaleObjekt) {
               dasRichtigeGlobaleObjekt.setTimeout(...);
            })(this);

            Ein ähnlicher Fall liegt bei null vs. undefined vor. undefined ist ein normaler Bezeichner, der gegen die Scope Chain aufgelöst wird - damit kann man undefined mit Quatsch überschreiben und es braucht seine Zeit. null hingegen ist ein Keyword, das immer dasselbe bedeutet und nicht zeitfressend aufgelöst werden muss.

            Siehe auch Globale Objekte importieren.

            Mathias

        2. @@jobo:

          nuqneH

          Selfhtml schreibt das teilweise anders, zB:

          setTimeout("teste_x(" + Zaehler + ")", 30);

          Dir ist klar, dass damit der String zusammengesetzt wir und beim Zählerstand von 42 'teste_x(42);' augerufen wird?

          Dasselbe kann (und sollte) man mit einer Funktion schreiben:

          window.setTimeout(function () { teste_x(Zaehler); }, 30);

          Qapla'

          --
          Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
          (Mark Twain)
          1. Hallo,

            Dir ist klar, dass damit der String zusammengesetzt wir und beim Zählerstand von 42 'teste_x(42);' augerufen wird?

            Ja.

            Dasselbe kann (und sollte) man mit einer Funktion schreiben:

            window.setTimeout(function () { teste_x(Zaehler); }, 30);

            Ja, sieht etwas besser aus, wobei mir persönlich setTimeout(teste_X(Zaehler),20); am besten gefallen würde.

            Aber gut zu wissen, dass man so etwas übersichtlicher auch Funktionen mit Parameterübergabe montieren kann.

            Gruß

            jobo

            1. @@jobo:

              nuqneH

              Ja, sieht etwas besser aus, wobei mir persönlich setTimeout(teste_X(Zaehler),20); am besten gefallen würde.

              Geht nicht, weil an der Stelle kein Rückgabewert 'foo()' erwartet wird, sondern die Referenz auf die Funktion 'foo'.

              Qapla'

              --
              Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
              (Mark Twain)
              1. Hallo,

                Geht nicht, weil an der Stelle kein Rückgabewert 'foo()' erwartet wird, sondern die Referenz auf die Funktion 'foo'.

                Macht Sinn. Bleibt als letzte Frage: schreibst Du auch window.document.getElementById("id");?

                Oder warum bestehst Du auf window.setTimeout() statt einfach setTimeout() (s.a. Selfhtmllink im andern Posting).

                Gruß

                jobo

                1. @@jobo:

                  nuqneH

                  Bleibt als letzte Frage: schreibst Du auch window.document.getElementById("id");?

                  Nö.

                  Oder warum bestehst Du auf window.setTimeout() statt einfach setTimeout() (s.a. Selfhtmllink im andern Posting).

                  Ich bestehe nicht drauf.

                  Qapla'

                  --
                  Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
                  (Mark Twain)
          2. Dasselbe kann (und sollte) man mit einer Funktion schreiben:

            window.setTimeout(function () { teste_x(Zaehler); }, 30);

            In manchen Browsern geht auch

            setTimeout(teste_x, 30, Zaehler);

            Dies wird in HTML5 standardisiert, aber IE macht das nicht, dort bedeutet der 3. Parameter bereits etwas anders.

            Aus funktionaler Sicht angebrachter wäre Currying:

            setTimeout(teste_x.curry(Zaehler), 30);

            Das erzeugt eine neue Funktion, die teste_x mit dem Parameter Zaehler aufruft.

            Function.prototype.curry bieten Frameworks wie Prototype an, viele Browser implementieren aber bereits das standardisierte Function.prototype.bind:

            setTimeout(teste_x.bind(null, Zaehler), 30);

            Das legt intern einen Wrapper an, eine Pseudo-Funktion, die Aufrufe an teste_x delegiert.

            https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

            Mathias

  2. @@Jörg:

    nuqneH

    funktioniert nur im Firfox einwandfrei.

    Was bei dem Code wohl eher ein Wunder ist.

    window.setTimeout erwartet im ersten Parameter entweder einen String, der JavaScript-Code enthält

    window.setTimeout("alert(42);", 1000);

    oder

    function answer() { alert(42); }  
    window.setTimeout("answer()", 1000);
    

    oder besser eine Funktion (nicht als String)

    function answer() { alert(42); }  
    window.setTimeout(answer, 1000);
    

    oder als anonyme Funktion

    window.setTimeout(function () { alert(42); }, 1000);

    Qapla'

    --
    Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
    (Mark Twain)