mathefritz: javascript forward referenz unmöglich?

es scheint, document.getElementById('x') ist erfolglos wenn das Element mit dieser id
im Text erst weiter nach dem getElementById kommt; nichteinmal das folgende weniger nützliche klappt - erwartet hatte ich eine p.length von 2

<html>
  <head>
  </head>
  <body>
    <div id='vt'>
          <script>
                h = document.getElementById('vt');
                p = h.getElementsByTagName('p');
                alert(p.length);
         </script>
         <p id='t'>forward</p>
         <p>xxxx</p>
    </div>
  </body>
</html>

Irgendwelche Tricks verfügbar?

  1. Hi,

    es scheint, document.getElementById('x') ist erfolglos wenn das Element mit dieser id
    im Text erst weiter nach dem getElementById kommt; nichteinmal das folgende weniger nützliche klappt - erwartet hatte ich eine p.length von 2

    <html>
      <head>
      </head>
      <body>
        <div id='vt'>
              <script>
                    h = document.getElementById('vt');
                    p = h.getElementsByTagName('p');
                    alert(p.length);
             </script>
             <p id='t'>forward</p>
             <p>xxxx</p>
        </div>
      </body>
    </html>
    

    Irgendwelche Tricks verfügbar?

    Das Javascript erst ausführen, wenn die Elemente existieren.

    z.B. durch Verschieben des Script-Elements, oder durch Ausnützen eines passenden Events (load, documentReady ...)

    cu,
    Andreas a/k/a MudGuard

    1. Danke ! .

  2. Tach!

    es scheint, document.getElementById('x') ist erfolglos wenn das Element mit dieser id
    im Text erst weiter nach dem getElementById kommt; Irgendwelche Tricks verfügbar?

    Kein Trick sondern üblich. Javascript-Code kann nur auf das zugreifen, was bereits vorhanden ist. Man führt DOM-zugreifenden Code in der Regel erst aus, wenn das Event DOMContentLoaded gefeuert wurde. Also Eventhandler für das genannte Event registrieren und den auszuführenden Code dort einfügen.

    dedlfix.

    1. @@dedlfix

      Also Eventhandler für das genannte Event registrieren und den auszuführenden Code dort einfügen.

      JavaScript erst nach dem Seiteninhalt notieren – also ganz am Ende des bodys –, damit die Ausführung des Scripts nicht das Rendern der Seite blockt.

      Und so ganz nebenbei spart man sich dann den Eventhandler.

      LLAP 🖖

      --
      “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
      Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
      1. Lieber Gunnar,

        JavaScript erst nach dem Seiteninhalt notieren – also ganz am Ende des bodys –, damit die Ausführung des Scripts nicht das Rendern der Seite blockt.

        ja, das liest man durchaus öfter. Das script-Element ist eigentlich eine Meta-Information, oder nicht? Der Semantik nach hätte ich jetzt gesagt muss sie in den head. Dass Performanz-Probleme (das Blocken des Renderings) nun dafür sorgen, diese semantische Trennung aufzuheben, finde ich unschön. Und ist der Eventhander nicht gerade dafür da, dass das Rendering eben nicht geblockt wird? Ob ich das Script am Ende des body so notiere, dass es sofort startet, oder ob ich es im head (oder auch am Ende des body) in einen Eventhandler verpacke ist jetzt inwiefern performance-technisch ein Unterschied?

        Liebe Grüße,

        Felix Riesterer.

        1. Ob ich das Script am Ende des body so notiere, dass es sofort startet, oder ob ich es im head (oder auch am Ende des body) in einen Eventhandler verpacke ist jetzt inwiefern performance-technisch ein Unterschied?

          Wenn der Browser beim Parsen des HTML auf ein script-Element stößt, beginnt er unmittelbar damit das Skript herunterzuladen, zu parsen und auszuführen. In der Zeit wird der HTML-Parser suspendiert, denn es könnte ja sein, dass das Skript bereits DOM-Manipulationen vornimmt, die den Parser anschließend beeinflussen könnten. Mit dem script-Element am Ende des body verschiebt man die Pause bis kurz vor Ende des Parsing-Prozesses, zu diesem Zeitpunkt sollte der Browser alle nötigen Informationen haben, um die Seite zu rendern. Diese Methode hat allerdings den Nachteil, dass erst sehr spät mit dem Download des Skripts begonnen wird. Ideal wäre es, möglichst früh mit dem Download zu beginnen, aber den HTML-Parser während des Downloads weitermachen zu lassen. Dafür notiert man das script-Tag im Kopfbereich zusammen mit dem async- oder defer-Attribut. Mit async-Attribut wird die Skriptausführung dann unmittelbar begonnen, wenn der Download abgeschlossen ist. Das blockiert dann wiederum den HTML-Parser. Beim defer-Attribut wird mit der Ausführung noch so lange gewartet bis auch der HTML-Parser seinen Job erledigt hat. Das kann man sich grafisch sehr schön veranschaulichen.

          1. Das kann man sich grafisch sehr schön veranschaulichen.

            Verstehe nicht, welchen Sinn es haben sollte, den HTML-Parser zu stoppen, während eine Datei geladen wird.

            Edit: Oder na ja, weil Javascript an dieser Stelle HTML einfügen könnte?

            Wenn die Datei nicht erreichbar ist, bleibt die Seite weiss? Ein Fehler, den man erstmal finden muss. Da ich sowas noch nicht erlebt habe, bezweifle ich, dass ein fehlendes Script die Anzeige der gesamten Seite blockiert.

            1. Hallo Linuchs,

              Wenn die Datei nicht erreichbar ist, bleibt die Seite weiss?

              Nein, dann kommt ein 404 und das Parsen des Skriptes ist beendet.

              Bis demnächst
              Matthias

              --
              Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
              1. Hi,

                Wenn die Datei nicht erreichbar ist, bleibt die Seite weiss?

                Nein, dann kommt ein 404 und das Parsen des Skriptes ist beendet.

                das wäre eine der "freundlichen" Situationen, das geht nämlich sehr schnell. Ärgerlicher ist es, wenn der Server zwar im DNS gefunden wird, aber nicht reagiert (z.B. temporär offline oder überlastet ist). Dann hängt der Seitenaufbau an der Stelle nämlich, bis ein Timeout zuschlägt.

                Dieser Timeout ist übrigens sogar browserspezifisch: Während z.B. Firefox nach 30s aufgibt (oder waren es 60s?), wartet der "alte" Opera 12.x gnadenlos auch mal mehrere Minuten auf einen nicht reagierenden Server.

                So long,
                 Martin

                --
                Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
                - Douglas Adams, The Hitchhiker's Guide To The Galaxy
            2. Hi,

              Verstehe nicht, welchen Sinn es haben sollte, den HTML-Parser zu stoppen, während eine Datei geladen wird.

              Edit: Oder na ja, weil Javascript an dieser Stelle HTML einfügen könnte?

              das ist wohl die Idee dahinter. Oder allgemeiner: Javascript-Code, der "mitten im Dokument" steht, soll beim Rendern auch genau an der Stelle ausgeführt werden, was immer er auch tun will.

              Wenn die Datei nicht erreichbar ist, bleibt die Seite weiss?

              Je nach Art des Fehlers, ja, zumindest eine Weile. Eventuell sieht man in der Zeit schon die bis dahin vom Browser interpretierten Teile der Seite.

              Ein Fehler, den man erstmal finden muss. Da ich sowas noch nicht erlebt habe, bezweifle ich, dass ein fehlendes Script die Anzeige der gesamten Seite blockiert.

              Wie gesagt: Je nach Art des Fehlers kann er den Seitenaufbau zumindest empfindlich verzögern.

              So long,
               Martin

              --
              Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
              - Douglas Adams, The Hitchhiker's Guide To The Galaxy
              1. Hallo Der Martin,

                Wie gesagt: Je nach Art des Fehlers kann er den Seitenaufbau zumindest empfindlich verzögern.

                Wobei ein Unbedarfter dies nicht auf JavaScript schieben wird, sondern „Das Internet ist heute aber wieder langsam.“ sagt.

                Bis demnächst
                Matthias

                --
                Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
        2. @@Felix Riesterer

          Das script-Element ist eigentlich eine Meta-Information, oder nicht? Der Semantik nach hätte ich jetzt gesagt muss sie in den head.

          Och, wenn’s danach ginge, würde ich auch sagen, dass die Referenz zum Stylesheet nicht in den head gehört, sondern als processing instruction an den Anfang – wie in XML:

          <?xml-stylesheet href="standard.css"?>
          <!DOCTYPE html>
          <html xmlns="http://www.w3.org/1999/xhtml"></html>
          

          Dass Performanz-Probleme (das Blocken des Renderings) nun dafür sorgen, diese semantische Trennung aufzuheben, finde ich unschön.

          Vielleicht hätte man noch ein foot-Element in HTML einführen sollen, dass nach dem body stehen und Scripte aufnehmen kann?

          Und ist der Eventhander nicht gerade dafür da, dass das Rendering eben nicht geblockt wird? Ob ich das Script am Ende des body so notiere, dass es sofort startet, oder ob ich es im head (oder auch am Ende des body) in einen Eventhandler verpacke ist jetzt inwiefern performance-technisch ein Unterschied?

          Bei im HTML notiertem JavaScript macht das keinen großen Unterschied. Üblicherweise werden aber externe JavaScript-Ressourcen geladen – und da macht es einen Unterschied, wann das geschieht.

          Bzw. wie das geschieht, wie 1unitedpower schon sagte.

          LLAP 🖖

          --
          “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
          Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
    2. Danke ! .

  3. Lieber mathefritz,

    es scheint, document.getElementById('x') ist erfolglos wenn das Element mit dieser id
    im Text erst weiter nach dem getElementById kommt;

    das ist richtig beobachtet. Du kennst offensichtlich den Hintergrund Deines Problems noch nicht: zeitversetztes Ausführen von Code, inhaltlich das schon angesprochene DOMContentLoaded-Ereignis

    Irgendwelche Tricks verfügbar?

    Liebe Grüße,

    Felix Riesterer.

    1. und nochmals Danke allen !

      da die meisten Wiki-Beispiele meinem Geschmack nach zu komplex sind also ein Einfaches hier

      <html>
        <head>
        </head>
        <body>
        <script>
            document.addEventListener('DOMContentLoaded',loaded);
      
            function loaded(){pp = document.getElementById('f');
        
                     alert(pp.innerHTML);
            }
      </script>
      <span id='f'>forward</span>
        </body>
      </html>
      
      1. Hallo mathefritz,

        da die meisten Wiki-Beispiele meinem Geschmack nach zu komplex sind

        Danke für die Rückmeldung. Es ist nicht immer einfach, einen passenden Schwierigkeitsgrad für die Beispiele zu finden.

        also ein Einfaches hier

        Es kann durchaus auch mehrere Beispiele pro Eigenschaft/Elenent/Methode geben.
        An welcher Stelle würdest du das im Wiki unterbringen?

        Bis demnächst
        Matthias

        --
        Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
        1. Hallo Matthias,

          wenn man schnell etwas nachschlagen will sollte man möglichst nicht mit Elementen und Methoden und ... konfrontiert werden die einem vielleicht auch noch nicht so geläufig sind, aber momentan nicht benötigt / nicht zu benötigen meint;

          Das Beispiele "Ansehen" beeindruckt natürlich, was sie aber aufwendig macht.

          10, max. 20 Zeilen zum copy/paste, leicht nachvollziehbar, varierbar, kein "main", kein "vieport",... direkt zur Sache .

          Gruß Fritz

          1. Lieber mathefritz,

            wenn man schnell etwas nachschlagen will

            das ist oft das Problem. Beim "schnellen Nachschlagen" kann es sein, dass ein weniger Versierter wesentliche Dinge nicht sinnvoll oder gar falsch macht (siehe Deine globale Variable pp oben). Da sollte man sich dann schon die Zeit nehmen und das Beispiel genau durcharbeiten, damit man es vollumfänglich verstanden hat.

            10, max. 20 Zeilen zum copy/paste, leicht nachvollziehbar, varierbar, kein "main", kein "vieport",... direkt zur Sache .

            Copy&Paste ohne Verstand ist genau das Falsche. Das "leicht nachvollziehbar" ist OK, das "direkt zur Sache" ist auch da, aber copy&paste ist genau nicht das Ziel, sondern die Energie des Verstehens ist es.

            Liebe Grüße,

            Felix Riesterer.

      2. Lieber mathefritz,

          function loaded(){pp = document.getElementById('f');
        
                   alert(pp.innerHTML);
          }
        

        Du verwendest mit pp eine globale Variable. Das solltest Du vermeiden. Das geht am einfachsten mit einem passenden Schlüsselwort wie var oder const.

        Liebe Grüße,

        Felix Riesterer.

        1. Hallo Felix,

          pp soll ja auch, nach der Initalisierung, global, in mehreren functions verfügbar sein, nicht immer wieder ... getElement ... benötigen;
          ok; hätte dann der Deutlichkeit halber auch global als const pp deklariert werden sollen.

          Gruß Fritz

          1. Tach!

            ok; hätte dann der Deutlichkeit halber auch global als const pp deklariert werden sollen.

            Ja, aus technischer Sicht braucht es diese Deklaration zwar nicht, aber um die Absicht des Autors den Lesern zu verdeutlichen sollte man trotzdem solche Dinge mit var/const/wasauchimmer im globalen Scope anlegen. (Unabhängig von der Frage, ob es nicht eine bessere Lösung als die globale Variable gibt.)

            dedlfix.