booboo: with() ?

Hallo Selfhtml-ler,

ich hätte eine Frage bezügl. Javascript und with().

Also nehmen wir mal diesen Code:

  
document.getElementById("test").id = "test";  
document.getElementById("test").src = "http://grafik.gif";  
document.getElementById("test").alt = "Alternativtext";  

(nur ein Beispiel :-) )

Leichter wäre es also, es so zu schreiben:

  
with(document.getElementById("test")) {  
  
      id = "test";  
      src = "http://grafik.gif";  
      alt = "Alternativtext";  
}  

Jetzt nehmen wir mal an, ich will nach dem Setzen der ID eine Meldung ausgeben lassen, dass alles geklappt hat oder so :-)

Dazu müsste ich also

window.alert("Alles bestens!");

schreiben.

Kann ich diesen Code einfach so in die with()-Anweisung reinschreiben? Also erkennt der Browser automatisch, dass ich das window-Objekt anspreche und dessen alert-Methode aufrufe, oder denkt der Browser, dass "window" ein Unterobjekt von "document.getElementById("test")" ist?

Ich hoffe, man kann meine Frage einigermaßen verstehen.

Danke für jede Hilfe,

booboo

  1. Hallo,

    Leichter wäre es also, es so zu schreiben:

    with(document.getElementById("test")) {

    id = "test";
          src = "http://grafik.gif";
          alt = "Alternativtext";
    }

    
    >   
    > Jetzt nehmen wir mal an, ich will nach dem Setzen der ID eine Meldung ausgeben lassen, dass alles geklappt hat oder so :-)  
    >   
    > Dazu müsste ich also  
    >   
    > `window.alert("Alles bestens!");`{:.language-javascript}  
    >   
    > schreiben.  
    >   
    > Kann ich diesen Code einfach so in die with()-Anweisung reinschreiben?  
      
    Können schon, nur es wird zu einem Fehler führen.  
      
    
    > Also erkennt der Browser automatisch, dass ich das window-Objekt anspreche und dessen alert-Methode aufrufe, oder denkt der Browser, dass "window" ein Unterobjekt von "document.getElementById("test")" ist?  
    >   
      
    "with" nimmt ein Objekt und referenziert auf alle Eigenschaften, Methoden und Events dieses Objekts.  
    Wenn du also  
    with(document.getElementById("test")) {  
     alert()  
    }  
    schreibst, referenzierst auf document.getElementById("test").alert (oder eben auf document.getElementById("test").window.alert) die es natürlich nicht gibt.  
      
    Grüße  
    Thomas
    
    1. Hello,

      with(document.getElementById("test")) {

      id = "test";
            src = "http://grafik.gif";
            alt = "Alternativtext";
      }

      Wäre es nicht sauberer, erst ein neues Objekt von dem Typ zu erzeugen, diesem die Werte zuzuweisen und dann das ganze Objekt dem document.getElementById("test") zuzuweisen? Geht das nicht?

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

      1. Hallo Tom,

        with(document.getElementById("test")) {

        id = "test";
              src = "http://grafik.gif";
              alt = "Alternativtext";
        }

        Wäre es nicht sauberer, erst ein neues Objekt von dem Typ zu erzeugen, diesem die Werte zuzuweisen und dann das ganze Objekt dem document.getElementById("test") zuzuweisen?

        Warum sollte das sauberer sein?

        Geht das nicht?

        Nein, in der Weise, wie Du's Dir vorstellst, geht das nicht. Du kannst einem Funktionsaufruf zum einen nichts zuweisen, ferner kannst Du nicht so ohne weiteres einen Knoten überschreiben.

        Was Du machen kannst, ist einen neuen Knoten per DOM anlegen und ihn dann per parentNode.replaceChild dann wieder an die Stelle einhängen, wo der alte hing. Ist allerdings kompliziert und imperformant - deswegen meine obige Frage: Warum meinst Du, dass das sauberer sei?

        Viele Grüße,
        Christian

        1. Hello,

          deswegen meine obige Frage: Warum meinst Du, dass das sauberer sei?

          Die Frage hatte ich ans Forum gerichtet.
          Den Weg hast Du nun aufgezeigt.

          In anderen Sprachen funktioniert so etwas,
          in (alten) Hochsprachen wiederum wäre es tödlich, einfach den Zeiger auf den bisher genutzten Speicherbereich mit einem auf den neuen zu überschreiben. Dann hat man irgendwann keinen Speicher mehr. Wie JS innen aussieht weiß ich keider nicht. Wäre aber sicherlich hilfreich.

          Ich nehme an, dass die Methode parentNode.replaceChild sich um diese Aufräumarbeiten kümmert?

          Ich hatte mir vorgestellt, dass die Methode document.getElementById("test") intern eben die Derefenzierung auf das Objekt betreibt und man daher das dadurch bezeichnete Objekt überschreiben könne.

          Harzliche Grüße vom Berg
          http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau

          1. hi,

            Ich hatte mir vorgestellt, dass die Methode document.getElementById("test") intern eben die Derefenzierung auf das Objekt betreibt

            Sie liefert dir eine Referenz auf die Javascript-Repräsentation eines Elementes im DOM-Baum.

            und man daher das dadurch bezeichnete Objekt überschreiben könne.

            Nein, du kannst Elementobjekte im Dom nicht einfach per Zuweisungsoperator "überschreiben".
            Du kannst sie Löschen, durch andere Ersetzen, Umhängen, etc. - wenn du die entsprechenden DOM-Methoden verwendest.

            Ein einfaches "Überschreiben" per Zuweisungsoperator ginge höchstens über _Eigenschaften_ wie innerHTML/outerHTML; wobei du dann aber wiederum einen neuen Parse-Vorgang des übergebenen HTML-Codes erzwingst, was ebenfalls nicht sonderlich performant ist - und lediglich zum Ändern von ein paar (beschreibbaren) Eigenschaften oder Style-Attributen m.E. absoluter Overkill wäre.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. Hallo booboo,

    Dazu müsste ich also

    window.alert("Alles bestens!");

    schreiben.

    Kann ich diesen Code einfach so in die with()-Anweisung reinschreiben? Also erkennt der Browser automatisch, dass ich das window-Objekt anspreche und dessen alert-Methode aufrufe, oder denkt der Browser, dass "window" ein Unterobjekt von "document.getElementById("test")" ist?

    Ja, das "denkt" der Browser zuerst und nachdem er festgestellt hat, dass dem nicht so ist, probiert er es auch noch einmal ohne "with" und dann klappt das ja auch. Also keine Angst! Ein paar Millisekunden länger braucht das "Nachdenken" des Browsers so halt schon. Das musst du halt selbst wissen, ob du lieber schreibfaul bist oder dem Browser die Millisekunden "Nachdenken" ersparst.

    Gruß Gernot

    1. Hallo,

      Dazu müsste ich also
      window.alert("Alles bestens!");
      schreiben.
      Kann ich diesen Code einfach so in die with()-Anweisung reinschreiben?

      Ja, das "denkt" der Browser zuerst und nachdem er festgestellt hat, dass dem nicht so ist, probiert er es auch noch einmal ohne "with" und dann klappt das ja auch.

      In der Tat.
      Ich revidiere meine frühere Aussage.

      -------------------------
      <html>
      <head>
       <title>Untitled</title>
       <script type="text/javascript">
        function machwas() {
         with(document.getElementById('myDiv')) {
          firstChild.data = "foo";
          window.alert(firstChild.data);
         }
        }
       </script>
      </head>

      <body onload="machwas()">

      <div id="myDiv">bla</div>

      </body>
      </html>

      ---------------------

      Grüße
      Thomas

  3. hallo,

    Kann ich diesen Code einfach so in die with()-Anweisung reinschreiben?

    Können kannst du alles. Nur Sinn muß es dann nicht unbedingt machen.

    Wenn ich vor derselben Frage stünde, würde ich es mit einer Bedingung versuchen. Also
      if ...
    Wenn nun dein "with" eine Ausgabe erzeugt hat (true) gibst du dein alert aus, wenn nicht, gibts eben eine andere Meldung.

    Grüße aus Berlin

    Christoph S.

    --
    Visitenkarte
    ss:| zu:) ls:& fo:) va:) sh:| rl:|
  4. Hallo,

    document.getElementById("test").id = "test";
    document.getElementById("test").src = "http://grafik.gif";
    document.getElementById("test").alt = "Alternativtext";

      
    Das ist ohnehin nicht gut, weil der Browser dann jedes Mal nach einem Element mit der ID „test“ suchen muss. Es wäre besser, wenn du das Ergebnis erstmal in eine Variable schreiben würdest.  
      
    ~~~javascript
      
    var el = document.getElementById("test");  
    el.id = "test";  
    el.src = "http://grafik.gif";  
    el.alt = "Alternativtext";  
    
    

    With nimmt natürlich ebenfalls den Rückgabewert und such nicht jedes Mal nach dem Element.

    Leichter wäre es also, es so zu schreiben:

    with(document.getElementById("test")) {

    id = "test";
          src = "http://grafik.gif";
          alt = "Alternativtext";
    }

    
    >   
    > Jetzt nehmen wir mal an, ich will nach dem Setzen der ID eine Meldung ausgeben lassen, dass alles geklappt hat oder so :-)  
    >   
    > Dazu müsste ich also  
    >   
    > `window.alert("Alles bestens!");`{:.language-javascript}  
    >   
    > schreiben.  
    >   
    > Kann ich diesen Code einfach so in die with()-Anweisung reinschreiben?  
      
    Ja, sofern dein Element keine „window“-Eigenschaft besitzt, hangelt sich der Browser in diesem Fall bis zu window-Objekt hoch.  
      
    Was bei with problematisch zu sein scheint, ist das hinzufügen von Eventhandlern. Wenn man z.B. schreibt:  
      
    ~~~javascript
      
    with (document.body.appendChild(document.createElement("input"))){  
     type = "button";  
     value = "klick mich";  
     onclick = function(){  
      alert("Button wurde angeklickt");  
     }  
    }
    

    …kommt die Meldung „Button wurde angeklickt“ seltsamerweise überall. Mann könnte natürlich tricksen, indem man „parentNode.lastChild“ vor das onclick schreibt, aber das ist ja dann auch nicht der Sinn der Sache. Oder man verwendet addEventListener, was jedoch nicht von allen Browsern unterstützt wird :-(

    Das ist einer der Gründe, warum ich es langsam einsehe, dass with deprecated ist. Trotzdem verwende ich es noch ab und zu, weil praktisch :-)

    mfg. Daniel

    1. Hallo,

      Das ist einer der Gründe, warum ich es langsam einsehe, dass with deprecated ist.

      Ist es nicht, wer sollte es als deprecated erklärt haben? with ist in Netscape/Mozilla JavaScript, ECMAScript und JScript definiert.

      Mathias

      1. Hallo,

        Das ist einer der Gründe, warum ich es langsam einsehe, dass with deprecated ist.

        Ist es nicht, wer sollte es als deprecated erklärt haben? with ist in Netscape/Mozilla JavaScript, ECMAScript und JScript definiert.

        Ich hätte es auch nicht für möglich gehalten, aber in diesem Thread haben mir das mehrere Stammposter geschrieben…

        mfg. Daniel

        1. Hallo,

          Ich hätte es auch nicht für möglich gehalten, aber in diesem Thread haben mir das mehrere Stammposter geschrieben…

          Ja, so entstehen Legenden, die durch ein wenig Recherchieren einfach aus der Welt geschafft werden können. ;)

          »Note: Firefox 1.5 generates a warning when the 'with' statement is used: "deprecated with statement usage". This has been removed in Firefox 1.5.0.1 (bug 322430).«
          http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Statements:with

          Selbst im proprietären Mozilla-JavaScript 1.5 ist with nicht offiziell deprecated, diese Warnung hat man wieder zurückgezogen.

          Mathias

          1. Hallo,

            Selbst im proprietären Mozilla-JavaScript 1.5 ist with nicht offiziell deprecated, diese Warnung hat man wieder zurückgezogen.

            Ah danke.

            Dann kann ich wohl wieder ruhigen Gewissens „with“ einsetzen, welches insbesondere bei der Erstellung von HTML-Objekten mit den DOM-Methoden sehr hilfreich sein kann :))

            mfg. Daniel